/*
  Site-wide shell layout — plain CSS, no build step, per spec Section 2.

  Structure (see templates/base.html):
    .org-band      — top band, Organization branding
    .nav-strip     — menu strip: username, profile link, logout, etc.
    .app-main      — 3-column grid, ratio 25:60:15
      .panel-left    — assignment instructions / future app-specific menus
      .panel-main    — the actual drawing screen (or any page's main content)
      .panel-right   — assignment list within category, navigation buttons
    .site-footer   — copyright / licensing / future footer links

  Column ratio uses `fr` units rather than percentages so that `gap` is
  subtracted correctly and the three panels can never overflow the
  container — with plain percentages, adding a gap on top of 25%+60%+15%
  would push total width past 100%.
*/

:root {
  /* Client, 2026-11-01 (MCQ_clarifications_1 / app.css): colour scheme
     supplied by the client — these are the DEFAULTS. From the portal
     release onward the Global Admin can override any of them from the
     database (portal.ThemeColour); portal's context processor emits an
     inline <style> after this sheet, so a stored override wins and a
     missing one falls back to the value here.
     WCAG note (computed, not assumed): every pairing passes AA 4.5:1
     EXCEPT plain text in .nav-strip (--nav-strip-fg #d2d2ea on
     --nav-strip-bg #8b8bc4 = 2.15:1). Links/buttons in the strip use
     the org-band pair (11.91:1) and are fine; only unstyled text such as
     the signed-in e-mail is affected. Left exactly as the client set it. */
  --org-band-bg: #0b0160;
  --org-band-fg: #d2d2ea;
  --nav-strip-bg: #8b8bc4;
  --nav-strip-fg: #d2d2ea;
  --panel-border: #e2e8f0;
  --panel-bg: #f8fafc;
  --footer-bg: #0b0160;
  --footer-fg: #d2d2ea;
  --link-color: #0369a1;
  --warning-bg: #fffbeb;
  --warning-fg: #92400e;
  --error-bg: #fee2e2;
  --error-fg: #991b1b;
  --success-bg: #d1fae5;
  --success-fg: #065f46;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: #1f2933;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

a {
  color: var(--link-color);
}

/* --- Top band: Organization branding --- */
.org-band {
  background: var(--org-band-bg);
  color: var(--org-band-fg);
  padding: 0.75rem 1.5rem;
}

.org-band h1 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.org-band h1 a {
  color: inherit;
  text-decoration: none;
}

/* --- Menu strip: user info, profile, logout, future items --- */
.nav-strip {
  background: var(--nav-strip-bg);
  color: var(--nav-strip-fg);
  padding: 0.5rem 1.5rem;
  border-bottom: 1px solid var(--panel-border);
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
}

.nav-strip form {
  margin: 0;
  display: inline;
}

/* Links and the logout button styled alike (client, 2026-07-26): same
   shape, same shade as the org band, so the whole nav strip reads as one
   consistent row of actions rather than a mix of plain text links and one
   differently-styled button. */
.nav-strip a,
.nav-strip button {
  background: var(--org-band-bg);
  color: var(--org-band-fg);
  border: none;
  border-radius: 4px;
  padding: 0.35rem 0.85rem;
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}

.nav-strip a:hover,
.nav-strip button:hover {
  opacity: 0.85;
}

/* --- Main content: 3-column grid. 20:60:20 by default (client,
   2026-09-27) — was 25:60:15; drawing/view/feedback screens instead add
   the .drawing-layout class (via base.html's panel_ratio_class block)
   for 20:65:15, needing more room for the canvas itself than other
   screens need for their content. --- */
.app-main {
  flex: 1;
  display: grid;
  grid-template-columns: 20fr 60fr 20fr;
  gap: 1px;
  background: var(--panel-border);
  /* Without this, a flex child that's also a grid container won't
     actually shrink below its content's natural size — defeating
     flex:1 and each panel's own overflow-y:auto below, and the whole
     page grows/scrolls instead of just the panel with too much content
     (client, 2026-07-27: needed for long lists — Users, Background
     Images, Drawing Assignments, and the drawing screen's right panel). */
  min-height: 0;
}

.app-main.drawing-layout {
  grid-template-columns: 20fr 65fr 15fr;
}

.panel-left,
.panel-main,
.panel-right {
  background: var(--panel-bg);
  padding: 1rem;
  overflow-y: auto;
  /* Same reasoning as .app-main's min-height:0 above — a grid item's
     default min-height is auto (its content's natural height), which
     otherwise overrides overflow-y:auto entirely. */
  min-height: 0;
}

/* Real bug, found and fixed (client, 2026-08-08): without these, the
   three panels relied entirely on CSS Grid's implicit auto-placement
   (filling columns in DOM order among whichever items are actually
   visible). That's fine while all three are visible, but the moment one
   panel gets `display: none` (the hide/show toggles above), the
   *remaining* visible panels get reshuffled into the wrong columns —
   e.g. hiding panel-left left panel-main auto-placed into column 1 (the
   collapsed, near-zero-width one) and panel-right auto-placed into
   column 2 (the wide one), with column 3 now empty and rendering as a
   plain, unexplained blank block in the grid's own background color.
   Pinning each panel to its intended column explicitly means hiding any
   one (or two) of them no longer moves the rest around at all. */
.panel-left {
  grid-column: 1;
}

.panel-main {
  grid-column: 2;
}

.panel-right {
  grid-column: 3;
}

/* Pages that don't use a panel (login, profile, etc.) leave it empty; an
   empty panel just collapses visually rather than leaving a broken gap. */
.panel-left:empty,
.panel-right:empty {
  padding: 0;
}

/* Below ~768px, stack the three panels instead of forcing the grid into
   a phone-width screen. Full responsive design is a later concern
   (Phase 8); this is just enough to keep the app usable while testing. */
@media (max-width: 768px) {
  .app-main {
    grid-template-columns: 1fr;
  }
}

/* .public-main removed (client, 2026-09-27) — public_home.html now
   extends base.html like every other screen, using .app-main's default
   20:60:20 ratio (base.html's nav-strip already handles the anonymous
   case correctly, so there was nothing else the separate template was
   actually needed for). .placeholder-block stays — still used by
   public_home.html's own content. */
.placeholder-block {
  border: 1px dashed var(--panel-border);
  border-radius: 4px;
  padding: 2rem 1rem;
  margin-bottom: 1rem;
  text-align: center;
  color: var(--nav-strip-fg);
  opacity: 0.6;
}

/* --- Footer: copyright, licensing, future links --- */
.site-footer {
  background: var(--footer-bg);
  color: var(--footer-fg);
  padding: 0.75rem 1.5rem;
  font-size: 0.85rem;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.site-footer a {
  color: var(--footer-fg);
}

/* --- Admin dashboard: same-size button tiles (client, 2026-07-26) --- */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}

/* Dashboard tiles are colorful buttons like everywhere else in
   .panel-main, just arranged in a grid and taller/centered — fully
   declared in one rule here rather than split across a separate
   .dashboard-tile rule plus a partial override, after a real CSS
   specificity bug (client, 2026-07-28): the old split left border/
   border-radius declared only on the lower-specificity .dashboard-tile
   rule, so the generic `.panel-main a { border: none; }` rule below
   silently won for just that property, and the tiles lost their visible
   border/bevel entirely even though the override rule looked like it
   should have won overall. */
.panel-main a.dashboard-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 4rem;
  padding: 1rem;
  background: var(--org-band-bg);
  color: var(--org-band-fg);
  border: 1px solid var(--org-band-bg);
  border-radius: 6px;
  text-decoration: none;
  font-weight: 600;
  font: inherit;
  cursor: pointer;
}

