@import url("/assets/fonts/fonts.css");

/* ===========================================================================
   Registration Portal — "warm paper, clinical signal"

   A calm off-white ground so the only saturated things on screen are
   statuses. Serif for headings keeps it human; mono for dates and counts
   keeps it checkable.

   The five status colours are the vocabulary of the whole product and they
   mean the same thing on every screen, every time:

     cleared   green   nothing to do
     expiring  amber   valid now, invalid before they finish
     missing   rust    nothing on file, or sent back
     review    blue    waiting on Katherine
     neutral   stone   not required here

   Deliberately light-only. This is a specific art direction — a warm paper
   ground is the point — and a dark inversion would be a different product.
   =========================================================================== */

:root {
  --paper:      #EFEAE1;
  --surface:    #F7F4EF;
  --card:       #FFFFFF;
  --card-soft:  #FCFBF8;
  --ink:        #191714;
  --ink-2:      #3D3830;
  --ink-3:      #544D43;
  --muted:      #6B6459;
  --muted-2:    #8A8377;
  --muted-3:    #9A9284;
  --faint:      #A8A093;
  /* Placeholder cream. Roughly 30% lighter than --muted-3 and warmed into the
     paper's own family, so an empty field reads as stationery rather than as
     faint data. Never use this for anything a person actually typed. */
  --placeholder: #C6B9A0;

  --cleared:    #1F6F5C;
  --cleared-bg: #E6F0EC;
  --expiring:   #B8791F;
  --expiring-fg:#8A5A12;
  --expiring-bg:#FBF0DC;
  --missing:    #A8412B;
  --missing-fg: #8E3320;
  --missing-bg: #F7E4DF;
  --review:     #2A5C8A;
  --review-fg:  #1B3E5E;
  --review-bg:  #E8EDF5;
  --neutral-bg: #F2EFE9;

  --line:       rgba(25, 23, 20, .10);
  --line-soft:  rgba(25, 23, 20, .06);
  --line-firm:  rgba(25, 23, 20, .16);
  --swatch:     #EAE4D9;

  --serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --sans:  'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono:  'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --r-sm: 6px;  --r:  9px;  --r-lg: 11px;  --r-pill: 999px;
  --sidebar: 250px;
  --shadow: 0 1px 3px rgba(25, 23, 20, .07);
  --shadow-lift: 0 6px 20px rgba(25, 23, 20, .10);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Containers are wide and several tables carry fixed-width columns, so a
     narrow window must clip inside its own scroller rather than pushing the
     whole page sideways. Wide content sits in .scroll-x for that reason. */
  overflow-x: hidden;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 17px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--review); text-decoration: none; }
a:hover { color: var(--review-fg); text-decoration: underline; }

h1, h2, h3 { font-family: var(--serif); font-weight: 400; letter-spacing: -.01em; margin: 0; }
h1 { font-size: 41px; line-height: 1.08; }
h2 { font-size: 31px; line-height: 1.12; }
h3 { font-size: 24px; line-height: 1.2; }

p { margin: 0 0 14px; }
p:last-child { margin-bottom: 0; }

.mono { font-family: var(--mono); }
.serif { font-family: var(--serif); }
.muted { color: var(--muted); }
.muted-2 { color: var(--muted-2); }
.small { font-size: 14px; }
.xs { font-size: 13px; }
.nowrap { white-space: nowrap; }
.right { text-align: right; }
.center { text-align: center; }
.grow { flex: 1; min-width: 0; }
.pretty { text-wrap: pretty; }

.eyebrow {
  font: 400 13px/1 var(--mono);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.eyebrow--tight { font-size: 13px; font-weight: 600; letter-spacing: .05em; }

/* --- Layout --------------------------------------------------------------- */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar);
  flex: none;
  background: var(--ink);
  color: var(--paper);
  padding: 24px 0;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}