.panel-main a.dashboard-tile:hover {
  opacity: 0.85;
}

/* --- Drawing screen: toolbar, custom confirm modal, assignment list
   (client, 2026-07-26) --- */
.drawing-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  /* Client, 2026-09-27, item 14: moved to the top of the screen (see
     assignment_draw.html) and made sticky here, so it stays reachable
     without scrolling back up — sticky positioning is relative to the
     nearest scrolling ancestor, which is .panel-main itself
     (overflow-y: auto), so this sticks to the top of the visible panel
     as the user scrolls down within it. An opaque background matching
     the panel's own is required for this to look right once something
     is actually scrolling underneath it — otherwise the content behind
     would show through a transparent toolbar. padding/margin make the
     sticky bar's own edges not butt directly against the panel's, which
     would otherwise look like the toolbar had no breathing room at all
     once it's pinned in place. */
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--panel-bg);
  padding: 0.5rem 0;
  margin-bottom: 0.5rem;
}

.confirm-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.confirm-dialog {
  background: var(--panel-bg);
  border-radius: 6px;
  padding: 1.5rem;
  max-width: 320px;
  text-align: center;
}

.confirm-dialog button {
  margin: 0.5rem 0.25rem 0;
}

.assignment-nav-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.assignment-nav-list li {
  margin-bottom: 0.4rem;
}