.sidebar__brand {
  padding: 0 24px 26px;
  display: flex;
  align-items: center;
  gap: 12px;
  color: inherit;
}
.sidebar__brand:hover { text-decoration: none; }
.mark {
  width: 31px; height: 31px; flex: none;
  border-radius: var(--r-sm);
  background: var(--cleared);
  display: flex; align-items: center; justify-content: center;
  font: 600 14px var(--mono); color: #fff;
}
.sidebar__name { font: 500 16px var(--sans); color: var(--paper); }
.sidebar__nav { display: flex; flex-direction: column; gap: 2px; padding: 0 10px; }
.sidebar__link {
  padding: 10px 14px;
  border-radius: var(--r-sm);
  font: 400 16px var(--sans);
  color: rgba(239, 234, 225, .72);
  display: flex; align-items: center; gap: 10px;
}
.sidebar__link:hover { background: rgba(255, 255, 255, .06); color: var(--paper); text-decoration: none; }
.sidebar__link.is-on { background: rgba(255, 255, 255, .11); color: var(--paper); font-weight: 500; }
.sidebar__count { margin-left: auto; font: 500 13px var(--mono); color: #E8A88C; }
.sidebar__foot {
  margin-top: auto;
  padding: 19px 24px 0;
  margin-inline: 10px;
  border-top: 1px solid rgba(255, 255, 255, .10);
}
.sidebar__stat { font: 500 23px var(--mono); color: var(--paper); }
.sidebar__sub { font: 400 13px var(--sans); color: rgba(239, 234, 225, .55); margin-top: 2px; }

.main { flex: 1; background: var(--surface); min-width: 0; display: flex; flex-direction: column; }

.topbar {
  height: 67px; flex: none;
  border-bottom: 1px solid var(--line);
  background: var(--card);
  display: flex; align-items: center; gap: 17px;
  padding: 0 29px;
  position: sticky; top: 0; z-index: 20;
}
.search {
  flex: 1; max-width: 408px;
}
.search input {
  width: 100%; height: 40px;
  border: 1px solid rgba(25, 23, 20, .14);
  border-radius: 7px;
  padding: 0 14px;
  font: 400 15px var(--sans);
  background: var(--card);
  color: var(--ink);
}
/* The search box takes the shared placeholder treatment — see ::placeholder
   below. It used to be the only field with one, which is how everything else
   ended up looking like it had a value in it. */
.search input:focus { outline: 2px solid rgba(42, 92, 138, .35); outline-offset: -1px; border-color: var(--review); }

.avatar {
  width: 35px; height: 35px; flex: none;
  border-radius: 50%;
  background: #DCD5C8;
  display: flex; align-items: center; justify-content: center;
  font: 600 13px var(--sans); color: var(--ink-3);
}
.avatar:hover { text-decoration: none; color: var(--ink-3); }

.page { flex: 1; padding: 29px; min-width: 0; }
.page--wide { padding: 29px 31px; }
.page__head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 5px; }
/* A lede is a caption under a heading, not an essay.
 *
 * It was capped at 78ch — the classic measure for sustained reading — which is
 * right for a page of prose and wrong here: on a 1,140px screen it left a 630px
 * ribbon of text stranded in empty space above a full-width table. 96ch is
 * still comfortably inside the range where the eye can find the start of the
 * next line, and it stops the pinching.
 *
 * Pages whose own container already provides the measure use --wide and let it
 * run. Do NOT put --wide on a full-width page: unbounded, a lede on a wide
 * monitor reaches ~190ch, and tracking back to the next line becomes real work. */
.page__lede { font: 400 16px/1.5 var(--sans); color: var(--muted); margin: 0 0 22px; max-width: 96ch; }
.page__lede--wide { max-width: none; }

/* --- Cards ---------------------------------------------------------------- */

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.card--pad { padding: 19px 22px; }
.card__head {
  padding: 16px 22px;
  border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.card__title { font: 600 14px var(--sans); }
.card__foot {
  padding: 13px 22px;
  background: var(--card-soft);
  border-top: 1px solid var(--line-soft);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  font: 400 14px var(--sans); color: var(--muted-2);
}

.stack { display: flex; flex-direction: column; gap: 17px; }
.row { display: flex; align-items: center; gap: 12px; }
.row--baseline { align-items: baseline; }
.wrap { flex-wrap: wrap; }
.split { display: flex; gap: 22px; align-items: flex-start; }
/* The rail carries whole sentences — queue headlines, receipt lines — so at
   the larger type it needs the extra width or every item wraps to four lines. */
.split__aside { width: 420px; flex: none; }
@media (max-width: 1500px) {
  .split { flex-direction: column; }
  .split__aside { width: 100%; }
}

/* --- Stat tiles ----------------------------------------------------------- */

.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 24px; }
@media (max-width: 1100px) { .tiles { grid-template-columns: repeat(2, 1fr); } }
.tile {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 16px 17px;
  display: block;
}
.tile:hover { text-decoration: none; border-color: var(--line-firm); }
.tile__n { font: 500 29px/1 var(--mono); color: var(--ink); }
.tile__l { font: 400 13px/1.3 var(--sans); color: var(--muted); margin-top: 5px; }
.tile--missing  .tile__n { color: var(--missing); }
.tile--expiring .tile__n { color: var(--expiring); }
.tile--cleared  .tile__n { color: var(--cleared); }
.tile--review   .tile__n { color: var(--review); }

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 38px; padding: 0 16px;
  border-radius: 7px;
  border: 1px solid var(--line-firm);
  background: var(--card);
  color: var(--ink);
  font: 500 15px var(--sans);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.btn:hover { text-decoration: none; color: var(--ink); background: var(--surface); }