/* Client, 2026-09-27, item 18: per-row action links/buttons (Users,
   Categories, Background Images, Assignments, Attempt History, the
   Admin's per-user Attempts view) sit as plain inline elements with no
   native concept of a "gap" between wrapped lines — when the window
   narrows enough that they wrap, the two lines end up touching with no
   visual separation at all. flex-wrap + gap fixes both directions at
   once: gap between buttons on the same line, and gap between wrapped
   lines, with no change to non-wrapped layouts. */
.row-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.assignment-list-item {
  background: none;
  border: none;
  color: var(--link-color);
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-decoration: underline;
  text-align: left;
}

/* Panel-collapse toggles only ever appear on the drawing/feedback
   screens, which always carry .drawing-layout (20:65:15 base) — scoped
   explicitly to it rather than bare .app-main, so the math below is
   never silently wrong if a collapse toggle is ever added to a
   different-ratio screen later. Recomputed for 20:65:15 (client,
   2026-09-27; was 25:60:15) — right-collapsed gives its freed 15 to
   main (65+15=80), left-collapsed gives its freed 20 to main (65+20=85),
   both-collapsed is unchanged either way (all freed space goes to main
   regardless of the starting ratio). */
.app-main.drawing-layout.right-panel-collapsed {
  grid-template-columns: 20fr 80fr 0fr;
}

.app-main.drawing-layout.right-panel-collapsed .panel-right {
  display: none;
}

/* Left panel toggle (client, 2026-08-06, item 4) — mirrors the right
   panel toggle above exactly. A combined rule is needed for when both
   are collapsed at once: grid-template-columns is a single property, so
   the two single-panel rules above can't just stack — whichever is
   declared later would otherwise simply overwrite the other rather than
   combining, since each fully redefines the property rather than
   adjusting one column of it. */
.app-main.drawing-layout.left-panel-collapsed {
  grid-template-columns: 0fr 85fr 15fr;
}

.app-main.drawing-layout.left-panel-collapsed .panel-left {
  display: none;
}

.app-main.drawing-layout.left-panel-collapsed.right-panel-collapsed {
  grid-template-columns: 0fr 100fr 0fr;
}

/* --- Links as buttons, all screens except the side panels (client,
   2026-07-27) — panel-left/panel-right stay plain text links
   deliberately: a dense scrollable list (assignments, attempts) reads
   better as compact text than as a column of bulky buttons. Scoped to
   .panel-main specifically, so links inside a table cell, a "back to X"
   link, download links, etc. all get the same button treatment
   consistently, without needing to touch every individual template. */
.panel-main a {
  display: inline-block;
  background: var(--org-band-bg);
  color: var(--org-band-fg);
  border: none;
  border-radius: 4px;
  padding: 0.35rem 0.85rem;
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}

.panel-main a:hover {
  opacity: 0.85;
}

/* --- Django messages framework --- */
.messages {
  list-style: none;
  margin: 0 0 1rem 0;
  padding: 0;
}

.messages li {
  padding: 0.5rem 0.75rem;
  border-radius: 4px;
  margin-bottom: 0.5rem;
}

.messages .warning {
  background: var(--warning-bg);
  color: var(--warning-fg);
}

.messages .error {
  background: var(--error-bg);
  color: var(--error-fg);
}

.messages .success {
  background: var(--success-bg);
  color: var(--success-fg);
}

/* --- Forms, all screens (client, 2026-07-26): labels stacked above their
   input rather than inline, consistent spacing, and a visible required-field
   marker. The required marker uses :has() rather than any template change —
   Django already renders a real `required` HTML attribute on every required
   field's widget, matching Field.required, so this works retroactively
   across every existing {{ form.as_p }} in the app with zero template
   edits. This also means the browser's own native HTML5 validation already
   blocks submission of a required field left blank — nothing extra needed
   for that part. --- */
form p {
  margin-bottom: 1rem;
}

form label {
  display: block;
  margin-bottom: 0.3rem;
  font-weight: 600;
}

form p:has(:required) label::after {
  content: " *";
  color: var(--error-fg);
  font-weight: 700;
}

form input[type="text"],
form input[type="email"],
form input[type="password"],
form input[type="date"],
form input[type="number"],
form input[type="file"],
form select,
form textarea {
  display: block;
  width: 100%;
  max-width: 28rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  font: inherit;
}

form textarea {
  min-height: 6rem;
}

form .helptext {
  display: block;
  font-size: 0.85rem;
  color: var(--nav-strip-fg);
  opacity: 0.8;
  margin-top: 0.2rem;
}

form ul.errorlist {
  color: var(--error-fg);
  font-size: 0.9rem;
  margin: 0.2rem 0 0.4rem 0;
  padding-left: 1.1rem;
}

/* --- Consistent left margin, all screens (client, 2026-07-26) --- */
.org-band,
.nav-strip,
.site-footer {
  padding-left: 2cm;
}

.app-main {
  margin-left: 2cm;
}

@media (max-width: 768px) {
  /* A fixed 2cm margin eats too much of a phone-width screen — drop back
     to the same padding used before this change once the layout is
     already stacking to a single column anyway. */
  .org-band,
  .nav-strip,
  .site-footer {
    padding-left: 1.5rem;
  }
  .app-main {
    margin-left: 0;
  }
}


/* =====================================================================
   Portal (client, 2026-11-01) — landing page, unified dashboard.
   All colours come from the CSS variables above, so the Global Admin's
   colour scheme applies here too. Mobile-first: single column by default,
   widened with min-width queries.
   ===================================================================== */

/* Landing page: full-width, side panels hidden. */
.app-main.landing-layout { grid-template-columns: 1fr; }
.landing-layout .panel-left,
.landing-layout .panel-right { display: none; }
.landing-layout .panel-main { grid-column: 1; }

.carousel {
  position: relative;
  max-width: 1152px;
  margin: 0 auto 1.5rem;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  overflow: hidden;
  background: #000;
}
.carousel-slide { display: none; margin: 0; }
.carousel-slide.is-active { display: block; }
.carousel-slide img { display: block; width: 100%; height: auto; max-height: 60vh; object-fit: contain; }
.carousel-slide figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 0.5rem 1rem;
  background: var(--org-band-bg); color: var(--org-band-fg);
}
.carousel-btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  background: var(--org-band-bg); color: var(--org-band-fg);
  border: none; border-radius: 4px; padding: 0.5rem 0.75rem; cursor: pointer; font-size: 1.1rem;
}
.carousel-btn.prev { left: 0.5rem; }
.carousel-btn.next { right: 0.5rem; }

.tile-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  max-width: 1152px;
  margin: 0 auto;
}
.tile { margin: 0; border: 1px solid var(--panel-border); border-radius: 6px; overflow: hidden; background: #fff; }
.tile img { display: block; width: 100%; height: auto; }
.tile figcaption { padding: 0.5rem 0.75rem; }
.tile a { text-decoration: none; display: block; }

/* Unified dashboard */
.dash-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.dash-card {
  background: #fff;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 1rem;
}
.dash-card h3 { margin-top: 0; }
.dash-card ul { list-style: none; margin: 0; padding: 0; }
.dash-card li { margin: 0.35rem 0; }
.dash-disabled { opacity: 0.6; }
.theme-grid { display: grid; gap: 0.5rem 1.5rem; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.theme-grid p { margin: 0; }

/* Image links on the landing page must not pick up the site's button
   styling (.panel-main a) — they wrap pictures, not labels. */
.panel-main .tile a,
.panel-main .carousel a {
  background: none;
  color: inherit;
  padding: 0;
  border: none;
  border-radius: 0;
  display: block;
}
.panel-main .tile figcaption { color: var(--link-color); }