.btn--primary { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn--primary:hover { background: #2B2723; color: #fff; }
.btn--go { background: var(--cleared); border-color: var(--cleared); color: #fff; }
.btn--go:hover { background: #1A5E4E; color: #fff; }
.btn--danger { border-color: rgba(168, 65, 43, .4); color: var(--missing); background: var(--card); }
.btn--danger:hover { background: var(--missing-bg); color: var(--missing-fg); }
.btn--lg { height: 46px; padding: 0 19px; font-size: 16px; }
.btn--sm { height: 31px; padding: 0 12px; font-size: 14px; }
.btn--block { width: 100%; }
.btn[disabled], .btn.is-disabled { opacity: .45; pointer-events: none; }

.link-action { font: 500 14px var(--sans); color: var(--review); white-space: nowrap; }

/* --- Chips, pills, filters ------------------------------------------------ */

.chips { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  height: 31px; padding: 0 13px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  color: var(--ink-3);
  font: 500 14px var(--sans);
  white-space: nowrap;
  border: 1px solid transparent;
}
.chip:hover { text-decoration: none; border-color: var(--line-firm); }
.chip.is-on { background: var(--ink); color: #fff; }
.chip--dashed { background: transparent; border: 1px dashed rgba(25, 23, 20, .22); color: var(--muted); }
.chip__n { font-family: var(--mono); font-size: 13px; opacity: .8; }

.pill {
  display: inline-flex; align-items: center;
  height: 26px; padding: 0 11px;
  border-radius: var(--r-pill);
  font: 500 13px var(--sans);
  white-space: nowrap;
  background: var(--neutral-bg); color: var(--ink-3);
}
.pill--lg { height: 29px; font-size: 13px; padding: 0 12px; }

.is-cleared  { background: var(--cleared-bg);  color: var(--cleared); }
.is-expiring { background: var(--expiring-bg); color: var(--expiring-fg); }
.is-missing  { background: var(--missing-bg);  color: var(--missing-fg); }
.is-review   { background: var(--review-bg);   color: var(--review); }
.is-neutral  { background: var(--neutral-bg);  color: var(--muted-2); }

.t-cleared  { color: var(--cleared); }
.t-expiring { color: var(--expiring-fg); }
.t-missing  { color: var(--missing-fg); }
.t-review   { color: var(--review); }

/* --- Tables --------------------------------------------------------------- */

.tbl { width: 100%; }
.tbl__head {
  display: flex; align-items: center;
  padding: 11px 22px;
  border-bottom: 1px solid var(--line);
  font: 600 13px var(--mono);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted-2);
}
.tbl__row {
  display: flex; align-items: center;
  padding: 13px 22px;
  border-bottom: 1px solid var(--line-soft);
}
.tbl__row:last-child { border-bottom: 0; }
.tbl__row:hover { background: var(--card-soft); }
.tbl__row--sub { padding-block: 11px; }
.cell-name { font: 500 16px/1.3 var(--sans); }
.cell-sub  { font: 400 13px/1.35 var(--sans); color: var(--muted-2); margin-top: 2px; }

/* Spine rows — a rounded row with a coloured left bar carrying the state. */
.spine {
  display: flex; align-items: center; gap: 17px;
  padding: 14px 19px;
  border-bottom: 1px solid var(--line-soft);
}
.spine:last-child { border-bottom: 0; }
.spine:hover { background: var(--card-soft); }
.spine__bar { width: 6px; height: 41px; border-radius: 3px; flex: none; background: var(--swatch); }
.spine__bar.is-cleared  { background: var(--cleared); }
.spine__bar.is-expiring { background: var(--expiring); }
.spine__bar.is-missing  { background: var(--missing); }
.spine__bar.is-review   { background: var(--review); }

/* --- Progress ------------------------------------------------------------- */

.meter { height: 6px; border-radius: 3px; background: var(--swatch); overflow: hidden; display: flex; }
.meter--lg { height: 12px; border-radius: 5px; }
.meter__seg { height: 100%; }
.meter__seg.is-cleared  { background: var(--cleared); }
.meter__seg.is-expiring { background: var(--expiring); }
.meter__seg.is-missing  { background: var(--missing); }
.meter__seg.is-review   { background: var(--review); }

.ring {
  width: 55px; height: 55px; flex: none;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.ring__in {
  width: 41px; height: 41px; border-radius: 50%;
  background: var(--card);
  display: flex; align-items: center; justify-content: center;
  font: 500 13px var(--mono);
}

/* --- The credential pip strip -------------------------------------------- */
/* One pip per required credential, in a stable order, so the shape of a
   person's compliance is recognisable at a glance across screens. */

.pips { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.pip {
  width: 17px; height: 24px;
  border-radius: 3px;
  background: var(--swatch);
  display: block;
}
.pip.is-cleared  { background: var(--cleared); }
.pip.is-expiring { background: var(--expiring); }
.pip.is-missing  { background: var(--missing); }
.pip.is-review   { background: var(--review); }
.pip.is-na       { background: var(--neutral-bg); }
.pips__ratio { margin-left: 10px; font: 400 13px var(--mono); color: var(--muted-2); }

/* Matrix cells */
.mcell {
  width: 31px; height: 31px;
  border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  font: 500 12px var(--mono);
  margin: 0 auto;
}

/* --- Forms ---------------------------------------------------------------- */

.field { display: block; margin-bottom: 14px; }
.field__label {
  display: block;
  font: 600 12px var(--mono);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted-2);
  margin-bottom: 6px;
}
.field__label--warn { color: var(--expiring); }
.input, select.input, textarea.input {
  width: 100%;
  height: 43px;
  border: 1px solid rgba(25, 23, 20, .14);
  border-radius: 7px;
  padding: 0 12px;
  font: 400 15px var(--sans);
  background: var(--card);
  color: var(--ink);
}
textarea.input { height: auto; padding: 11px 12px; line-height: 1.5; resize: vertical; }
.input.mono { font-family: var(--mono); }

/* --- Placeholders ---------------------------------------------------------
   A placeholder is an EXAMPLE, never a value, and on a screen full of real
   dates and licence numbers that difference has to be unmistakable at a
   glance. Only the search box was ever styled here; every other field fell
   through to the browser's default dark grey, which reads exactly like
   something somebody typed.

   Three signals, because one is not enough: cream rather than ink, well
   below the weight of real text, and italic. Cream specifically — it belongs
   to the warm paper the whole product sits on, so an empty field reads as
   part of the stationery rather than as faint data.

   The contrast is deliberately low (~2:1). That is acceptable here and only
   here: every field carries its own <label> above it, so the placeholder
   never carries meaning on its own — it is an example of the shape of an
   answer. Do not start putting the label in the placeholder.
   ------------------------------------------------------------------------- */

::placeholder {
  color: var(--placeholder);
  font-style: italic;
  opacity: 1;                      /* Firefox dims placeholders by default */
}

/* A select showing its empty option is a placeholder too — "Choose your
   school…" is not a school. */
select.input:has(option[value=""]:checked) {
  color: var(--placeholder);
  font-style: italic;
}
select.input option { color: var(--ink); font-style: normal; }

/* An empty date field shows the browser's own mm/dd/yyyy, which the rule
   above cannot reach. Controllers add .is-empty when there is no value —
   see the "Expires" field in the document reader, which is blank precisely
   because the extractor could not read it. */
.input.is-empty { color: var(--placeholder); font-style: italic; }
.input.is-empty::-webkit-datetime-edit { color: var(--placeholder); }
.input:focus { outline: 2px solid rgba(42, 92, 138, .3); outline-offset: -1px; border-color: var(--review); }
.input--warn { border: 1.5px solid var(--expiring); background: #FEFAF2; }
.field__hint { font: 400 13px/1.45 var(--sans); color: var(--muted-2); margin-top: 7px; }

.check { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--cleared); }

.toggle {
  width: 46px; height: 26px; flex: none;
  border-radius: var(--r-pill);
  background: rgba(25, 23, 20, .18);
  position: relative;
  border: 0; padding: 0; cursor: pointer;
  transition: background .12s ease;
}
.toggle__dot {
  position: absolute; top: 4px; left: 4px;
  width: 19px; height: 19px; border-radius: 50%;
  background: #fff;
  transition: left .12s ease;
}
.toggle.is-on { background: var(--cleared); }
.toggle.is-on .toggle__dot { left: 23px; }
.toggle--sm { width: 41px; height: 24px; }
.toggle--sm .toggle__dot { width: 17px; height: 17px; }
.toggle--sm.is-on .toggle__dot { left: 20px; }

.dropzone {
  border: 1.5px dashed rgba(31, 111, 92, .4);
  border-radius: var(--r);
  background: #F6FAF8;
  padding: 31px;
  text-align: center;
}
.dropzone__t { font: 500 16px var(--sans); color: var(--cleared); }
.dropzone__s { font: 400 14px var(--sans); color: #6B8B80; margin-top: 5px; }

/* --- Notes and banners ---------------------------------------------------- */

.note {
  padding: 14px 17px;
  border-radius: var(--r);
  font: 400 14px/1.6 var(--sans);
}
.note--info   { background: #F2F4F7;           color: #4A5666; border: 1px solid rgba(25, 23, 20, .10); }
/* Pale blue-grey, NOT the demonstration blue. A product message must never
   be mistaken for scaffolding that is about to disappear. */
.note--warn   { background: var(--expiring-bg); color: var(--expiring-fg); border: 1px solid rgba(184, 121, 31, .25); }
.note--stop   { background: var(--missing-bg);  color: var(--missing-fg); border: 1px solid rgba(168, 65, 43, .25); }
.note--ok     { background: var(--cleared-bg);  color: var(--cleared); border: 1px solid rgba(31, 111, 92, .2); }
.note--plain  { background: var(--surface);     color: var(--ink-3); border: 1px solid var(--line); }

.demo-bar {
  background: var(--ink);
  color: rgba(239, 234, 225, .82);
  font: 400 14px/1.45 var(--sans);
  padding: 8px 29px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.demo-bar strong { color: #fff; font-weight: 600; }
.demo-bar a { color: #E8A88C; }

.flashes { position: fixed; right: 24px; bottom: 24px; z-index: 60; display: flex; flex-direction: column; gap: 10px; max-width: 504px; }
.flash {
  padding: 13px 17px;
  border-radius: var(--r);
  box-shadow: var(--shadow-lift);
  font: 400 15px/1.5 var(--sans);
  background: var(--ink); color: #fff;
}
.flash.is-warn { background: var(--expiring-bg); color: var(--expiring-fg); border: 1px solid rgba(184,121,31,.3); }
.flash.is-stop { background: var(--missing-bg);  color: var(--missing-fg); border: 1px solid rgba(168,65,43,.3); }

/* --- Horizon (the rolling-days home screen) ------------------------------- */

.bucket { margin-bottom: 22px; }
.bucket__head { display: flex; align-items: baseline; gap: 11px; margin-bottom: 8px; }
.bucket__label {
  font: 600 13px var(--mono);
  letter-spacing: .06em; text-transform: uppercase;
}
.bucket__rule { flex: 1; height: 1px; background: var(--line); }
.bucket__sum { font: 400 13px var(--mono); color: var(--muted-2); white-space: nowrap; }

.days { width: 65px; flex: none; text-align: center; }
.days__n { font: 500 20px/1 var(--mono); }
.days__l { font: 400 11px var(--sans); color: var(--faint); margin-top: 2px; }

/* --- Triage deck ---------------------------------------------------------- */

.deck { position: relative; max-width: 624px; }
.deck__shadow {
  position: absolute; left: 10px; right: 10px; top: 19px; bottom: 0;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); opacity: .5;
}
.deck__shadow--2 { left: 5px; right: 5px; top: 10px; opacity: .75; }
.deck__card {
  position: relative;
  background: var(--card);
  border: 1px solid rgba(25, 23, 20, .14);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}
.deck__body { padding: 22px; }
.deck__statement { font: 400 18px/1.5 var(--sans); color: var(--ink); margin-bottom: 19px; }
.deck__statement strong { font-weight: 600; }
.choice {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  min-height: 46px; padding: 10px 17px;
  border-radius: 8px;
  border: 1px solid var(--line-firm);
  background: var(--card);
  font: 500 15px/1.35 var(--sans);
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.choice:hover { background: var(--surface); text-decoration: none; color: var(--ink); }
.choice--primary { background: var(--ink); border-color: var(--ink); color: #fff; }
.choice--primary:hover { background: #2B2723; color: #fff; }
.choice__key {
  font: 500 12px var(--mono);
  background: rgba(25, 23, 20, .08);
  padding: 2px 6px; border-radius: 3px;
  flex: none;
}
.choice--primary .choice__key { background: rgba(255, 255, 255, .16); }

/* --- Document review (read and confirm) ----------------------------------- */

.reader { display: flex; min-height: 672px; }
@media (max-width: 1250px) { .reader { flex-direction: column; } }
.reader__doc {
  flex: 1; min-width: 0;
  background: #2A2724;
  display: flex; flex-direction: column;
}
.reader__bar {
  flex: none; padding: 13px 19px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border-bottom: 1px solid rgba(255, 255, 255, .10);
  font: 500 14px var(--sans); color: var(--paper);
}
.reader__bar .muted { color: rgba(239, 234, 225, .5); }
.reader__stage { flex: 1; display: flex; align-items: center; justify-content: center; padding: 29px; }
.reader__side {
  width: 432px; flex: none;
  background: var(--card);
  display: flex; flex-direction: column;
  border-left: 1px solid var(--line);
}
@media (max-width: 1250px) { .reader__side { width: 100%; border-left: 0; border-top: 1px solid var(--line); } }

/* A stand-in for the scanned page: enough to read the layout, never
   pretending to be a real document. */
.scan {
  width: 100%; max-width: 408px;
  aspect-ratio: 8.5 / 11;
  background: #F4F1EA;
  border-radius: 3px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .4);
  padding: 31px;
  display: flex; flex-direction: column; gap: 11px;
}
.scan__line { height: 7px; background: #E2DDD2; border-radius: 2px; }
.scan__line--head { height: 11px; background: #D6D0C4; }
.scan__hl {
  margin: 14px 0; padding: 12px;
  border: 2px solid var(--expiring);
  border-radius: 4px;
  background: rgba(184, 121, 31, .09);
  display: flex; flex-direction: column; gap: 7px;
}
.scan__hl .scan__line { background: #C9B48C; }
.scan__sig { margin-top: auto; height: 26px; width: 44%; background: #DCD5C8; border-radius: 2px; }

/* --- Badge proof ---------------------------------------------------------- */

.badge-proof { border: 1px solid rgba(25, 23, 20, .12); border-radius: 8px; overflow: hidden; background: var(--card); }
.badge-proof__stripe { height: 8px; background: var(--cleared); }
.badge-proof__body { padding: 14px; display: flex; gap: 13px; }
.badge-proof__photo {
  width: 72px; height: 89px; flex: none;
  border-radius: 4px; background: var(--swatch);
  display: flex; align-items: center; justify-content: center;
  font: 400 11px var(--sans); color: var(--muted-3); text-align: center;
}
.badge-proof__name { font: 600 16px/1.2 var(--sans); }
.badge-proof__line { font: 400 13px var(--sans); color: var(--muted); margin-top: 2px; }
.badge-proof__code {
  height: 26px; margin: 0 14px 14px;
  background: repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px 4px, var(--ink) 4px 5px, transparent 5px 9px);
}
.badge-proof--void { opacity: .5; }
.badge-proof--void .badge-proof__stripe { background: var(--missing); }

/* --- Email preview -------------------------------------------------------- */

.mail { background: var(--card); border: 1px solid rgba(25, 23, 20, .12); border-radius: var(--r); overflow: hidden; }
.mail__head { padding: 13px 19px; border-bottom: 1px solid var(--line-soft); background: var(--card-soft); }
.mail__subject { font: 500 14px var(--sans); }
.mail__from { font: 400 13px var(--sans); color: var(--muted-2); margin-top: 2px; }
.mail__body { padding: 26px 29px; font: 400 17px/1.65 var(--sans); color: var(--ink); white-space: pre-wrap; }
.mail__foot {
  padding: 14px 29px; background: var(--card-soft);
  border-top: 1px solid var(--line-soft);
  font: 400 13px/1.5 var(--sans); color: var(--muted-3);
}

/* --- Timeline ------------------------------------------------------------- */

.tl { display: flex; gap: 14px; }
.tl__rail { width: 17px; flex: none; display: flex; flex-direction: column; align-items: center; }
.tl__dot { width: 11px; height: 11px; border-radius: 50%; background: var(--swatch); margin-top: 6px; flex: none; }
.tl__line { flex: 1; width: 1px; background: rgba(25, 23, 20, .12); }
.tl__body { flex: 1; min-width: 0; padding-bottom: 17px; }
.tl__t { font: 500 14px var(--sans); }
.tl__s { font: 400 13px/1.5 var(--sans); color: var(--muted-2); margin-top: 2px; }
.tl__w { font: 400 12px var(--mono); color: var(--faint); margin-top: 4px; }

/* --- Sign in -------------------------------------------------------------- */

.signin { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 48px 24px; }
.signin__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; max-width: 1320px; width: 100%; align-items: start; }
@media (max-width: 1150px) { .signin__grid { grid-template-columns: 1fr; } }
.signin__flag {
  padding: 11px 19px; background: var(--ink); color: #fff;
  font: 500 13px var(--mono); letter-spacing: .04em;
}
.persona {
  display: flex; align-items: center; gap: 14px;
  width: 100%;
  padding: 13px 17px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--card);
  text-align: left;
  cursor: pointer;
  color: var(--ink);
}
.persona:hover { border-color: var(--line-firm); background: var(--surface); text-decoration: none; color: var(--ink); }
.persona__avatar {
  width: 41px; height: 41px; flex: none; border-radius: 8px;
  background: var(--swatch);
  display: flex; align-items: center; justify-content: center;
  font: 500 14px var(--sans); color: var(--muted-2);
}

/* --- Utility -------------------------------------------------------------- */

.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 17px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 17px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 17px; }
@media (max-width: 1450px) { .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 1100px) { .grid-3, .grid-2 { grid-template-columns: 1fr; } }

.scroll-x { overflow-x: auto; }
.hr { height: 1px; background: var(--line); border: 0; margin: 19px 0; }

.empty {
  padding: 48px 29px; text-align: center;
  color: var(--muted-2);
  font: 400 16px/1.6 var(--sans);
}
.empty__t { font-family: var(--serif); font-size: 26px; color: var(--ink); margin-bottom: 7px; }

.steps { display: flex; gap: 10px; margin-bottom: 24px; flex-wrap: wrap; }
.step {
  flex: 1; min-width: 168px;
  padding: 12px 14px; border-radius: 8px;
  background: var(--card); border: 1px solid rgba(25, 23, 20, .12);
}
.step__n { font: 500 12px var(--mono); color: var(--muted-3); }
.step__t { font: 500 14px var(--sans); color: var(--muted-3); margin-top: 4px; }
.step.is-done { background: var(--cleared-bg); border-color: rgba(31, 111, 92, .2); }
.step.is-done .step__n, .step.is-done .step__t { color: var(--cleared); }
.step.is-now { background: var(--ink); border-color: var(--ink); }
.step.is-now .step__n { color: rgba(255, 255, 255, .6); }
.step.is-now .step__t { color: #fff; }

@media print {
  .sidebar, .topbar, .demo-bar, .flashes, .btn { display: none !important; }
  body { background: #fff; }
  .page { padding: 0; }
}

/* ===========================================================================
   DEMONSTRATION SCAFFOLDING

   Everything in soft blue is here ONLY to make the demonstration walkable and
   will not exist when the site goes live. Not the data — the data becomes real
   students — but the machinery around it:

     · the banner explaining that nothing here is a real person
     · the persona picker that signs you in without a password
     · the "let the documents arrive" shortcut that manufactures a roster's
       outstanding paperwork
     · the sample CSV, for walking the upload without a file to hand

   The blue is deliberately unlike anything in the product's own palette —
   nothing else on the site has a blue ground — so it reads as an overlay
   rather than as a feature. The dashed edge says the same thing again for
   anyone who does not register colour.

   Every one of these is gated on DEMO_MODE in PHP. Setting DEMO_MODE=0 in
   .env removes them; none of these styles will match anything, and what is
   left is the product.
   =========================================================================== */

:root {
  --demo-bg:      #DCE8F7;
  --demo-bg-2:    #CBDDF2;
  --demo-edge:    #8DB2DA;
  --demo-ink:     #2C5480;
  --demo-ink-2:   #4A719A;
}

/* The banner across the top of every page. */
.demo-bar {
  background: var(--demo-bg-2);
  color: var(--demo-ink);
  border-bottom: 1px solid var(--demo-edge);
  font: 400 14px/1.45 var(--sans);
  padding: 10px 29px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.demo-bar strong { color: var(--demo-ink); font-weight: 600; }
.demo-bar a { color: var(--demo-ink); text-decoration: underline; }
.demo-bar a:hover { color: #1B3A5C; }

/* A whole block that exists only for the demo. */
.demo-block {
  background: var(--demo-bg);
  border: 1px dashed var(--demo-edge);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.demo-block .card,
.demo-block .persona {
  background: rgba(255, 255, 255, .72);
  border-color: var(--demo-edge);
}
.demo-block .persona:hover { background: #fff; }

/* Its header strip — the "DEMONSTRATION · …" label. */
.demo-block__flag {
  padding: 11px 19px;
  background: var(--demo-edge);
  color: #16324F;
  font: 600 13px var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
  display: flex; align-items: center; gap: 10px;
}
.demo-block__body { padding: 19px 22px; }
.demo-block__body,
.demo-block .cell-name,
.demo-block .cell-sub,
.demo-block .card__title { color: var(--demo-ink); }
.demo-block .muted,
.demo-block .muted-2,
.demo-block .xs { color: var(--demo-ink-2); }

/* An inline note about a demo affordance, where a whole block is too much. */
.demo-note {
  background: var(--demo-bg);
  border: 1px dashed var(--demo-edge);
  border-radius: var(--r);
  color: var(--demo-ink);
  font: 400 14px/1.6 var(--sans);
  padding: 13px 15px;
}
.demo-note strong { font-weight: 600; }

/* A control that only works because this is a demonstration. */
.btn--demo {
  background: var(--demo-bg);
  border: 1px dashed var(--demo-edge);
  color: var(--demo-ink);
}
.btn--demo:hover { background: var(--demo-bg-2); color: #1B3A5C; }

/* The little "not in production" tag. */
.demo-tag {
  display: inline-flex; align-items: center;
  height: 21px; padding: 0 8px;
  border-radius: var(--r-pill);
  background: var(--demo-edge);
  color: #16324F;
  font: 600 11px var(--mono);
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
}
