/* Colby Forms design tokens + components.

   Adapted from apps/diploma/app/static/css/components.css -- the most complete
   console kit in the repo -- retinted to Assessment's current palette so the
   college's staff tools read as one suite: #005BDE brand, #01214B navy,
   #2E8BFC sky accent, Space Grotesk + Inter + IBM Plex Mono.

   The token VALUES below mirror ../../tailwind.config.js. Change both or they
   drift.

   Everything specific to printing a diploma -- the award grid, the batch strip,
   the PDF preview shell -- was dropped rather than carried across unused. What is
   here is the console vocabulary: a rail of sections, ruled sheets of rows, quiet
   cards, and mono for anything that is a *record* (reference numbers, field ids,
   counts, timestamps) so it can be read one character at a time.

   Tailwind is compiled at build time and its stylesheet is linked AFTER this one
   -- see the comment on that <link> in base.html for why the order is
   load-bearing. @apply is deliberately not used here: this file is plain CSS that
   composes alongside utility classes in the templates, and it has to keep working
   whether or not the build has been run.

   -- Where a rule belongs ------------------------------------------------------
   HERE, if two or more pages draw it. In a page's own `head_extra`, if exactly
   one does. Before adding a class, check whether one of these already says it --
   `.card`, `.card--flush`, `.subcard`, `.check-row`, `.table-link`, `.pill`,
   `.empty-state`, `.page-head`, `.pager`, `.tabs`.

   -- The two rules that are not taste ------------------------------------------
   1. State is never carried by colour alone. Every pill, tab, rail item and
      checked row says what it is in words, and the tint is the second signal
      (WCAG 1.4.1).
   2. Every colour pairing in this file clears WCAG AA against the surface it
      actually lands on. The contrast notes on --ink-faint and --border-field
      record what was measured and why those two are where they are. */

:root {
  /* Surfaces. The page is the tinted one and cards are white -- Assessment's
     arrangement, and the reason its console reads as cards rather than as ruled
     regions. */
  --bg:            #F4F6FA;
  --surface:       #FFFFFF;
  --surface-2:     #EAF2FE;

  /* Borders.

     `--border` and `--divider` are DECORATIVE: they separate regions that are
     already identifiable without them (a card's edge, a rule between rows), so
     WCAG 1.4.11 does not apply and they stay quiet.

     `--border-field` is not decorative. An empty text input is identified by its
     boundary and nothing else, so that boundary is "visual information required
     to identify a user interface component" and owes 3:1 against the page.
     Carried over from diploma at #848C99 (3.39:1) for exactly that reason. */
  --border:        #D9DDE3;
  --border-strong: #BFC1C3;
  --border-field:  #848C99;
  --divider:       #EBEEF2;

  /* Ink (text).

     Four steps. `--ink-heading` is the navy from the wordmark and carries every
     h1-h4; `--ink-faint` is #656E7A rather than a lighter grey because it is used
     almost entirely at 11-13px, where the large-text contrast exemption does not
     apply and the usual #8A93A3 fails AA on both the white cards and the tinted
     page. The hierarchy leans on size, weight and caps rather than on fading the
     text past legibility. */
  --ink:           #1E2A38;
  --ink-heading:   #01214B;
  --ink-soft:      #5A6573;
  --ink-faint:     #656E7A;

  /* Brand.

     --brand-soft / --sky (#D3E3FB, #8DC8E8) are DECORATIVE ONLY: both are under
     2:1 on white. Never set text in them, and never make one the only thing
     carrying a state. */
  --brand:         #005BDE;
  --brand-hover:   #01214B;
  --brand-soft:    #D3E3FB;
  --brand-tint:    #EAF2FE;
  --navy:          #01214B;
  --sky:           #8DC8E8;
  --on-brand:      #FFFFFF;

  /* Sky accent -- the mark's top bar. Used for the eyebrow rule and for the
     focus ring on the public form, where the brand blue sits under the field. */
  --accent:        #2E8BFC;
  --accent-soft:   #E4F0FF;

  /* Status */
  --success:       #0E7A5F;
  --success-soft:  #E3F5EF;
  --on-success:    #FFFFFF;
  --warning:       #B45309;
  --warning-soft:  #FBEFD9;
  --danger:        #C2392E;
  --danger-soft:   #FBE6E3;
  /* The pill sets these two colours smaller than anything else does — 12px,
     normal weight, on their own tint — and that is the one size at which they
     miss WCAG AA: axe measures --warning at 4.41:1 and --danger at 4.47:1 on
     their tints, against a 4.5 floor. A darker ink of the same hue for the pill
     (6.5:1 and 5.8:1) rather than moving the whole palette, which is correct
     everywhere it is larger, bolder, or a background. */
  --warning-ink:   #8A4108;
  --danger-ink:    #A82C22;

  /* Type */
  --font-sans:     "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-heading:  "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:     "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Shadow */
  --shadow-card:   0 1px 2px rgba(1, 33, 75, 0.05), 0 1px 3px rgba(1, 33, 75, 0.08);
  --shadow-card-hover: 0 6px 18px rgba(1, 33, 75, 0.12);
  --shadow-modal:  0 24px 60px rgba(1, 33, 75, 0.22);

  /* Radii */
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-full: 9999px;

  --rail-width: 15.5rem;
}

html, body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-feature-settings: "cv02", "cv03", "cv04", "cv11";
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .display {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--ink-heading);
  letter-spacing: -0.015em;
}

/* Small-caps label above a section heading or stat. */
.eyebrow {
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.4;
}

.eyebrow-brand   { color: var(--brand); }
.eyebrow-success { color: var(--success); }
.eyebrow-warning { color: var(--warning); }

/* Records, not prose: applicant ids, field ids, counts, timestamps. */
.num, [data-tabular] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum", "ss01";
}
.record {
  font-family: var(--font-mono);
  font-feature-settings: "tnum";
  letter-spacing: -0.01em;
}

/* ─── Brand mark ────────────────────────────────────────────────────────────
   The owner's artwork, static/img/brand/ (2026-10-31). The full logo where the app
   is named: the plain masthead here, the open rail below. The icon
   (_partials/_mark.html) where there is no room for it: the folded rail and the
   applicant masthead, whose words name the application. */
.brandmark { display: block; text-decoration: none; color: inherit; }
.brandmark__seal {
  grid-row: span 2;
  width: 1.75rem;
  height: 1.75rem;
}
.brandmark__logo { display: block; height: 2rem; width: auto; max-width: none; }

/* Cards */
.card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 1.5rem;
}

.card-shadow {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-card);
}

/* A card whose whole content is one edge-to-edge thing — a table, a ruled list,
   an empty state. The padding belongs to the rows, not to the sheet, or the
   header rule stops short of the corner and the card reads as a table sitting
   inside a box rather than as a sheet of records.

   Modifier rather than a utility: this was written three ways across the console
   (`card !p-0`, `card-shadow style="padding:0"`, and a padded card with the table
   crammed inside), which is exactly the drift a named idiom prevents. */
.card--flush { padding: 0; }

.card__title {
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink);
}

/* A panel INSIDE a card: one claimed award, one signature slot, one repeated
   record in a list of them. No shadow and no tint — it is a division of the
   sheet it sits on, not a second sheet, and stacking two card treatments makes
   the page read as boxes inside boxes.

   Three files had written this as `rounded-lg border border-border p-4` before
   it had a name. */
.subcard {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 1rem;
}

/* A checkbox or radio as a full-width row rather than a 13px dot with a label
   beside it — the console's counterpart to the public form's `.choice`, and the same
   reasoning: the whole row is the target.

   `--border-field` because this IS the control, so its boundary is what
   identifies it (WCAG 1.4.11). */
.check-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 2.75rem;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--border-field);
  border-radius: var(--r-md);
  font-size: 0.875rem;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease;
}
.check-row:hover { border-color: var(--ink-faint); background: var(--surface); }
.check-row input { flex: none; accent-color: var(--brand); width: 1rem; height: 1rem; }
/* Tint AND weight, never the tint alone (WCAG 1.4.1). */
.check-row:has(input:checked) {
  border-color: var(--navy);
  background: var(--brand-tint);
  font-weight: 500;
}
.check-row:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .check-row { transition: none; }
}

/* Inline notice — a standing condition on the page, not a flash.

   `.flash` is the transient stack after a POST and it scrolls out of mind; this
   one stays put and explains why the controls beneath it are disabled ("4 award
   options are unmapped, so approval is blocked"). The icon slot is not
   decoration: the tint alone would leave the state carried by colour
   (WCAG 1.4.1), so every instance pairs it with a title that says the condition
   in words. */
.notice {
  display: flex;
  gap: 0.875rem;
  padding: 1rem 1.125rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--r-lg);
  background: var(--bg);
}
.notice__icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.0625rem;
  color: var(--ink-soft);
}
.notice__title {
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink);
}
.notice__body {
  margin-top: 0.25rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
/* Same three values .flash--warning uses, so the two read as one system. */
.notice--warning {
  background: var(--warning-soft);
  border-color: #F0D5A4;
  border-left-color: var(--warning);
}
.notice--warning .notice__icon { color: var(--warning); }
.notice--warning .notice__title,
.notice--warning .notice__body { color: #6B3F00; }

/* ─── Skip link ─────────────────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  left: 0.75rem;
  top: -3rem;
  z-index: 60;
  background: var(--navy);
  color: #FFFFFF;
  font-size: 0.875rem;
  padding: 0.625rem 1rem;
  border-radius: var(--r-md);
  transition: top 120ms ease;
}
.skip-link:focus { top: 0.75rem; }

/* ─── Console shell (staff_base.html) ───────────────────────────────────── */
.console {
  min-height: 100vh;
  display: grid;
  grid-template-columns: var(--rail-width) 1fr;
  background: var(--surface);
}

.console__rail {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  background: var(--bg);
  border-right: 1px solid var(--border);
  padding: 1.25rem 0.875rem 1rem;
  position: sticky;
  top: 0;
  height: 100vh;
}

.rail__brand {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  column-gap: 0.5625rem;
  padding: 0.25rem 0.5rem 1.25rem;
  text-decoration: none;
  color: inherit;
}
.rail__brand .brandmark__seal {
  grid-row: span 2;
  width: 1.875rem;
  height: 1.875rem;
}
/* The full logo while the rail is open; the icon takes over once it folds. Both are
   drawn, and the link's aria-label is the name in either state. */
.rail__logo { display: block; height: 1.75rem; width: auto; max-width: none; }
.rail__brand--logo .brandmark__seal { display: none; }

.rail__nav { display: flex; flex-direction: column; gap: 0.125rem; }

.rail__link {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5625rem 0.625rem;
  border-radius: var(--r-md);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  transition: background-color 120ms ease, color 120ms ease;
}
.rail__link:hover { background: var(--surface); color: var(--ink); }
/* Weight AND fill, never colour alone (WCAG 1.4.1) — and `aria-current="page"`
   is set on the same element, so assistive tech is told what the tint says. */
.rail__link.is-current {
  background: var(--brand-tint);
  color: var(--brand);
  font-weight: 600;
}
.rail__icon { width: 1.125rem; height: 1.125rem; flex: none; }

.rail__foot {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--divider);
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.rail__user {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.25rem 0.625rem 0.5rem;
}
.rail__avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--r-full);
  background: var(--navy);
  color: #FFFFFF;
  font-family: var(--font-heading);
  font-size: 0.875rem;
  font-weight: 600;
}
.rail__identity {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.rail__role { font-size: 0.6875rem; font-weight: 400; color: var(--ink-faint); }

.rail__signout {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.5625rem 0.625rem;
  border: none;
  border-radius: var(--r-md);
  background: transparent;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
}
.rail__signout:hover { background: var(--surface); color: var(--ink); }

.console__body { min-width: 0; display: flex; flex-direction: column; }

.console__topbar {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 1.5rem 2rem;
}

/* `margin-inline: auto` is load-bearing, not cosmetic. The console grid is
   `var(--rail-width) 1fr`, so the content column takes every pixel left over —
   on a wide display that is far more than 78rem. Without the auto margin the
   column caps its width and then sits hard against the rail, leaving the page
   visibly lopsided with a band of empty surface down the right. Applied here
   rather than per page so `--wide` (and anything else that only changes
   `max-width`) inherits the centring instead of restating it. */
.console__content {
  padding: 1.75rem 2rem 4rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  max-width: 78rem;
  width: 100%;
  margin-inline: auto;
}

/* The form builder is a three-pane document surface rather than a column of
   rows, so it opts out of the reading width the rest of the console keeps. */
.console__content--wide { max-width: 104rem; }

/* Under a laptop the rail lies down above the content. No drawer: this is a
   desktop tool, and a hamburger would add state for seven links. */
@media (max-width: 1023px) {
  .console { grid-template-columns: 1fr; }
  .console__rail {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 0.75rem 1rem;
  }
  .rail__brand { padding: 0; }
  .rail__nav { flex-direction: row; flex-wrap: wrap; }
  .rail__foot {
    margin-top: 0;
    margin-left: auto;
    padding-top: 0;
    border-top: none;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
  }
  .rail__user { padding: 0; }
  .rail__identity { display: none; }
  .console__topbar { padding: 1.25rem 1.25rem; }
  .console__content { padding: 1.25rem 1.25rem 3rem; }
}

/* On a phone the laid-down rail is seven links plus the logo on a 375px line,
   so it wraps to three rows. The links keep their words — dropping to icons
   alone would mean hiding a bare text node, and the ways of doing that which
   survive every screen reader all need markup this doesn't have. Instead the
   rows are tightened.

   Still no drawer: a hamburger is state to open, close and trap focus in, and
   this is a desktop tool that is merely *reachable* from a phone. */
@media (max-width: 639px) {
  .console__rail { gap: 0.5rem; padding: 0.625rem 0.875rem; }
  .rail__nav { gap: 0.125rem 0.25rem; }
  .rail__link { padding: 0.4375rem 0.5rem; gap: 0.4375rem; font-size: 0.8125rem; }
  .rail__link .rail__icon { width: 1rem; height: 1rem; }
  .rail__signout { width: auto; padding: 0.4375rem 0.5rem; font-size: 0.8125rem; }
  .console__topbar { padding: 1rem; }
  .console__content { padding: 1rem 1rem 2.5rem; }
  .flash-stack { padding: 0.875rem 1rem 0; }
}

/* The plain masthead (base.html) — the chrome on every page nobody has an
   identity on yet: sign-in, the SSO dead end, and all five error pages. A rule
   rather than two Tailwind utilities so those pages still look like the app
   before `build-css.sh forms` has ever been run. */
.plain-masthead {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

/* ─── Applicant public form masthead (public_base.html) ─────────────────────────────
   Two lines and no navigation at all. A applicant arrives once a term, from an
   emailed link, with one thing to do — a single-item nav bar would be chrome
   pretending to be structure. What the masthead owes them instead is *which*
   college and *which* form, in the first line they read. */
.public-masthead {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.public-masthead .brandmark__seal { width: 2.125rem; height: 2.125rem; flex: none; }
.public-masthead__text { display: flex; flex-direction: column; min-width: 0; }
.public-masthead__org {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.public-masthead__title {
  font-family: var(--font-heading);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
  line-height: 1.2;
}

/* ─── Page header (inside .console__topbar) ─────────────────────────────────
   ONE shape for every console page, in one place — crumb / title / sub, then the
   page's actions hard right. `staff_base.html` draws it from four blocks so a
   page fills in the slots it has rather than restating the markup; there is no
   second spelling of this anywhere.

   The crumb is the PARENT section and appears only on a child page (a template,
   a batch, a preview). A top-level section page has no crumb — the rail already
   says where you are, and "staff member /" above "Users" is a breadcrumb to a place
   that isn't a page. */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem; }
/* The text column yields; the buttons don't. Without this a long submission
   title pushes the actions off the topbar. */
.page-head > :first-child { min-width: 0; }
.page-head__crumb {
  font-size: 0.75rem;
  color: var(--ink-faint);
}
.page-head__crumb a { color: inherit; text-decoration: none; }
.page-head__crumb a:hover { color: var(--brand); text-decoration: underline; }
.page-head__title {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.page-head__sub { font-size: 0.875rem; color: var(--ink-soft); margin-top: 0.25rem; }
/* Wraps rather than overflows: the builder's head carries six controls. */
.page-head__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; flex: none; }
/* A pill or a version stamp sitting in the sub line reads as a row, not a
   paragraph, so it gets the alignment a row needs. */
.page-head__sub .pill { vertical-align: middle; }

/* Under a tablet the actions stop being a right-hand column and become a row
   under the title — side by side there is no room for either. */
@media (max-width: 767px) {
  .page-head { flex-direction: column; gap: 0.875rem; }
  .page-head__actions { flex: 1 1 auto; }
  .page-head__title { font-size: 1.3125rem; }
}

/* ─── Page sub-navigation ───────────────────────────────────────────────────
   A short strip of links under the page head, for a record with more than one
   view of itself (a submission's Answers / Awards / History).

   Deliberately NOT `.tabs`. Those are the queue's index tabs — filled, cornered
   and sitting ON the sheet's top border, because they change what that one sheet
   shows and carry a count of what is behind each. This changes the page under
   your feet, and page-level navigation that borrowed the louder device would have
   a reader hunting for the sheet it was attached to.

   Current-ness is weight + a navy bar, never colour alone, and it hangs off
   `[aria-current="page"]` — the attribute that tells assistive tech where it is
   is the same one that draws it, so there is no `.is-current` twin to forget. */
.subnav {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 1.5rem;
  border-bottom: 1px solid var(--border);
}

.subnav__link {
  /* No horizontal padding: the bar is then exactly the label's width, which is
     what makes this read as a marked word rather than a chip. */
  padding: 0.4375rem 0.125rem 0.5rem;
  /* -1px so the current bar lands ON the strip's rule instead of above it. */
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
  transition: color 120ms ease, border-color 120ms ease;
}
.subnav__link:hover { color: var(--ink); }
.subnav__link[aria-current="page"] {
  color: var(--ink);
  font-weight: 600;
  border-bottom-color: var(--navy);
}
/* Stated rather than left to the console's global ring: the 2px bar sits in the
   same place the ring would, and offsetting it keeps the two apart. */
.subnav__link:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ─── Stat row ──────────────────────────────────────────────────────────── */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.875rem;
}
.stat {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 0.9375rem 1.125rem 1.0625rem;
}
.stat__label {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.stat__value {
  display: block;
  margin-top: 0.4375rem;
  font-family: var(--font-heading);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.stat__value.is-muted { color: var(--ink-faint); font-weight: 500; }
.stat__note {
  display: block;
  margin-top: 0.1875rem;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

/* ─── Detail grid ───────────────────────────────────────────────────────── */
.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}
@media (min-width: 1180px) {
  .detail-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ─── Danger zone + destructive controls ────────────────────────────────── */
.danger-card {
  background: var(--bg);
  border: 1px solid #EFCBC9;
  border-radius: var(--r-lg);
  padding: 1.5rem;
}
.danger-card__title { color: var(--danger); }

.btn-danger {
  background: var(--danger);
  color: #FFFFFF;
}
.btn-danger:hover { background: #86201C; }
.btn-danger:disabled {
  background: var(--surface-2);
  color: var(--ink-faint);
  cursor: not-allowed;
}

.btn-danger-ghost {
  background: var(--bg);
  color: var(--danger);
  border-color: #EFCBC9;
}
.btn-danger-ghost:hover { background: var(--danger-soft); border-color: var(--danger); }

/* ─── Destructive confirmation ──────────────────────────────────────────────
   Most confirmations here are still `hx-confirm` — the native browser dialog,
   keyboard-reachable and screen-reader announced without anything for us to get
   wrong, and every destructive route re-checks server-side regardless. Use it
   for "delete a batch", "unapprove an award" and anything else that only needs
   a yes.

   ─── The dialog ────────────────────────────────────────────────────────────
   `.modal` is for the one case `hx-confirm` cannot serve: a confirmation that
   has to *collect* something. Today that is exactly one control — approving an
   award by override, which takes a written reason (`queue/_award_override.html`).

   It is the native `<dialog>` element opened with `showModal()`, which is what
   the note that used to sit here asked for and what the removed stub never had:
   focus capture, Escape, inertness of the page behind it and the top layer, all
   from the platform rather than from us. `hx-swap` replaces award rows wholesale
   and a hand-rolled overlay inside one would have to survive that; a dialog in
   the top layer is not clipped by an ancestor's overflow, stacking context or
   transform, so it does.

   Two things the platform does not do, and we do here: lock the page behind it
   (`html:has`), and keep the head and footer still while a long reason scrolls. */
.modal {
  width: min(34rem, calc(100vw - 2rem));
  max-height: min(42rem, calc(100vh - 4rem));
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--bg);
  color: var(--ink);
  box-shadow: var(--shadow-modal);
}
/* Navy rather than neutral black: the page behind it is the console, and the
   backdrop should read as the same material dimmed, not as a grey scrim. */
.modal::backdrop { background: rgba(1, 33, 75, 0.42); }
.modal[open] { display: flex; flex-direction: column; }
html:has(.modal[open]) { overflow: hidden; }

.modal__head {
  padding: 1.125rem 1.25rem 0.9375rem;
  border-bottom: 1px solid var(--divider);
}
.modal__title {
  margin-top: 0.25rem;
  font-family: var(--font-heading);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}
/* The record being acted on, restated inside the dialog. An override is signed
   and permanent, so the thing being overridden is named here rather than left
   behind the backdrop where it cannot be re-read. */
.modal__record {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 0.875rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--sky);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: 0.875rem;
}
/* `min-height: 0` is what lets this shrink and scroll instead of pushing the
   footer off a short viewport — a flex item's default `min-height: auto` refuses
   to go below its content. The same body is reused outside a dialog by the no-JS
   render, where it is an ordinary block and none of this applies. */
.modal__body {
  display: grid;
  gap: 0.875rem;
  min-height: 0;
  padding: 1.125rem 1.25rem;
  overflow-y: auto;
}
.modal__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.875rem 1.25rem 1rem;
  border-top: 1px solid var(--divider);
  background: var(--surface);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

@media (prefers-reduced-motion: no-preference) {
  .modal[open] { animation: modal-rise 160ms cubic-bezier(.2, .7, .2, 1); }
  .modal[open]::backdrop { animation: modal-fade 160ms ease; }
  @keyframes modal-rise {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
  }
  @keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
}

/* Status pills.

   ALWAYS worded. The dot and the tint are the fast signal for someone who has
   seen the screen before; the word is what makes the state survive greyscale, a
   screen reader and colour blindness (WCAG 1.4.1). There is no `.pill` anywhere
   in this app whose meaning is carried by its colour alone, and there must not
   be one. Every combination below clears 4.5:1 against its own tint. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  padding: 0.3125rem 0.625rem;
  border-radius: var(--r-full);
  white-space: nowrap;
}
.pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 9999px;
  background: currentColor;
  opacity: 0.85;
}
.pill-success { color: var(--success); background: var(--success-soft); }
.pill-warning { color: var(--warning-ink); background: var(--warning-soft); }
.pill-danger  { color: var(--danger-ink);  background: var(--danger-soft); }
.pill-neutral { color: var(--ink-soft); background: var(--surface-2); }
.pill-brand   { color: var(--brand); background: var(--brand-tint); }

/* Buttons */
.btn {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 0.875rem;
  line-height: 1;
  padding: 0.625rem 1rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
  cursor: pointer;
  text-decoration: none;
}

.btn-primary {
  background: var(--brand);
  color: var(--on-brand);
}
.btn-primary:hover { background: var(--brand-hover); }

.btn-ghost {
  background: var(--bg);
  color: var(--ink);
  border-color: var(--border);
}
.btn-ghost:hover { background: var(--surface); border-color: var(--border-strong); }

/* The console's `.btn` is 36px tall, which is right for a toolbar a staff member
   drives with a mouse all day and wrong for the one button on a page a applicant
   meets once, on a phone. `.btn-lg` is the applicant flow's primary control —
   Start, Save and continue, Submit — at the 44px minimum target size
   (WCAG 2.5.8) with the type to match. Everything in the public form that a thumb
   has to find uses it. */
.btn-lg {
  font-size: 0.9375rem;
  padding: 0.8125rem 1.375rem;
  min-height: 2.75rem;
}

.btn-link {
  color: var(--brand);
  background: transparent;
  border: none;
  padding: 0.25rem 0;
  cursor: pointer;
  font: inherit;
}
.btn-link:hover { color: var(--brand-hover); text-decoration: underline; }

/* Compact square control for a row's own tools — reorder a form block, remove an
   option. Icon-only by design (three word-buttons per row makes a table
   unreadable), so every instance MUST carry an `aria-label` naming the thing it
   acts on and mark the glyph `aria-hidden`. */
.icon-btn {
  width: 1.5rem; height: 1.5rem; line-height: 1;
  display: grid; place-items: center;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent; color: var(--ink-soft);
  font-size: 0.8125rem; cursor: pointer;
}
.icon-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--ink); }
.icon-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.icon-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.icon-btn--danger:hover:not(:disabled) { background: var(--danger-soft); color: var(--danger); }

/* Form inputs.

   The resting border is `--border-field` and not the `--border` used on cards:
   see the token note. Hover then goes DARKER (to --ink-faint) rather than to
   --border-strong, which is lighter than the resting state and made hover read
   as the control receding. */
.field-input,
.field-select,
.field-textarea {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  background: var(--bg);
  border: 1px solid var(--border-field);
  border-radius: var(--r-md);
  padding: 0.6rem 0.75rem;
  color: var(--ink);
  width: 100%;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.field-input:hover,
.field-select:hover,
.field-textarea:hover { border-color: var(--ink-faint); }
.field-input:focus,
.field-select:focus,
.field-textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-tint);
}

.field-select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23566072' stroke-width='1.5'><path d='M5 8l5 5 5-5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1.1rem;
  padding-right: 2.25rem;
}

/* The hint under a control, and the node its `aria-describedby` points at — so
   the format rule a sighted applicant reads is the one a screen reader announces. */
.field-hint {
  margin-top: 0.3125rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ink-soft);
}
/* Never colour-only: an error message is words, and this only tints them. */
.field-error {
  margin-top: 0.3125rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--danger);
}
.field-input.is-invalid,
.field-select.is-invalid,
.field-textarea.is-invalid { border-color: var(--danger); }

/* Progress bar — batch generation, and a applicant's way through the form's
   sections. */
.progress-track {
  height: 6px;
  background: var(--surface-2);
  border-radius: var(--r-full);
  width: 100%;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: var(--brand);
  border-radius: var(--r-full);
  transition: width 600ms cubic-bezier(.2, .7, .2, 1);
}
.progress-fill--indeterminate {
  width: 40%;
  animation: progress-indeterminate 1.4s ease-in-out infinite;
}
@keyframes progress-indeterminate {
  from { transform: translateX(-100%); }
  to { transform: translateX(250%); }
}
.progress-track--success .progress-fill { background: var(--success); }

/* List rows */
.list-divide > * + * {
  border-top: 1px solid var(--divider);
}

/* ─── Table ─────────────────────────────────────────────────────────────────
   ONE table idiom for the whole console. `.modern-table` is the shared rhythm;
   `.queue-table` (below) is the same table set tighter for 25 rows of scanning.
   Every instance lives in a `.table-scroll` inside a `.card.card--flush`. */
.modern-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}
.modern-table thead th {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: left;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  background: transparent;
}
/* `th` too: every list's first column is a `<th scope="row">` row header, and
   a rule that pads only `td` leaves that cell flush against the table edge. */
.modern-table tbody td,
.modern-table tbody th {
  padding: 1rem;
  border-bottom: 1px solid var(--divider);
  vertical-align: middle;
}
.modern-table tbody tr:hover { background: var(--surface); }
.modern-table tbody tr:last-child td,
.modern-table tbody tr:last-child th { border-bottom: none; }

/* The one link that opens the row's record, in the row's first cell.

   Ink rather than brand, going brand on hover. A work queue is a column of
   twenty-five of these, and setting them all in #005BDE turns the column the
   page exists to scan into the loudest thing on screen. This was written three
   ways (ink→brand, brand+underline, and an inline `style="color:var(--brand)"`)
   before it was one. */
.table-link {
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}
.table-link:hover { color: var(--brand); text-decoration: underline; }

/* The cell that holds a row's own controls, hard right. */
.modern-table td.cell-actions { text-align: right; white-space: nowrap; }

/* ─── Work queue ────────────────────────────────────────────────────────────
   The staff member's working surface: facets, a filter bar, and one ruled sheet of
   submissions.

   Layout note: the toolbar and the results sheet share one <section> with NO gap
   between them, because the tab strip has to sit on the sheet's top edge.
   `.console__content`'s 1.5rem gap would open a seam. */
.queue { display: flex; flex-direction: column; }

.queue-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
}

/* Index tabs on a file jacket, and ONE rule does the whole job: the current
   tab's 2px navy edge lands exactly on the sheet's 1px top border (hence the
   -1px), so the tab reads as attached to the page below it rather than floating
   above it. The 0.75rem inset is --r-lg, the card's corner radius, so the strip
   starts where the sheet's top border stops curving. */
.tabs {
  display: flex;
  align-items: flex-end;
  gap: 0.125rem;
  margin-left: 0.75rem;
  margin-bottom: -1px;
  position: relative;
  z-index: 1;
  min-width: 0;
}

.tab {
  flex: none;
  display: inline-flex;
  align-items: baseline;
  gap: 0.375rem;
  padding: 0.4375rem 0.75rem 0.5rem;
  border-bottom: 2px solid transparent;
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.tab:hover { background: var(--surface-2); color: var(--ink); }
/* White, so the open tab and the sheet under it read as one piece of paper
   against the console's grey. */
.tab.is-current {
  background: var(--bg);
  color: var(--brand);
  font-weight: 600;
  border-bottom-color: var(--navy);
}
.tab:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Mono, because a count is a record — the same signal as .record and .num
   elsewhere in this file. */
.tab__count {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--ink-faint);
}
.tab.is-current .tab__count { color: var(--brand); }

.queue-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  /* Lifted off the sheet's top border; the tabs are the only thing that touches
     it. */
  margin-bottom: 0.4375rem;
}
.queue-filters__field {
  display: flex;
  flex-direction: column;
  gap: 0.1875rem;
  min-width: 0;
}
.queue-filters__field--search { flex: 1 1 12rem; max-width: 18rem; }
.queue-filters__label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
/* Denser than a form page's inputs: this is a toolbar, not a thing to fill in. */
.queue-filters .field-input,
.queue-filters .field-select {
  font-size: 0.8125rem;
  padding: 0.4375rem 0.625rem;
}
.queue-filters .field-select { padding-right: 1.875rem; background-size: 1rem; }

/* The band across the top of the sheet: what you are looking at, and the way out
   of it. aria-live lives on the text so a search announces its own result count;
   the same node is the hx-indicator, which is why the two indicator spans are its
   children. */
.result-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.375rem 1rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--divider);
  font-size: 0.8125rem;
  color: var(--ink-soft);
}
.result-summary__clear { color: var(--brand); font-weight: 500; text-decoration: none; }
.result-summary__clear:hover { text-decoration: underline; }

/* Several columns of record data don't become a card list without losing the
   vertical scan the page exists for, so below the table's own width it scrolls
   sideways instead of breaking. The card around it never grows, so the PAGE
   never scrolls sideways — only this box does.

   Every `.table-scroll` around a table of RECORDS carries `tabindex="0"`,
   `role="region"` and an `aria-label`: its cells are mostly plain text, so
   without its own tab stop a keyboard user is stranded at column four and can
   never see the rest (WCAG 2.1.1). `tabindex` alone would put an unnamed stop in
   the tab order, hence the role and the label.

   The one exception is the public form's grid question (`public/_blocks.html`), whose
   every cell is a radio. Moving between those already scrolls the box, so a tab
   stop there would be a redundant stop in front of every grid. */
/* `position: relative` is not decoration: `.sr-only` (a table `<caption>`, an
   "Actions" column heading) is absolutely positioned, and without a positioned
   ancestor inside the scroller it resolves against the initial containing block
   — so it is laid out at the WIDE table's far edge, escapes `overflow-x` and
   drags the whole document's scroll width out with it. The table stays inside
   its box; a one-pixel clipped span was pulling the page to 1051px at 390px
   wide on the Payments tab and the queue. */
.table-scroll { position: relative; overflow-x: auto; }
.table-scroll:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Below this the columns are unreadable, so the box scrolls instead. Set on the
   table rather than the box: the box must stay free to shrink to the card. */
.queue-table { min-width: 46rem; }
.table-wide  { min-width: 62rem; }
/* Tighter than the shared .modern-table rhythm: a work queue is 25 rows of
   scanning. Both th and td, or the header stops lining up with its column. */
.queue-table thead th { padding: 0.6875rem 0.75rem; }
.queue-table tbody td,
.queue-table tbody th { padding: 0.8125rem 0.75rem; }

/* ─── Pager ─────────────────────────────────────────────────────────────── */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--divider);
}
.pager__link {
  padding: 0.375rem 0.6875rem;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--brand);
  text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.pager__link:hover { background: var(--surface); border-color: var(--border-strong); }
/* Rendered as a <span>, not a disabled link — there is nowhere for it to go, so
   it is not a control and never takes focus. */
.pager__link.is-disabled {
  background: var(--surface);
  border-color: var(--divider);
  color: var(--ink-faint);
}
.pager__link:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
.pager__where { font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-soft); }

/* ─── Empty states ──────────────────────────────────────────────────────────
   An empty screen is an invitation to act, so each one names the next action
   rather than reporting a count of zero. Which one applies is decided in the
   service, never here. */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  padding: 3rem 1.5rem;
  text-align: center;
}
.empty-state__title {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
}
.empty-state__body {
  max-width: 34rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.empty-state .btn { margin-top: 0.875rem; }

@media (max-width: 899px) {
  /* Below this the toolbar stacks, so there is no shared edge for the tabs to
     sit on. They stop pretending to be attached to something two rows away and
     become a plain wrapping underline strip. */
  .queue-toolbar { flex-direction: column; align-items: stretch; margin-bottom: 0.75rem; }
  .tabs { margin-left: 0; margin-bottom: 0; flex-wrap: wrap; }
  .queue-filters { margin-bottom: 0; }
  .queue-filters__field--search { flex-basis: 100%; max-width: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   THE STUDENT PORTAL — the part of it the console can also see
   ════════════════════════════════════════════════════════════════════════════
   The public form's own stylesheet is `templates/public/_public_css.html`, included
   INLINE by `public/_section_form.html` because that partial is also rendered
   standalone into `builder.preview` and into HTMX 422 swaps, where a <head> is
   not guaranteed to be ours.

   What lives HERE instead is the vocabulary the public form's prose pages
   (`home.html`, `confirmation.html`) share with the question sheet. Those two
   pages used to pull in the entire 213-line sheet stylesheet to get five rules
   out of it. Splitting it this way means every rule has exactly one home and no
   page carries CSS for a screen it isn't. */

/* One reading column, for the public form pages that are prose rather than questions.
   `#apply-section` takes the same 44rem in the sheet's own stylesheet: a single
   column of inputs at the shared 64rem shell width is a ~1000px line, and the
   eye loses the next label. Left-aligned, not centred, so the page hangs off the
   same edge as the masthead's seal. */
.public-col { max-width: 44rem; }

/* ─── The flow's type scale ──────────────────────────────────────────────────
   All three applicant pages used to set their h1 with `text-xl` — 1.25rem, which
   is SMALLER than the question sheet's own `.sheet__title` at 1.375rem. So the
   front door and the receipt, the two pages that open and close the whole
   thing, carried the quietest type in the flow. One named step instead, and it
   is the largest thing on the page it sits on.

   Named classes rather than Tailwind utilities on purpose: the same
   `text-sm text-ink-soft mt-3 leading-relaxed` string was written eight times
   across two files, which is a paragraph style with no name and no home. */
/* Deliberately the SMALLER of the two title steps, because on the open page
   this slot holds the form's own title — staff-authored, and in the
   baseline form that is "Application for Degree — Colby Community College,
   Fall 2025 – Summer 2026". Set at display size it is five lines on a phone
   before the applicant has read anything. `.milestone__title` is where the
   display size lives; that copy is the app's own and it is four words. */
.public-title {
  font-family: var(--font-heading);
  font-size: clamp(1.375rem, 1.15rem + 1vw, 1.5rem);
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}
/* The one paragraph directly under a title — set at reading size and in full
   ink, because on the receipt this slot holds the message the staff member wrote
   for the moment (ceremony date, venue) and it is the point of the page. */
.public-lede {
  margin-top: 0.75rem;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
}
.public-body {
  margin-top: 0.875rem;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--ink-soft);
}
.public-lede a,
.public-body a {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ─── The milestone band ─────────────────────────────────────────────────────
   The receipt's head, and the ONLY saturated block anywhere in the applicant
   flow. It exists because "we have your application" and "the form isn't open
   yet" were rendering as the same grey-bordered card, so the end of a two-year
   piece of work looked exactly like an error state.

   Tint ground with a 3px brand rule on top rather than a solid navy slab: this
   is a receipt, not a warning, and the same shape is repeated at the top of the
   confirmation EMAIL so the screen and the inbox are recognisably one message.
   Navy on --brand-tint is 11.9:1. */
.milestone {
  padding: 1.5rem;
  background: var(--brand-tint);
  border-top: 3px solid var(--brand);
  border-radius: var(--r-lg);
}
.milestone__title {
  margin-top: 0.4375rem;
  font-family: var(--font-heading);
  font-size: clamp(1.375rem, 1.05rem + 1.5vw, 1.625rem);
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--navy);
}

/* ─── Payments: the itemised quote ───────────────────────────────────────────
   Inside the milestone band on the pay page, and the one place in the applicant
   flow that is genuinely a table of money. Drawn as a `<dl>` in two columns
   rather than as a real <table>: three rows are not tabular data, and a <table>
   at 320px is a horizontal scrollbar around six words.

   Amounts are mono and tabular so the cents line up under each other — the whole
   point of itemising is that the reader can add the rows up and get the total —
   and the total carries a brand rule above it rather than bold alone, because
   "which number am I about to be charged" must not depend on font weight.

   Passing the card fee to the payer is a surcharge under the card networks'
   rules and those rules require disclosure before payment (plan D-P3), which is
   why the processing row exists at all. */
.quote {
  margin-top: 1.125rem;
  display: flex;
  flex-direction: column;
}
.quote__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4375rem 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--ink);
}
.quote__row dt { min-width: 0; }
.quote__row dd {
  flex: none;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.quote__row--total {
  margin-top: 0.3125rem;
  padding-top: 0.75rem;
  border-top: 2px solid var(--brand);
  font-size: 1.0625rem;
  font-weight: 600;
}
.quote__row--total dt,
.quote__row--total dd { color: var(--navy); }

/* ─── Payments: the staff-side card ──────────────────────────────────────────
   The submission page's payment panel and the refund confirmation inside it.
   Shared with the console, so it lives here rather than in public.css. */
.paycard__amount {
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--ink-heading);
}
.paycard__meta {
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.paycard__links {
  margin-top: 0.625rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  font-size: 0.8125rem;
}
.paycard__links a { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
.paycard__refund { margin-top: 0.875rem; }
.paycard__reason { margin-top: 0.5rem; }
/* A textarea sizes itself from `cols` unless told otherwise, which in a 17rem
   refund panel is 350px of field hanging out of a 272px box. */
.paycard__reason .field-textarea { width: 100%; }

/* ─── The fact strip ─────────────────────────────────────────────────────────
   How long the form is, when it closes, when it was submitted, its reference.
   A `<dl>` in a 12rem/1fr grid was giving a two-word label half the line and
   pushing a timestamp onto its own row on every phone; these are captioned
   values, not definitions, so they read better stacked and set in a row.
   Ruled top and bottom, because a strip of record values is a band across the
   document rather than another box on it. */
.factline {
  margin-top: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.25rem;
  padding: 0.875rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.factline__item { min-width: 0; }
.factline__label {
  display: block;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.factline__value {
  display: block;
  margin-top: 0.1875rem;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* ─── The typed sequence ─────────────────────────────────────────────────────
   Used twice, and only where the content genuinely IS a sequence: what happens
   when the form opens (on the page with nothing to do), and what happens to an
   application after it is filed (on the receipt). Those are the two questions a
   applicant actually arrives with, and both were previously answered — or not —
   inside a paragraph.

   `<ol>` carries the ordering, so the numerals are drawn by a CSS counter and
   never announced twice. Safari drops list semantics from a list with
   `list-style: none`, so every instance carries `role="list"`. */
.steps {
  margin-top: 0.875rem;
  list-style: none;
  counter-reset: step;
}
/* The number sits in a 1.5rem gutter via absolute positioning rather than a
   grid column. A grid blockifies every child — so a `<strong>` followed by a
   bare text run became two grid items, and the text run fell into the 1.5rem
   number column and rendered one word per line (done.html, 2026-09-13). */
.steps > li {
  position: relative;
  padding: 0.8125rem 0 0.8125rem 2.375rem;
  border-top: 1px solid var(--divider);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
.steps > li::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: 0;
  top: 1rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--brand);
}
.steps strong { color: var(--ink); font-weight: 600; }

/* ─── The packet strip ───────────────────────────────────────────────────────
   Which sheet of the application this is. It lives HERE rather than in the
   sheet's own stylesheet because two pages draw it: every section page, and
   `public/home.html` when a applicant is coming back to a draft — where a bar
   showing four of five sections done is the difference between "Continue" and
   "Continue, you are nearly there".

   The count is mono and tabular like every other record in the app. The bar
   itself is the shared `.progress-track`/`.progress-fill` pair. */
.packet { display: flex; flex-direction: column; gap: 0.5rem; }
.packet__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.packet__count {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.packet__of { color: var(--ink-faint); }

/* The notches, and the one place this flow spends any boldness.

   An application is a fixed number of sheets, not a continuous quantity. A
   plain 60% fill answers "how far along" and says nothing about "how much is
   left", which is the question that decides whether somebody finishes the form
   on a phone or closes the tab. Cutting the track at the section boundaries
   answers both at a glance.

   Drawn as ONE pseudo-element over the whole track, so the element carrying
   `role="progressbar"` and its aria values is untouched and none of this is
   announced — a screen reader gets `aria-valuetext` ("Section 3 of 5"), which
   is the same fact in words. `--packet-total` is set inline by whichever page
   draws the strip; it is a bare integer, never JSON. */
.packet .progress-track { height: 8px; position: relative; }
.packet .progress-track::after {
  content: "";
  position: absolute;
  /* 2px past the right edge, so the notch that would land exactly on 100% is
     clipped by the track's own `overflow: hidden` instead of chipping the end
     of the bar. */
  inset: 0 -2px 0 0;
  pointer-events: none;
  --packet-step: calc(100% / var(--packet-total, 1));
  background-image: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(var(--packet-step) - 2px),
    var(--bg) calc(var(--packet-step) - 2px),
    var(--bg) var(--packet-step)
  );
}

/* A record laid out as label/value pairs: the receipt's stamps, the open form's
   length and closing date, and the review panel inside the question sheet. */
.answers {
  margin-top: 0.5rem;
  display: grid;
  gap: 0.375rem 1rem;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  font-size: 0.875rem;
}
.answers dt { color: var(--ink-soft); }
.answers dd { color: var(--ink); overflow-wrap: anywhere; }
/* Following prose rather than a heading, so it needs the paragraph's air. */
.answers--spaced { margin-top: 1.25rem; }

/* What the applicant applied for, on both receipt pages. The award TYPE is the
   thing being claimed and the option is which one, so the type leads in ink and
   the name follows — stacked under 480px, where "Associate of Applied Science"
   and a curriculum name will not share a line at any size worth reading. */
.receipt__list { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem; }
.receipt__award {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.625rem;
  padding: 0.75rem 0.875rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--sky);
  border-radius: var(--r-md);
  font-size: 0.9375rem;
  line-height: 1.4;
}
.receipt__kind { font-weight: 600; }

/* Forward is a filled button and comes FIRST in the DOM so it is the default
   submit for a keyboard; back is a link, because going back is navigation. */
.actions {
  display: flex;
  flex-wrap: wrap-reverse;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 1.5rem;
}
/* Back is a link, but it is still something a thumb has to hit, so it carries
   the same 44px height as everything else in the flow (WCAG 2.5.8). */
.actions__back {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
  text-decoration: none;
}
.actions__back:hover { color: var(--brand); text-decoration: underline; }

/* The last thing before Submit. A warning printed UNDER the button is a warning
   nobody reads, so on the final page the "you cannot edit this afterwards"
   sentence moves above the control it is about and gets a rule of its own. */
.commit {
  margin-top: 1.5rem;
  padding: 0.9375rem 1.125rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--navy);
  border-radius: var(--r-lg);
  background: var(--surface);
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink);
}
.commit strong { color: var(--navy); }

/* On a phone the label/value grid stops being two columns — 12rem of label
   leaves nothing for a date — and the actions go full width. */
@media (max-width: 599px) {
  .answers { grid-template-columns: minmax(0, 1fr); gap: 0 0; }
  .answers dd { margin-bottom: 0.5rem; }
  .actions { align-items: stretch; }
  .actions .btn { justify-content: center; }
  .factline { gap: 0.875rem 1.5rem; }
  .milestone { padding: 1.25rem; }
}
@media (max-width: 479px) {
  /* One award per line rather than a type and a name fighting for 20rem. */
  .receipt__award { flex-direction: column; }
}
/* ════════════════════════ end of the applicant public form ════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .tab, .subnav__link, .pager__link, .progress-fill { transition: none; }
  .progress-fill--indeterminate { width: 100%; animation: none; opacity: 0.55; }
}

/* ─── Alpine ────────────────────────────────────────────────────────────────
   Alpine is loaded `defer`, so any `x-show` block paints once before it boots.
   This is the one rule that keeps that flicker off every page that uses one —
   it was written separately in `builder/shell.html` and in `users/create.html`,
   which meant a third page using x-show would have flickered until somebody
   noticed. It belongs with the script, and the script is global. */
[x-cloak] { display: none !important; }

/* ─── Compact labelled field ────────────────────────────────────────────────
   A denser label/control pair than the `.field-hint` rhythm used on form pages:
   0.75rem label, tight gap, for the tool panels where a dozen of them stack in a
   16rem rail. Named `bld-` for the builder, which is where it was written and
   still its heaviest user (canvas, block editor, group rules) — but `forms/`
   index uses it too, and one shared idiom in one place beat two copies drifting. */
.bld-field { display: grid; gap: 0.25rem; }
.bld-label { font-size: 0.75rem; font-weight: 600; color: var(--ink-soft); }
/* A group of checkboxes is a <fieldset> for the legend's sake, not for the box
   the browser draws round it. */
fieldset.bld-field { border: 0; padding: 0; margin: 0; min-width: 0; }

/* A notice inside a tool pane, which supplies its own edges — so this one keeps
   the pane's gutter instead of sitting flush in it. */
.notice--pane { margin: 0.875rem 0.875rem 0; }

/* ─── Schema problem list ───────────────────────────────────────────────────
   What is wrong with a form definition, one row per problem, each carrying the
   JSON path it came from — the same path the export is edited at.

   This lives here rather than in `builder/shell.html`'s head_extra because it is
   drawn on TWO pages. `_lint_panel.html` and `_publish_gate.html` are inside the
   shell and had the styles; `_import_errors.html` is returned as a 422 and swaps
   into `builder/index.html`, which never loaded them — so a refused import
   rendered as an unstyled bullet list. Same markup, two destinations, therefore
   one stylesheet that both destinations have.

   Level is a WORD ("Blocks publish" / "Warning") in `.bld-issue__tag`, never the
   tint alone. */
.bld-issues { list-style: none; margin: 0; padding: 0; display: grid; }
.bld-issue { padding: 0.625rem 0.875rem; border-top: 1px solid var(--divider); display: grid; gap: 0.1875rem; }
.bld-issues > .bld-issue:first-child { border-top: 0; }
/* Inside a `.danger-card`, which brings its own gutter — the rows only need the
   rule between them. Replaces a `style="padding-left:0;padding-right:0"` that
   was written out on both of the pages that do this. */
.bld-issues--inset { margin-top: 0.75rem; }
.bld-issues--inset .bld-issue { padding-left: 0; padding-right: 0; }
.bld-issue__where { display: flex; align-items: baseline; gap: 0.375rem; flex-wrap: wrap; }
.bld-issue__tag {
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.0625rem 0.375rem;
  border-radius: var(--r-full);
}
/* The -ink variants: at 10px these are smaller than the pill the inks were
   made for, and --warning / --danger on their own tints miss AA (4.41 / 4.47). */
.bld-issue--error .bld-issue__tag { color: var(--danger-ink); background: var(--danger-soft); }
.bld-issue--warning .bld-issue__tag { color: var(--warning-ink); background: var(--warning-soft); }
.bld-issue__msg { font-size: 0.8125rem; color: var(--ink); }
.bld-issue__hint { font-size: 0.75rem; color: var(--ink-soft); }
.bld-issue__path { font-family: var(--font-mono); font-size: 0.6875rem; color: var(--ink-faint); overflow-wrap: anywhere; }
.bld-issue__link { color: var(--brand); text-decoration: none; font-weight: 500; }
.bld-issue__link:hover { text-decoration: underline; }

/* A count of problems, mono because a count is a record. */
.bld-count { font-family: var(--font-mono); font-size: 0.6875rem; }
.bld-count--error { color: var(--danger); }
.bld-count--warning { color: var(--warning); }

/* A quieter link inside a dense tool panel, where a full `.btn` would be the
   loudest thing in a 16rem rail. */
.btn-link--sm { font-size: 0.8125rem; }

/* HTMX request indicator swap.

   Two states in one node pair: the resting label and the in-flight one, with the
   second hidden until htmx puts `htmx-request` on an ANCESTOR. That last word is
   the whole contract — htmx marks the element named by `hx-indicator` (or the
   triggering element itself), so the pair has to live *inside* whatever that
   names, not beside it. Point `hx-indicator` at the wrapper. */
.htmx-indicator-show { display: none; }
.htmx-request .htmx-indicator-hide { display: none; }
.htmx-request .htmx-indicator-show { display: inline; }

/* Flash banner */
/* Centred for the same reason `.console__content` is, and it has to move with
   it: the stack is a SIBLING of <main> in the console column (staff_base.html
   renders it just above), at the same 78rem. Left as-is it would sit hard left
   while the content it belongs to sat centred, so a flash would appear off the
   page's axis — the one moment the layout is asked to look composed. */
.flash-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem 2rem 0;
  max-width: 78rem;
  margin-inline: auto;
  width: 100%;
}
.flash {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.75rem 1rem;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 0.9375rem;
  color: var(--ink);
}
.flash--success { background: var(--success-soft); border-color: #B7DECB; color: #0B4D35; }
.flash--error   { background: var(--danger-soft);  border-color: #EFCBC9; color: #6E1512; }
.flash--warning { background: var(--warning-soft); border-color: #F0D5A4; color: #6B3F00; }

@media (max-width: 1023px) {
  .flash-stack { padding: 1rem 1.25rem 0; }
}

/* Focus rings — WCAG 2.1 AA.
   `summary` is in the list because the public form's review disclosure is one, and a
   control a applicant tabs to on the page before Submit must show where it is. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Staggered entrance for top-level page sections.

   `:not(dialog)` on every rule: a `<dialog>` placed as a direct child of a
   `.stagger` container is display:none at load, so `rise` (whose `forwards`
   fill parks the other children at opacity 1) never runs on it — the static
   `opacity: 0` becomes its resting state, and `.modal[open]`'s own fill-less
   animation ends by snapping the open dialog invisible. That bit EarlyAlert's
   roster on 2026-08-18 (modal flashed and vanished, but only for users with
   reduced motion off); the exclusion here keeps the copied pattern safe. */
@media (prefers-reduced-motion: no-preference) {
  .stagger > :not(dialog) {
    opacity: 0;
    animation: rise 420ms cubic-bezier(.2, .7, .2, 1) forwards;
  }
  .stagger > :not(dialog):nth-child(1) { animation-delay:   0ms; }
  .stagger > :not(dialog):nth-child(2) { animation-delay:  60ms; }
  .stagger > :not(dialog):nth-child(3) { animation-delay: 120ms; }
  .stagger > :not(dialog):nth-child(4) { animation-delay: 180ms; }
  .stagger > :not(dialog):nth-child(5) { animation-delay: 240ms; }
  .stagger > :not(dialog):nth-child(6) { animation-delay: 300ms; }
  @keyframes rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
  }
}

::selection { background: var(--brand-tint); color: var(--brand-hover); }

/* ════════════════════════════════════════════════════════════════════════════
   ADMIN SECTIONS + DASHBOARD (Phase 2A)

   Three ledgers (years, departments, accounts) and one summary. The ledgers
   deliberately reuse the existing vocabulary wholesale — `.card--flush`,
   `.modern-table`, `.pill`, `.empty-state`, `.notice` — because they ARE the
   same page three times and any per-section styling here would be three ways to
   draw one thing. What is new below is only what none of those could say.
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── Rail group label ──────────────────────────────────────────────────────
   The divider between "the work" and "the scaffolding" in the console rail.
   A label rather than a horizontal rule, because the two groups are different
   kinds of task rather than two halves of one list — and a word survives being
   read out by a screen reader, which a border does not. */
.rail__group {
  margin: 1.125rem 0 0.375rem;
  padding: 0 0.75rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ─── The academic-year band (dashboard) ────────────────────────────────────
   Not a card in the grid below it: the current year is the frame everything
   else on the page sits inside, and giving it the same rounded-white treatment
   as the department cards would make it one item among several.

   The navy left rule is the whole device. It is the same idea as
   `.modal__record` — "this is the record we are working inside" — and it is the
   only place on the dashboard that spends any weight. */
.year-band {
  border: 1px solid var(--border);
  border-left: 4px solid var(--navy);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  padding: 1.125rem 1.25rem;
}
.year-band__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.year-band__name {
  font-family: var(--font-heading);
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-heading);
}
.year-band__dates {
  margin-top: 0.25rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
}
.year-band__progress { margin-top: 1rem; }
.year-band__note {
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

/* ─── Department summary cards (dashboard) ──────────────────────────────────
   `auto-fill` rather than a fixed column count: a college with three offices
   and one with eleven both get full rows, and neither gets a stretched card.

   `.is-busy` is a LEFT RULE, not a tint. The card already says what it is
   waiting on in words directly underneath; the rule is only there so a busy
   department can be picked out of eleven at a glance, and it has to be
   ignorable in greyscale (WCAG 1.4.1). */
.dept-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 0.875rem;
}
.dept-card {
  border: 1px solid var(--border);
  border-left: 3px solid transparent;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  padding: 1rem 1.125rem;
}
.dept-card.is-busy { border-left-color: var(--accent); }
.dept-card__head { display: flex; flex-direction: column; gap: 0.125rem; }
.dept-card__name {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-heading);
}
.dept-card__open { font-size: 0.8125rem; color: var(--ink-soft); }
/* The resting state, and it is a full sentence rather than a row of zeros. A
   dashboard that renders three noughts as prominently as three fives is a
   dashboard people stop reading. */
.dept-card__quiet {
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

/* The things to act on this week. One line each, and a line only exists when
   its count is non-zero. */
.attention {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--divider);
  list-style: none;
  display: grid;
  gap: 0.375rem;
}
.attention__item {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.8125rem;
  color: var(--ink);
}
.attention__count {
  flex: none;
  min-width: 1.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-heading);
}

/* A heading over a group of cards that is not inside one. */
.section-heading {
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-heading);
  margin-bottom: 0.75rem;
}

/* ─── Ledger row detail ─────────────────────────────────────────────────────
   A second line under a table cell's main value — an email under a name, the
   departments an administrator is mailed for. Block, so it wraps under rather
   than stretching the column. */
.row-sub {
  display: block;
  margin-top: 0.125rem;
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--ink-faint);
}
/* Names of offices, several to a cell; they wrap rather than widening a column
   that is already competing with seven others. */
.cell-departments { max-width: 16rem; }

/* The current academic year's row. Third signal, after the word in the status
   column and the pill's tint. */
.modern-table tbody tr.is-current-row td,
.modern-table tbody tr.is-current-row th { background: var(--brand-tint); }
.modern-table tbody tr.is-current-row th[scope="row"] { box-shadow: inset 3px 0 0 var(--brand); }

/* ─── Admin forms ───────────────────────────────────────────────────────────
   The same markup renders inside a <dialog> and on a page of its own (see
   `blueprints/_admin.render_form`), so the form itself carries no width, no
   background and no border — its wrapper supplies all three. That is what keeps
   the two renders from drifting into two designs. */
.admin-form { display: contents; }
/* `display: contents` collapses the <form> box so `.modal__head/body/foot`
   become children of the dialog's own flex column — which is what lets a long
   body scroll while the head and footer stay still. Inside a `.card--flush`
   there is no flex column to join and the three blocks simply stack. */

/* The second line of a checkbox or radio row — what the option MEANS, under
   what it is called. `.field-hint` is styled for a <p> under a control, and an
   inline <span> would keep it on the label's own line and drop its margin
   entirely (inline boxes ignore vertical margins). */
.check-row .field-hint { display: block; margin-top: 0.125rem; }

/* Two dates side by side; one column on a phone, where 12rem each is unusable. */
.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.875rem; }
@media (max-width: 559px) {
  .field-pair { grid-template-columns: 1fr; }
}

/* A column of `.check-row`s inside a fieldset. Scrolls rather than pushing the
   footer off a short viewport once a college has fifteen departments. */
.check-list {
  display: grid;
  gap: 0.375rem;
  max-height: 15rem;
  overflow-y: auto;
}

/* The account form carries two more sections than the others, so its dialog is
   allowed to be wider — 34rem of role radios and department checkboxes reads as
   a column of fragments. */
.modal--wide { width: min(40rem, calc(100vw - 2rem)); }

/* ─── Department members ────────────────────────────────────────────────────
   The add control is a select and a button on one line, because it is one
   action and splitting it across two rows makes it look like a form to fill in
   rather than a thing to do. */
.member-add {
  display: flex;
  align-items: flex-end;
  gap: 0.625rem;
  flex-wrap: wrap;
  margin-top: 0.875rem;
}
.member-add__field { flex: 1 1 16rem; min-width: 0; }

/* A plain vertical rhythm for a page of sections that are not `.stagger`
   children — the members partial is one swapped node containing several. */
.stack { display: flex; flex-direction: column; gap: 1.25rem; }

/* ════════════════════════════════════════════════════════════════════════════
   ─── Builder ─── (Phase 3A: the forms list's builder, and its four sibling tabs)

   The Questions tab is a three-pane document surface rather than a column of
   cards, so it gets its own grid and its own card idiom. Everything else on the
   five tabs reuses the console vocabulary already above — `.card`, `.tabs`,
   `.check-row`, `.notice`, `.danger-card`, `.empty-state`, `.modal` — and only
   what none of those could say is written here.

   The signature device is the ID STAMP (`.bld-id`). A block's id is the join key
   between a stored answer and the schema, and a document requirement's id is the
   join key for an uploaded file; both must never change. They are therefore
   stamped in mono everywhere they appear and are an input nowhere. That is where
   this surface spends its one piece of emphasis; everything around it is
   deliberately quiet so the stamp reads as the record it is.

   Panes sit on `--bg` inside white console chrome — the reverse of the admin
   ledgers, which are white cards on the tinted board. That inversion is the
   signal that this page is a workbench rather than a report.

   `.bld-field` / `.bld-label` / `.bld-issue*` / `.bld-count*` are NOT here: they
   are further up, because the forms list and the import-error panel use them too.
   ════════════════════════════════════════════════════════════════════════════ */

.bld {
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr) 23rem;
  gap: 1rem;
  align-items: start;
}
/* One column below a laptop: three panes at 320px is three unusable panes, and
   the order below is the order the work happens in. */
@media (max-width: 1279px) { .bld { grid-template-columns: minmax(0, 1fr); } }

.bld__pane {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  min-width: 0;
}
@media (min-width: 1280px) {
  .bld__rail {
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .bld__right { position: sticky; top: 1rem; }
}
.bld__right { display: grid; gap: 1rem; align-content: start; }

.bld__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.6875rem 0.875rem;
  border-bottom: 1px solid var(--divider);
}
.bld__eyebrow {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.bld__body { padding: 0.625rem; display: grid; gap: 0.375rem; }
.bld__empty { padding: 1.25rem 0.875rem; font-size: 0.8125rem; color: var(--ink-soft); }

/* The id stamp — see the note at the top of this block. */
.bld-id {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.35;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r-full);
  padding: 0.0625rem 0.4375rem;
  white-space: nowrap;
}

.bld-glyph {
  flex: none;
  width: 1.625rem;
  height: 1.625rem;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: 0.8125rem;
}

/* ─── Section rail ─────────────────────────────────────────────────────── */
.bld-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.125rem; }
.bld-section {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  gap: 0.5rem;
  padding: 0.4375rem 0.5rem;
  border-radius: var(--r-md);
  border: 1px solid transparent;
}
.bld-section:hover { background: var(--surface); }
/* Tint AND weight AND the marker column, never colour alone (WCAG 1.4.1); the
   same element carries aria-current. */
.bld-section[aria-current] { background: var(--brand-tint); border-color: #CCE2F4; }
.bld-section[aria-current] .bld-section__name { color: var(--brand); font-weight: 600; }
.bld-section.is-drop { border-color: var(--brand); border-style: dashed; }
.bld-section__no {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--ink-faint);
  padding-top: 0.1875rem;
}
.bld-section__name {
  display: block;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.bld-section__name.is-untitled { color: var(--ink-faint); font-style: italic; }
.bld-section__meta {
  font-size: 0.6875rem;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.bld-tools { display: flex; align-items: center; gap: 0.125rem; margin-top: 0.1875rem; }
.bld-tools form { display: inline-flex; }
.bld-grip { cursor: grab; color: var(--ink-faint); font-size: 0.75rem; padding: 0 0.125rem; }

/* ─── Canvas ───────────────────────────────────────────────────────────── */
.bld-canvas__head {
  padding: 1rem 1.125rem;
  border-bottom: 1px solid var(--divider);
  display: grid;
  gap: 0.625rem;
}
.bld-canvas__row {
  display: grid;
  gap: 0.625rem;
  grid-template-columns: minmax(0, 1fr) 12rem;
  align-items: end;
}
@media (max-width: 720px) { .bld-canvas__row { grid-template-columns: minmax(0, 1fr); } }
.bld-canvas__blocks { padding: 0.875rem 1.125rem 1.125rem; display: grid; gap: 0.5rem; }

.bld-card {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg);
  padding: 0.6875rem 0.75rem;
  display: grid;
  gap: 0.375rem;
}
.bld-card:hover { border-color: var(--border-strong); }
.bld-card.is-selected { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }
/* Content blocks are paper-white against the questions' tinted ground: an author
   scanning a section needs to see at a glance which rows will collect an answer
   and which are only prose. */
.bld-card.is-content { background: var(--surface); }
.bld-card__top { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.bld-card__type { font-size: 0.75rem; font-weight: 500; color: var(--ink-soft); }
.bld-card__pick {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 0.9375rem;
  color: var(--ink);
  cursor: pointer;
  overflow-wrap: anywhere;
}
.bld-card__pick:hover { color: var(--brand); }
.bld-card__sub { display: flex; flex-wrap: wrap; gap: 0.5rem; font-size: 0.75rem; color: var(--ink-faint); }
.bld-req { color: var(--danger); font-weight: 600; }
.bld-spacer { flex: 1 1 auto; }

/* ─── Palette ──────────────────────────────────────────────────────────── */
.bld-palette { position: relative; }
.bld-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 0.375rem);
  z-index: 20;
  width: 16rem;
  max-height: 24rem;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-modal);
  padding: 0.375rem;
}
.bld-menu__group { padding: 0.5rem 0.5rem 0.25rem; }
.bld-menu__item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.5rem;
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.bld-menu__item:hover { background: var(--brand-tint); color: var(--brand); }
/* Offered, refused, and explained on the same line — a type that is simply
   missing reads as an app that cannot do it. The reason is words, not a tint. */
.bld-menu__item.is-disabled,
.bld-menu__item:disabled { color: var(--ink-faint); cursor: not-allowed; }
.bld-menu__item:disabled:hover { background: none; color: var(--ink-faint); }
.bld-menu__item .bld-sub { display: block; }

/* ─── Editor ───────────────────────────────────────────────────────────── */
.bld-check { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; color: var(--ink); }
.bld-options { display: grid; gap: 0.25rem; }
.bld-option {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) auto;
  gap: 0.25rem;
  align-items: center;
}
/* A grid ROW has one visible input — its id travels hidden — so it gets the
   whole width rather than leaving a phantom column. */
.bld-option--single { grid-template-columns: minmax(0, 1fr) auto; }
/* A table COLUMN is a heading, a kind, a required flag and its tools on one
   line, with the dropdown's choices (shown only for that kind) on a second. */
.bld-option--stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.25rem; }
.bld-option--stack > .bld-option { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 0.9fr) auto; }
.bld-option .field-select { font-size: 0.8125rem; padding: 0.375rem 1.75rem 0.375rem 0.5rem; }
.bld-option .field-input { font-size: 0.8125rem; padding: 0.375rem 0.5rem; }
.bld-rule-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 0.875rem;
  display: grid;
  gap: 0.625rem;
}
.bld-editor__form { padding: 0.875rem; display: grid; gap: 0.75rem; }
.bld-editor__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-top: 0.25rem;
}
.bld-editor__aside { margin-top: 0.75rem; }
.bld-sub { font-size: 0.75rem; color: var(--ink-faint); }
fieldset.bld-field { border: 0; padding: 0; margin: 0; min-width: 0; }
.bld-field > legend.bld-label { padding: 0; }

/* ─── The four single-column tabs ──────────────────────────────────────────
   Settings, Documents, Rubric, Schedule and Share are sheets ABOUT the form rather than
   part of it, so they are one reading column of cards — the console's ordinary
   idiom — and not the workbench above. That difference is the information: a
   glance says whether you are editing the questions or the folder they sit in. */
.bld-sheet { display: flex; flex-direction: column; gap: 1.25rem; max-width: 52rem; }
.bld-sheet .card { display: flex; flex-direction: column; gap: 0.875rem; }
.bld-sheet form { display: flex; flex-direction: column; gap: 0.875rem; }
.bld-sheet .field-pair { display: grid; }


/* ─── The Documents tab: a checklist of rows that open in place ────────────
   Wider than the other sheets (the modifier keeps Settings, PrintOut, Schedule
   and Share at 52rem): a closed row is one line of facts, an open row splits
   into the words (left) and the settings (right). Every rule is scoped under
   `.bld-sheet--wide` so it outranks `.bld-sheet form`, which would otherwise
   turn the quick-add line and the move-arrow forms into columns. */
.bld-sheet--wide { max-width: 70rem; gap: 1rem; }
.bld-sheet--wide .docs-top { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 0.625rem 1.5rem; }
.bld-sheet--wide .docs-top__text { min-width: 0; flex: 1 1 24rem; }
.bld-sheet--wide .docs-top__title { font-size: 1.125rem; font-weight: 600; }
.bld-sheet--wide .docs-top__lede { margin-top: 0.1875rem; font-size: 0.875rem; color: var(--ink-soft); }
.bld-sheet--wide .docs-checks-ok {
  display: inline-flex; align-items: center; gap: 0.375rem; flex: none;
  padding: 0.25rem 0.75rem; border-radius: var(--r-full);
  background: var(--success-soft); color: var(--success);
  font-size: 0.8125rem; font-weight: 600;
}
.bld-sheet--wide .docs-checks-ok svg { width: 0.875rem; height: 0.875rem; }
/* Something to fix: the full checks list drops under the title, full width. */
.bld-sheet--wide .docs-checks { flex: 1 1 100%; }

.bld-sheet--wide .docs { display: flex; flex-direction: column; gap: 1rem; }
.bld-sheet--wide .docs-facts {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.375rem 1.125rem;
  padding: 0.625rem 0.875rem; border-radius: var(--r-md); background: var(--bg);
  font-size: 0.8125rem; color: var(--ink-soft);
}
.bld-sheet--wide .docs-facts b { color: var(--ink-heading); font-weight: 600; font-variant-numeric: tabular-nums; }
.bld-sheet--wide .docs-facts__how { margin-left: auto; }
.bld-sheet--wide .docs-facts__how summary { cursor: pointer; color: var(--brand); font-weight: 500; }
.bld-sheet--wide .docs-facts__how[open] { flex-basis: 100%; margin-left: 0; }
.bld-sheet--wide .docs-facts__how ul { margin: 0.5rem 0 0.125rem; padding-left: 1.125rem; display: grid; gap: 0.25rem; list-style: disc; color: var(--ink); max-width: 75ch; }

.bld-sheet--wide .docs-list { border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface); overflow: hidden; }
.bld-sheet--wide .docs-empty { padding: 1.25rem 1rem 1rem; }
.bld-sheet--wide .docs-empty__title { font-family: var(--font-heading); font-weight: 600; color: var(--ink-heading); }
.bld-sheet--wide .docs-empty__body { margin-top: 0.25rem; font-size: 0.875rem; color: var(--ink-soft); max-width: 65ch; }

.bld-sheet--wide .docs-row { border-top: 1px solid var(--divider); }
.bld-sheet--wide .docs-row:first-child { border-top: 0; }
.bld-sheet--wide .docs-row.is-open { box-shadow: inset 3px 0 0 var(--brand); }
.bld-sheet--wide .docs-sum {
  display: grid; grid-template-columns: 2.2rem minmax(0, 1fr) auto; gap: 0.875rem; align-items: start;
  padding: 0.875rem 1rem 0.875rem 0.875rem; cursor: pointer;
}
.bld-sheet--wide .docs-row:not(.is-open) .docs-sum:hover { background: var(--bg); }
.bld-sheet--wide .docs-row.is-open .docs-sum { padding-bottom: 0.375rem; cursor: default; }
.bld-sheet--wide .docs-num {
  display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--brand-tint); color: var(--navy);
  font-family: var(--font-heading); font-size: 0.875rem; font-weight: 600; font-variant-numeric: tabular-nums;
}
.bld-sheet--wide .docs-sum__main { min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.bld-sheet--wide .docs-sum__title { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem 0.625rem; }
.bld-sheet--wide .docs-sum__title h3 { font-family: var(--font-sans); font-size: 0.9375rem; font-weight: 600; color: var(--ink-heading); overflow-wrap: anywhere; }
.bld-sheet--wide .docs-excerpt {
  max-width: 90ch; font-size: 0.8125rem; color: var(--ink-soft);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.bld-sheet--wide .docs-excerpt.is-empty { font-style: italic; color: var(--ink-faint); }
.bld-sheet--wide .docs-row.is-open .docs-excerpt { display: none; }

.bld-sheet--wide .docs-chip {
  display: inline-flex; align-items: center; gap: 0.3125rem; white-space: nowrap;
  padding: 0.0625rem 0.5rem; border: 1px solid var(--border); border-radius: var(--r-full);
  background: var(--surface); color: var(--ink-soft); font-size: 0.6875rem; font-weight: 500; line-height: 1.5;
}
.bld-sheet--wide .docs-chip svg { width: 0.75rem; height: 0.75rem; }
.bld-sheet--wide .docs-chip--required { background: var(--navy); border-color: var(--navy); color: var(--on-brand); }
.bld-sheet--wide .docs-chip--optional { border-style: dashed; border-color: var(--border-field); }
.bld-sheet--wide .docs-chip--esign { background: var(--success-soft); border-color: transparent; color: var(--success); }

.bld-sheet--wide .docs-tools { display: flex; flex-direction: row; align-items: center; gap: 0.125rem; }
.bld-sheet--wide .docs-tools form { display: inline-flex; flex-direction: row; gap: 0; }
.bld-sheet--wide .docs-tools svg { width: 0.9375rem; height: 0.9375rem; }
.bld-sheet--wide .docs-edit { margin-left: 0.375rem; }
.bld-sheet--wide .btn-sm { padding: 0.3125rem 0.6875rem; font-size: 0.8125rem; gap: 0.375rem; }
.bld-sheet--wide .docs-edit svg { width: 0.8125rem; height: 0.8125rem; }

/* The open row's editor: words | settings, with the actions under both. */
.bld-sheet--wide .docs-ed {
  margin: 0 1rem 1rem calc(0.875rem + 2.2rem + 0.875rem);
  border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden;
}
.bld-sheet--wide .docs-ed__form { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(16rem, 1fr); gap: 0; }
.bld-sheet--wide .docs-ed__words { padding: 1rem; display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.bld-sheet--wide .docs-ed__words .field-textarea { resize: vertical; line-height: 1.55; }
.bld-sheet--wide .docs-ed__settings {
  padding: 1rem; display: flex; flex-direction: column; gap: 1rem; min-width: 0;
  background: var(--bg); border-left: 1px solid var(--border);
}
.bld-sheet--wide .docs-ed__foot {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  padding: 0.625rem 1rem; border-top: 1px solid var(--border); background: var(--surface);
}
.bld-sheet--wide .docs-remove { color: var(--danger-ink); font-size: 0.8125rem; }
.bld-sheet--wide .docs-remove:hover { color: var(--danger-ink); }
.bld-sheet--wide .docs-confirm {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem;
  padding: 0.625rem 1rem; background: var(--danger-soft); color: var(--danger-ink); font-size: 0.875rem;
}
.bld-sheet--wide .docs-confirm p { flex: 1 1 18rem; }
.bld-sheet--wide .docs-confirm form { display: inline-flex; flex-direction: row; }

.bld-sheet--wide .docs-source { display: flex; flex-direction: column; gap: 0.375rem; }
.bld-sheet--wide .docs-radio { display: flex; align-items: flex-start; gap: 0.5625rem; font-size: 0.875rem; color: var(--ink); cursor: pointer; }
.bld-sheet--wide .docs-radio input { margin: 0.1875rem 0 0; accent-color: var(--brand); flex: none; }
.bld-sheet--wide .docs-radio small { display: block; line-height: 1.4; }
.bld-sheet--wide .docs-agreement { display: grid; gap: 0.625rem; }
.bld-sheet--wide .docs-agreement .answers { grid-template-columns: auto minmax(0, 1fr); column-gap: 1rem; }
.bld-sheet--wide .docs-agreement .btn-link { justify-self: start; }

/* The applicant-facing switches of an e-sign agreement and their preview
   (2026-10-26, rendition "Forms multi-signer agreements"). */
.bld-sheet--wide .docs-chip--signers { background: var(--navy); border-color: var(--navy); color: var(--on-brand); }
/* The template, the folder and the three switches in one box, as the
   rendition draws them; the preview sits under the box. */
.bld-sheet--wide .docs-agreement-box {
  display: grid; gap: 0; padding: 0.875rem 1rem;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
}
.bld-sheet--wide .docs-switches {
  display: grid; gap: 0.75rem; margin-top: 0.875rem; padding-top: 0.875rem;
  border-top: 1px solid var(--divider);
}
.bld-sheet--wide .docs-preview { display: grid; gap: 0.5rem; margin-top: 1rem; }
.bld-sheet--wide .docs-preview__label { font-size: 0.8125rem; font-weight: 600; color: var(--ink-heading); }
.bld-sheet--wide .docs-preview__frame {
  padding: 0.75rem; border: 1px dashed var(--border-strong); border-radius: var(--r-lg); background: var(--bg);
}
.bld-sheet--wide .docs-preview__card {
  display: grid; gap: 0.625rem; padding: 0.75rem; border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--surface); font-size: 0.8125rem;
}
.bld-sheet--wide .docs-preview__head { display: flex; justify-content: space-between; align-items: center; gap: 0.625rem; }
.bld-sheet--wide .docs-preview__title {
  min-width: 0; font-family: var(--font-heading); font-size: 0.875rem; font-weight: 600;
  color: var(--navy); overflow-wrap: anywhere;
}
.bld-sheet--wide .docs-preview__pill {
  flex: none; padding: 0.0625rem 0.5rem; border-radius: var(--r-full); background: var(--brand-tint);
  color: var(--navy); font-size: 0.6875rem; font-weight: 600; line-height: 1.5; white-space: nowrap;
}
.bld-sheet--wide .docs-preview__pill--done { background: var(--success-soft); color: var(--success); }
.bld-sheet--wide .docs-preview__pill--progress { background: var(--warning-soft); color: var(--warning-ink); }
.bld-sheet--wide .docs-preview__multi { display: grid; gap: 0.5rem; }
.bld-sheet--wide .docs-preview__list { border: 1px solid var(--divider); border-radius: var(--r-md); }
.bld-sheet--wide .docs-preview__row {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 0.625rem;
  padding: 0.5rem 0.625rem; border-bottom: 1px solid var(--divider);
}
.bld-sheet--wide .docs-preview__row:last-child { border-bottom: 0; }
.bld-sheet--wide .docs-preview__who { display: grid; min-width: 0; }
.bld-sheet--wide .docs-preview__name { font-weight: 600; color: var(--navy); }
.bld-sheet--wide .docs-preview__sub { color: var(--ink-soft); }
.bld-sheet--wide .docs-preview__tag { justify-self: start; padding: 0 0.375rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--navy); font-size: 0.75rem; line-height: 1.125rem; }
.bld-sheet--wide .docs-switch-nest { margin-left: 3.25rem; padding-left: 0.875rem; border-left: 2px solid var(--brand-tint); }
.bld-sheet--wide .docs-preview__dl { font-weight: 600; color: var(--brand); }
.bld-sheet--wide .docs-preview__add { font-weight: 600; color: var(--brand); }
.bld-sheet--wide .docs-preview__single { display: grid; gap: 0.375rem; }

/* "More than one file" on an upload document (2026-10-29, rendition "Forms
   multi-file documents", board "Staff · Documents tab"): the switch and the
   largest-file choice share a box, like the agreement's, and the preview under
   it draws the applicant's card. */
.bld-sheet--wide .docs-chip--files { background: var(--navy); border-color: var(--navy); color: var(--on-brand); }
.bld-sheet--wide .docs-upload-box {
  display: grid; gap: 0.875rem; padding: 0.875rem 1rem;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
}
.bld-sheet--wide .docs-upload-box .bld-field { margin: 0; padding-top: 0.875rem; border-top: 1px solid var(--divider); }
.bld-sheet--wide .docs-preview__file {
  display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.625rem;
  border-bottom: 1px solid var(--divider);
}
.bld-sheet--wide .docs-preview__file:last-child { border-bottom: 0; }
.bld-sheet--wide .docs-preview__pdf {
  flex: none; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 6px;
  background: var(--danger-soft); color: var(--danger-ink); font-size: 9px; font-weight: 700;
}
.bld-sheet--wide .docs-preview__fname { display: grid; flex: 1 1 auto; min-width: 0; }
.bld-sheet--wide .docs-preview__fname b {
  font-weight: 600; color: var(--navy); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bld-sheet--wide .docs-preview__remove { flex: none; font-weight: 600; color: var(--brand); }
.bld-sheet--wide .docs-preview__finish {
  display: block; padding: 0.5rem; border-radius: 8px; background: var(--brand);
  color: var(--on-brand); font-weight: 600; text-align: center;
}

/* Sizes as one segmented row of radios. */
.bld-sheet--wide .docs-seg {
  display: inline-flex; flex-wrap: wrap; justify-self: start; align-self: flex-start; gap: 2px; padding: 2px;
  border: 1px solid var(--border-field); border-radius: var(--r-md); background: var(--surface);
}
.bld-sheet--wide .docs-seg label { position: relative; }
.bld-sheet--wide .docs-seg input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.bld-sheet--wide .docs-seg span { display: block; padding: 0.3125rem 0.75rem; border-radius: 6px; font-size: 0.8125rem; font-weight: 500; color: var(--ink-soft); }
.bld-sheet--wide .docs-seg input:checked + span { background: var(--navy); color: var(--on-brand); }
.bld-sheet--wide .docs-seg input:focus-visible + span { outline: 2px solid var(--brand); outline-offset: 1px; }
.bld-sheet--wide .docs-ed__settings .switch__label .field-hint { display: block; }
.bld-sheet--wide .docs-stamp { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.3125rem; font-size: 0.75rem; color: var(--ink-soft); }
.bld-sheet--wide .docs-stamp svg { width: 0.6875rem; height: 0.6875rem; }

/* Quick add: the list's last row. */
.bld-sheet--wide .docs-add {
  display: grid; grid-template-columns: 2.2rem minmax(0, 1fr) auto; align-items: center; gap: 0.875rem;
  padding: 0.875rem 1rem 0.875rem 0.875rem; border-top: 1px dashed var(--border-field); background: var(--bg);
}
.bld-sheet--wide .docs-list > .docs-add:first-child { border-top: 0; }
.bld-sheet--wide .docs-num--add { background: transparent; border: 1.5px dashed var(--border-field); color: var(--ink-soft); }
.bld-sheet--wide .docs-num--add svg { width: 0.875rem; height: 0.875rem; }

@media (max-width: 1023px) {
  .bld-sheet--wide .docs-ed { margin-left: 0.875rem; }
  .bld-sheet--wide .docs-ed__form { grid-template-columns: minmax(0, 1fr); }
  .bld-sheet--wide .docs-ed__settings { border-left: 0; border-top: 1px solid var(--border); }
}
@media (max-width: 639px) {
  .bld-sheet--wide .docs-sum { grid-template-columns: minmax(0, 1fr) auto; gap: 0.5rem 0.625rem; padding: 0.75rem 0.625rem 0.75rem 0.75rem; }
  .bld-sheet--wide .docs-sum > .docs-num { display: none; }
  .bld-sheet--wide .docs-ed { margin: 0 0.625rem 0.75rem; }
  .bld-sheet--wide .docs-facts__how { margin-left: 0; }
  .bld-sheet--wide .docs-add { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; padding: 0.75rem; }
  .bld-sheet--wide .docs-add > .docs-num { display: none; }
  .bld-sheet--wide .docs-add .btn { justify-self: start; }
}

/* ─── The Checklist tab: the Documents tab's rows, plus links and PDFs ──────
   Everything a closed row and the editor frame need is the `.docs-*` set above
   (same sheet, same chips, same quick add). What is new is inside the open
   editor: link rows, the item's PDFs with their replace/remove tools and the
   drop zone, and the side note. The editor is a grid of plain columns rather
   than a form (`.docs-ed__form`) because the PDF forms sit between the saved
   controls; those point at the hidden save form with `form=`. */
.bld-sheet--wide .ckl-save { display: none; }
.bld-sheet--wide .ckl-ed { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(16rem, 1fr); }
.bld-sheet--wide .ckl-opt { font-weight: 400; color: var(--ink-soft); }
.bld-sheet--wide .ckl-flash { margin: 0; font-size: 0.875rem; align-items: center; }
.bld-sheet--wide .ckl-flash svg { width: 1rem; height: 1rem; flex: none; }
.bld-sheet--wide .ckl-how { flex-basis: 100%; margin-top: 0.5rem; display: grid; gap: 0.5rem; max-width: 75ch; color: var(--ink); font-size: 0.875rem; }
.bld-sheet--wide .ckl-how b { color: var(--ink); }
.bld-sheet--wide .ckl-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: 0.5rem; }
.bld-sheet--wide .ckl-fieldset > legend { padding: 0; margin-bottom: 0.375rem; }
.bld-sheet--wide .ckl-links,
.bld-sheet--wide .ckl-files { display: grid; gap: 0.5rem; min-width: 0; }
.bld-sheet--wide .ckl-link { display: flex; align-items: center; gap: 0.5rem; }
.bld-sheet--wide .ckl-link .field-input { flex: 1 1 0; min-width: 0; }
.bld-sheet--wide .ckl-link__url { font-family: var(--font-mono); font-size: 0.8125rem; }
.bld-sheet--wide .ckl-link-slot .field-error { margin-top: 0.25rem; }
.bld-sheet--wide .ckl-links svg,
.bld-sheet--wide .ckl-file__tools svg { width: 0.9375rem; height: 0.9375rem; }
.bld-sheet--wide .ckl-links .btn svg,
.bld-sheet--wide .ckl-drop .btn svg { width: 0.875rem; height: 0.875rem; }

.bld-sheet--wide .ckl-file {
  display: flex; align-items: center; gap: 0.75rem; min-width: 0;
  padding: 0.625rem 0.75rem; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface);
}
.bld-sheet--wide .ckl-file__icon {
  display: grid; place-items: center; flex: none; width: 2.125rem; height: 2.5rem; border-radius: 5px;
  background: var(--danger-soft); color: var(--danger-ink); font-size: 0.625rem; font-weight: 700; letter-spacing: 0.02em;
}
.bld-sheet--wide .ckl-file__text { flex: 1 1 auto; min-width: 0; }
.bld-sheet--wide .ckl-file__name { font-size: 0.875rem; font-weight: 500; color: var(--ink); overflow-wrap: anywhere; text-decoration: none; }
.bld-sheet--wide .ckl-file__name:hover { color: var(--brand); text-decoration: underline; }
.bld-sheet--wide .ckl-file__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; margin-top: 0.125rem; font-size: 0.75rem; color: var(--ink-soft); }
.bld-sheet--wide .ckl-ok { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--success); }
.bld-sheet--wide .ckl-ok svg { width: 0.8125rem; height: 0.8125rem; }
.bld-sheet--wide .ckl-file__tools { display: flex; align-items: center; gap: 0.25rem; flex: none; }
.bld-sheet--wide .ckl-file__tools form { display: inline-flex; flex-direction: row; gap: 0; }
/* The file chooser is the real control, kept focusable inside its label; the
   label draws the button and its focus ring. */
.bld-sheet--wide .ckl-pick { position: relative; }
.bld-sheet--wide .ckl-pick:focus-within { outline: 2px solid var(--brand); outline-offset: 2px; }
.bld-sheet--wide .ckl-drop {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.75rem;
  padding: 0.875rem; border: 1.5px dashed var(--border-field); border-radius: var(--r-md); background: var(--surface);
}
.bld-sheet--wide .ckl-drop.is-over { border-color: var(--brand); background: var(--brand-tint); }
.bld-sheet--wide .ckl-drop__hint { font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .ckl-file-error { margin: 0; }
.bld-sheet--wide .ckl-side-note { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .ckl-side-note svg { width: 1rem; height: 1rem; flex: none; margin-top: 0.0625rem; }
.bld-sheet--wide .ckl-full { display: block; font-size: 0.8125rem; color: var(--ink-soft); }

/* Under the list: the one check the pill does not spell out. */
.bld-sheet--wide .ckl-checks { border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; background: var(--surface); }
.bld-sheet--wide .ckl-checks__head {
  padding: 0.625rem 0.875rem; border-bottom: 1px solid var(--divider); background: var(--bg);
  font-family: var(--font-sans); font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint);
}
.bld-sheet--wide .ckl-checks__line { padding: 0.75rem 0.875rem 0; font-size: 0.875rem; color: var(--ink); }
.bld-sheet--wide .ckl-checks__sub { padding: 0.25rem 0.875rem 0.75rem; font-size: 0.8125rem; color: var(--ink-soft); }

@media (max-width: 1023px) {
  .bld-sheet--wide .ckl-ed { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 639px) {
  .bld-sheet--wide .ckl-link { flex-wrap: wrap; }
  .bld-sheet--wide .ckl-link .field-input { flex-basis: 100%; }
  .bld-sheet--wide .ckl-file { flex-wrap: wrap; }
}

/* Terms and tokens. The stamp beside each value is the token that prints it —
   the same device the block cards use for ids, doing double duty as the thing
   you paste into the prose. */
.bld-tokens { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.bld-token-group {
  border: 1px solid var(--divider);
  border-radius: var(--r-md);
  padding: 0.75rem 0.875rem 0.875rem;
  display: grid;
  gap: 0.625rem;
  min-width: 0;
}
.bld-legend { font-family: var(--font-mono); font-size: 0.6875rem; color: var(--ink-soft); padding: 0 0.3125rem; }
.bld-token-group .bld-id { justify-self: start; }
.bld-token-add { border-top: 1px solid var(--divider); padding-top: 0.875rem; }
.bld-import { border-top: 1px solid var(--divider); padding-top: 0.875rem; }

/* Share: the address and its copy button on one line, because they are one
   action. The field is readonly rather than plain text so it can be selected,
   tabbed to and read out — the copy button is the enhancement. */
.bld-share { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.bld-share .field-input { flex: 1 1 22rem; min-width: 0; font-size: 0.8125rem; }

/* The preview renders the applicant's own section partial, which brings its own
   type scale from the public stylesheet. Give it the page it expects rather than
   letting it inherit the console's density. */
.bld-preview { padding: 1.5rem; background: var(--surface); border-radius: var(--r-lg); }

@media (prefers-reduced-motion: reduce) {
  .bld-card, .bld-section { transition: none; }
}
/* ════════════════════════ end of the Builder ════════════════════════ */

/* ════════════════════════════════════════════════════════════════════════════
   ─── Queue & detail ─── (Phase 4A: the submission queue and one application)

   The console's second work surface. It reuses the vocabulary above wholesale —
   `.queue-toolbar`, `.tabs`, `.card--flush`, `.modern-table`, `.pill`,
   `.factline`, `.answers`, `.empty-state`, `.pager` — and what follows is only
   what none of those could say.

   ONE structural decision, and it is the page rather than the styling: the
   application detail is a READING column beside an ACTING column. Somebody
   adjudicating a four-page application scrolls the answers while the decision
   controls have to stay in reach, and the two jobs are different enough that
   stacking them into one column (which is what every other page here does)
   would bury the controls under the read. Below a laptop they stack in DOM
   order — read first, then act — and the history runs full width beneath both,
   because a history is something you read, not something you use.

   Nothing here introduces a colour. Both status axes are rendered as `.pill`s
   whose word is the state and whose tint is the second signal, and the one place
   this surface spends any weight is the same one the builder does: the MONO
   STAMP on anything that is a record — a reference number, a pinned version, a
   requirement id, a byte count, a timestamp in the history.
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── The queue ─────────────────────────────────────────────────────────────
   The row leads with the person and stamps the reference under the name, so a
   cell carries two facts without a seventh column. `.row-sub.record` is the
   pairing that does it and needs the mono size stepped down a notch — 0.75rem
   IBM Plex Mono beside 0.9375rem Inter otherwise reads as the same size. */
.row-sub.record { font-size: 0.6875rem; letter-spacing: 0; }

/* Six columns, one of them two lines. 52rem is where the assignee column stops
   wrapping every name onto two lines on a laptop. */
.queue-table { min-width: 52rem; }

/* The submitted stamp. One line, always: "Sep 2 · 2:31 PM" broken across two is
   two half-dates, and the column is the one people scan down. */
.queue-when { font-size: 0.8125rem; white-space: nowrap; }

/* A row header is a label, not a caption. `<th>` centres by browser default,
   which centres the applicant's name AND the two `.row-sub` lines under it
   against a table of left-aligned columns — a default nobody chose. */
.modern-table tbody th,
.queue-table tbody th { text-align: left; }

/* ─── The dashboard's attention lines ───────────────────────────────────────
   Each count now leads somewhere — the queue filtered to exactly the thing the
   line names. The link carries the sentence rather than sitting beside it, so
   the target is the whole phrase rather than a word somebody has to aim at. */
.dept-card__link { color: inherit; text-decoration: none; }
.dept-card__link:hover { color: var(--brand); text-decoration: underline; }
.attention__item a { color: inherit; text-decoration: none; }
.attention__item a:hover { color: var(--brand); text-decoration: underline; }

/* ─── One application ───────────────────────────────────────────────────────
   The fact strip sits directly under the console's page head, so it loses the
   top rule the public form's version carries: the header above it is already a
   boundary and two rules 12px apart read as a mistake. */
.subm { display: flex; flex-direction: column; gap: 1.25rem; }
.subm__facts { margin-top: 0; border-top: 0; padding-top: 0; }

.subm__layout { display: grid; gap: 1.25rem; align-items: start; }
.subm__main,
.subm__aside { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }

@media (min-width: 1100px) {
  /* 23rem is the width the two selects, the file inputs and a filename need
     without wrapping; the rest goes to the answers, which are the long read. */
  .subm__layout { grid-template-columns: minmax(0, 1fr) 23rem; }
}

/* A labelled control and its button, stacked. Not `.field-pair`: these are one
   decision each, and putting Save beside the select makes a pair of them look
   like one form with two fields.

   The top margin is unconditional rather than `+ .subm__control`, because the
   FIRST control also needs air under the card's title — without it "Review" and
   the "Review state" label under it read as one two-line heading. */
.subm__control { display: grid; gap: 0.5rem; justify-items: start; margin-top: 1rem; }
.subm__control .bld-field { width: 100%; }

.subm__stamp {
  margin-top: 0.875rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--divider);
  font-size: 0.75rem;
  color: var(--ink-faint);
}
.subm__internal { font-size: 0.75rem; line-height: 1.5; color: var(--ink-faint); margin-top: 0.375rem; }

/* ─── The answers ───────────────────────────────────────────────────────────
   Grouped by the section they were asked in, with the section title as a quiet
   rule rather than another card: a form's sections are pages of one document,
   and drawing each as a card would make an application look like six things. */
/* Unconditional, for the same reason `.subm__control`'s is: the first section
   title also has to clear the card's own "Answers" heading. */
.answer-group { margin-top: 1.125rem; }
.answer-group__title {
  font-family: var(--font-heading);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-heading);
  padding-bottom: 0.375rem;
  border-bottom: 1px solid var(--divider);
}
/* A question the applicant's own answers switched off. Italic and faint, and it
   says the word "(hidden)" — the tint alone would be indistinguishable from an
   answer nobody typed. */
.answer-hidden { color: var(--ink-faint); font-style: italic; }

/* ─── The document checklist ────────────────────────────────────────────────
   One rule per requirement rather than a nested card, because these already sit
   inside one and a card in a card has no edge left to give. */
.doc-list { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; }
.doc {
  display: grid;
  gap: 0.5rem;
  padding: 0.875rem 0;
  border-top: 1px solid var(--divider);
}
.doc-list > .doc:first-child { border-top: 0; padding-top: 0.25rem; }
.doc__head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.625rem; }
.doc__label { font-size: 0.875rem; font-weight: 600; color: var(--ink); min-width: 0; }
.doc__file { font-size: 0.875rem; overflow-wrap: anywhere; }
/* The filename reads as a link because it IS one — brand blue, underlined on
   hover, with the "open in a box" arrow saying that it opens rather than
   downloads. `table-link` is ink-coloured by design (a queue of blue rows is
   noise); here there is one link per card and it should look like one. */
.doc__link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-weight: 500;
  color: var(--brand);
  text-decoration: none;
}
.doc__link:hover { color: var(--brand-hover); text-decoration: underline; }
.doc__link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 2px; }
.doc__link-icon { width: 0.9em; height: 0.9em; flex: 0 0 auto; }
/* An e-sign agreement's record inside its requirement: set on the quiet
   surface tint so it reads as "arriving from elsewhere", distinct from the file
   row and the upload control around it. */
.doc__agreement {
  display: grid;
  gap: 0.375rem;
  padding: 0.625rem 0.75rem;
  border-radius: 0.375rem;
  background: var(--surface-2);
}
.doc__agreement .answers { margin-top: 0; grid-template-columns: minmax(0, 7rem) minmax(0, 1fr); }
.doc__agreement-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 1rem; }
.doc__upload { display: grid; gap: 0.375rem; justify-items: start; }
.doc__upload .field-input { width: 100%; font-size: 0.8125rem; padding: 0.375rem 0.5rem; }
/* A multi-signer agreement (2026-10-26): a summary line, one row per signer,
   extra copies, and hand-filing for a named signer. The rows stack in the 23rem
   side column and line up as the rendition's table once the card is wide —
   `.signer-rows` is a size container, so this follows the card, not the window. */
.doc__agreement--multi { gap: 0.625rem; }
.signers-sum { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 0.75rem; font-size: 0.8125rem; }
.signers-sum p { margin: 0; }
.signers-sum b { color: var(--ink-heading); }
.signers-sum .record { color: var(--ink-soft); white-space: nowrap; }
.signer-rows { container-type: inline-size; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); }
.signer-rows__head { display: none; }
.signer-rows__list { list-style: none; margin: 0; padding: 0; }
.signer-row {
  display: grid; gap: 0.375rem; padding: 0.625rem 0.75rem;
  border-top: 1px solid var(--divider); font-size: 0.8125rem;
}
.signer-rows__list > .signer-row:first-child { border-top: 0; }
.signer-row--off { background: var(--bg); }
.signer-row__who { display: grid; min-width: 0; }
.signer-row__name { font-weight: 600; color: var(--ink-heading); overflow-wrap: anywhere; }
.signer-row--off .signer-row__name { color: var(--ink-soft); text-decoration: line-through; }
.signer-row__mail { font-size: 0.75rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.signer-again { display: inline-block; justify-self: start; padding: 0 0.375rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--ink-heading); font-size: 0.75rem; font-weight: 500; line-height: 1.125rem; white-space: nowrap; }
.signer-row__status { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; }
.signer-row__sent, .signer-row__copy { min-width: 0; overflow-wrap: anywhere; }
.signer-row__sent .row-sub, .signer-row__copy .row-sub { display: block; }
.signer-row__k { margin-right: 0.375rem; font-weight: 600; color: var(--ink-soft); }
.signer-row__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.125rem 0.875rem; }
.signer-row__actions form { display: inline-flex; margin: 0; }
@container (min-width: 40rem) {
  .signer-rows__head,
  .signer-row {
    display: grid;
    /* Fixed last track: the head row and each signer row are separate grids,
       so an `auto` track would size to its own content in each and the
       columns would drift apart. */
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.05fr) minmax(0, 0.8fr) minmax(0, 1.35fr) 8.75rem;
    gap: 0.75rem; align-items: start;
  }
  .signer-rows__head {
    padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); background: var(--bg);
    font-size: 0.75rem; font-weight: 600; color: var(--ink-soft);
  }
  .signer-row { padding: 0.75rem; }
  .signer-row__k { display: none; }
  .signer-row__actions { flex-direction: column; align-items: flex-start; }
}
.signers-extra { display: grid; gap: 0.375rem; }
.doc__upload--signer { justify-items: stretch; }
.doc__upload-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 0.75rem; }
.doc__upload-field { display: grid; gap: 0.25rem; flex: 1 1 12rem; min-width: 0; }
.doc__upload-field .field-select { width: 100%; font-size: 0.8125rem; }
.doc-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1rem;
  margin-top: 0.875rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--divider);
}
/* What is still missing, listed inside the waiver dialog so the decision is made
   in front of the thing it is about. */
.doc-outstanding {
  margin: 0.75rem 0 0;
  padding: 0.625rem 0.875rem;
  list-style: none;
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning);
  border-radius: var(--r-md);
  font-size: 0.8125rem;
  color: var(--ink);
  display: grid;
  gap: 0.25rem;
}

/* ─── The checklist card ────────────────────────────────────────────────────
   One ruled row per pinned item: a done/not-done glyph (decorative — the line
   under the title says it in words), the title with Required/Optional, who
   ticked it and when, and the one control that applies. */
.ckl-card__head { display: flex; align-items: center; justify-content: space-between; gap: 0.625rem; }
.ckl-card__waived {
  margin-top: 0.75rem; padding: 0.625rem 0.75rem; border-radius: var(--r-md);
  background: var(--bg); font-size: 0.875rem; color: var(--ink); overflow-wrap: anywhere;
}
.ckl-items { list-style: none; margin: 0.875rem 0 0; padding: 0; display: grid; }
.ckl-item {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.75rem 0; border-top: 1px solid var(--divider);
}
.ckl-glyph {
  display: grid; place-items: center; flex: none; width: 1.375rem; height: 1.375rem; margin-top: 0.0625rem;
  border-radius: 50%; border: 2px solid var(--border-field); box-sizing: border-box; color: var(--on-success);
}
.ckl-glyph.is-done { border-color: var(--success); background: var(--success); }
.ckl-glyph svg { width: 0.8125rem; height: 0.8125rem; }
.ckl-item__body { flex: 1 1 auto; min-width: 0; }
.ckl-item__title { font-size: 0.875rem; font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.ckl-item__req {
  margin-left: 0.375rem; font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--ink-soft);
}
.ckl-item__meta { margin-top: 0.125rem; font-size: 0.8125rem; color: var(--ink-soft); }
.ckl-item form { flex: none; display: flex; }
.ckl-item .btn { padding: 0.375rem 0.625rem; font-size: 0.8125rem; }
.ckl-card__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 1rem;
  margin-top: 0.25rem; padding-top: 0.75rem; border-top: 1px solid var(--divider);
}
.ckl-card__note { margin-top: 0.75rem; font-size: 0.75rem; line-height: 1.5; color: var(--ink-soft); }
/* The queue's Checklist cell for an application filed before the form had one. */
.queue-none { font-size: 0.8125rem; font-weight: 500; color: var(--ink-soft); white-space: nowrap; }

/* ─── Notes ─────────────────────────────────────────────────────────────────
   Newest first, each one a small stack of who/when over what. */
.note-list { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; }
.note { padding: 0.75rem 0; border-top: 1px solid var(--divider); }
.note__meta { font-size: 0.6875rem; color: var(--ink-faint); }
.note__body { margin-top: 0.1875rem; font-size: 0.875rem; line-height: 1.5; overflow-wrap: anywhere; }

/* ─── The history ───────────────────────────────────────────────────────────
   Three columns: when, what, who. The stamp is mono and fixed-width so the
   column reads as a ruler down the left, which is what makes a run of events
   scannable — the alternative, a wrapping sentence per line, is a paragraph
   nobody finishes. Actor last, because it is the least-asked of the three. */
.subm__history { padding: 0; }
.subm__history-title { padding: 1.125rem 1.25rem 0.75rem; }
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline__item {
  display: grid;
  grid-template-columns: 9.5rem minmax(0, 1fr) 11rem;
  gap: 0.25rem 1rem;
  align-items: baseline;
  padding: 0.625rem 1.25rem;
  border-top: 1px solid var(--divider);
  font-size: 0.8125rem;
}
.timeline__when { color: var(--ink-faint); font-size: 0.75rem; white-space: nowrap; }
/* The middle column. `min-width: 0` because a grid item defaults to `auto`,
   which refuses to shrink below its longest word — a filename with no spaces in
   it would push the actor column off the card instead of wrapping. */
.timeline__what { min-width: 0; }
.timeline__label { font-weight: 600; color: var(--ink); }
.timeline__detail { color: var(--ink-soft); overflow-wrap: anywhere; }
.timeline__who { color: var(--ink-soft); font-size: 0.75rem; }

@media (max-width: 719px) {
  /* Three columns at 360px is three unreadable ones; the stamp and the actor
     become a caption line under the event rather than columns beside it. */
  .timeline__item { grid-template-columns: minmax(0, 1fr); gap: 0.125rem; }
  .timeline__when { order: -1; }
  .doc__head { flex-direction: column; align-items: flex-start; }
}
/* ════════════════════════ end of Queue & detail ════════════════════════ */

/* ---- Document viewer -----------------------------------------------------
   The one modal in the app that shows a FILE rather than a form, so it takes
   the whole viewport rather than the 34rem form width: a transcript scaled to
   a form-sized dialog is a transcript nobody can read. The checklist rail on
   the left is the reason the dialog exists at all — every file on the
   application is one click away without leaving the page — and it drops above
   the stage on a phone, where a rail would leave the page no room to read.
   The stage frames the inline route (a PDF or an image); a Word document gets
   `.viewer__empty` instead of a blank frame. */
.modal--viewer {
  width: min(88rem, calc(100vw - 2rem));
  max-width: none;
  height: calc(100vh - 3rem);
  max-height: calc(100vh - 3rem);
}
.viewer { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.viewer__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 1rem;
}
.viewer__head-text { min-width: 0; flex: 1 1 18rem; }
.viewer__head .modal__title { overflow-wrap: anywhere; }
.viewer__meta { margin: 0.25rem 0 0; font-size: 0.8125rem; color: var(--ink-soft); }
.viewer__head-actions { display: flex; gap: 0.5rem; flex: 0 0 auto; }
.viewer__body {
  display: grid;
  grid-template-columns: 17rem minmax(0, 1fr);
  min-height: 0;
  flex: 1 1 auto;
}
.viewer-page .viewer__body { min-height: calc(100vh - 14rem); }
.viewer__list {
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 0.875rem;
  border-right: 1px solid var(--divider);
  background: var(--surface-2);
}
.viewer__list-title {
  margin: 0 0 0.5rem 0.375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.viewer__items { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.viewer__item {
  display: grid;
  gap: 0.125rem;
  padding: 0.5rem 0.625rem;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  color: var(--ink);
  text-decoration: none;
  min-width: 0;
}
a.viewer__item:hover { background: var(--surface); border-color: var(--border); }
a.viewer__item:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.viewer__item--current { background: var(--surface); border-color: var(--brand); }
.viewer__item--missing { color: var(--ink-faint); }
.viewer__item-label { font-size: 0.8125rem; font-weight: 600; }
.viewer__item-file { font-size: 0.8125rem; overflow-wrap: anywhere; }
.viewer__item-sub { font-size: 0.75rem; color: var(--ink-soft); }
.viewer__stage {
  display: flex;
  min-height: 0;
  min-width: 0;
  background: var(--surface-2);
}
.viewer__frame { flex: 1 1 auto; width: 100%; height: 100%; min-height: 24rem; border: 0; background: #fff; }
.viewer__image {
  display: block;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.viewer__empty {
  margin: auto;
  max-width: 28rem;
  padding: 2rem 1.5rem;
  text-align: center;
  display: grid;
  gap: 0.75rem;
  justify-items: center;
}
.viewer__empty-title { margin: 0; font-weight: 600; color: var(--ink); }
@media (max-width: 47.9375rem) {
  .viewer__body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .viewer__list { max-height: 11rem; border-right: 0; border-bottom: 1px solid var(--divider); }
  .viewer__stage { min-height: 20rem; }
}

/* ════════════════════════════════════════════════════════════════════════════
   Rubric (builder)

   The rubric tab is a board of compact criterion cards. The editor is a two-
   column form: authored values on the left, the form's evidence choices on the
   right. It keeps the existing builder vocabulary quiet so the point values and
   stable criterion numbers are the things a builder can scan.
   ════════════════════════════════════════════════════════════════════════════ */

.rubric-page,
.rubric-editor-page { display: grid; gap: 1.25rem; max-width: 78rem; }

.rubric-settings { display: grid; gap: 1rem; }
.rubric-settings__head,
.rubric-board__head,
.rubric-evidence__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.rubric-settings__eyebrow,
.rubric-board__eyebrow {
  display: block;
  margin-bottom: 0.25rem;
  color: var(--ink-faint);
}
.rubric-settings__row {
  display: grid;
  grid-template-columns: minmax(15rem, 1fr) minmax(16rem, 24rem);
  gap: 1.25rem;
  align-items: start;
}
.rubric-settings__threshold { min-width: 0; }
.rubric-settings__number,
.rubric-editor__points { display: flex; align-items: center; gap: 0.5rem; }
.rubric-settings__number .field-input,
.rubric-editor__points .field-input { min-width: 0; }
.rubric-settings__suffix,
.rubric-editor__suffix {
  flex: none;
  color: var(--ink-soft);
  font-size: 0.8125rem;
  white-space: nowrap;
}
.rubric-settings__instructions {
  border-top: 1px solid var(--divider);
  padding-top: 0.875rem;
}
.rubric-settings__instructions summary {
  color: var(--brand);
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 600;
}
.rubric-settings__instructions .bld-field { margin-top: 0.75rem; }

/* A real checkbox, dressed as a switch. The input remains in the accessibility
   tree and the label supplies the visible focus state. */
.switch {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: start;
  gap: 0.625rem;
  cursor: pointer;
  min-width: 0;
}
.switch > input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}
.switch__track {
  position: relative;
  display: block;
  width: 2.5rem;
  height: 1.5rem;
  margin-top: 0.0625rem;
  border-radius: var(--r-full);
  background: var(--border-strong);
  transition: background-color 120ms ease;
}
.switch__thumb {
  position: absolute;
  top: 0.1875rem;
  left: 0.1875rem;
  width: 1.125rem;
  height: 1.125rem;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(1, 33, 75, 0.18);
  transition: transform 120ms ease;
}
.switch > input:checked + .switch__track { background: var(--brand); }
.switch > input:checked + .switch__track .switch__thumb { transform: translateX(1rem); }
.switch > input:focus-visible + .switch__track { outline: 2px solid var(--brand); outline-offset: 2px; }
.switch__label { min-width: 0; font-size: 0.875rem; font-weight: 600; color: var(--ink); }
.switch__label .field-hint { font-weight: 400; }

.rubric-board { display: grid; gap: 1rem; }
.rubric-board__title { font-family: var(--font-heading); font-size: 1.25rem; font-weight: 600; color: var(--ink-heading); }
.rubric-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.875rem; }
.rubric-card { display: flex; flex-direction: column; gap: 0; min-width: 0; padding: 0; overflow: hidden; }
.rubric-card__link {
  display: grid;
  align-content: start;
  gap: 0.625rem;
  min-width: 0;
  flex: 1 1 auto;
  padding: 1rem 1rem 0.875rem;
  color: var(--ink);
  text-decoration: none;
}
.rubric-card__link:hover { background: var(--brand-tint); }
.rubric-card__link:focus-visible { z-index: 1; outline-offset: -3px; }
.rubric-card__head { display: flex; align-items: center; gap: 0.4375rem; min-width: 0; }
.rubric-card__number {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--r-sm);
  background: var(--brand-tint);
  color: var(--brand);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
}
.rubric-card__group {
  min-width: 0;
  overflow: hidden;
  color: var(--ink-soft);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-overflow: ellipsis;
  text-transform: none;
  white-space: nowrap;
}
.rubric-card__points { margin-left: auto; flex: none; color: var(--ink-heading); font-family: var(--font-mono); font-size: 0.75rem; }
.rubric-card__title { overflow-wrap: anywhere; font-size: 1rem; font-weight: 600; line-height: 1.3; color: var(--ink-heading); }
.rubric-card__minimum { color: var(--warning); font-size: 0.8125rem; line-height: 1.4; }
.rubric-card__minimum span { font-weight: 700; }
.rubric-card__evidence { display: flex; flex-wrap: wrap; gap: 0.3125rem; align-items: center; min-width: 0; }
.chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 0.1875rem 0.4375rem;
  border: 1px solid var(--divider);
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: 0.6875rem;
  line-height: 1.25;
}
.chip--q { border-color: #C7DDF8; background: var(--brand-tint); color: var(--brand); }
.chip--doc { border-color: #D8D3F0; background: #F2F0FB; color: #55458A; }
.rubric-card__evidence .chip { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rubric-card__judgement { color: var(--ink-faint); font-size: 0.75rem; font-style: italic; }
.rubric-card__tools {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.125rem;
  min-height: 2.5rem;
  padding: 0.375rem 0.625rem;
  border-top: 1px solid var(--divider);
  background: var(--surface);
}
.rubric-card__tools form { display: inline-flex; }

.rubric-editor__back { width: fit-content; color: var(--brand); font-size: 0.875rem; font-weight: 500; text-decoration: none; }
.rubric-editor__back:hover { text-decoration: underline; }
.rubric-editor { display: grid; gap: 1rem; }
.rubric-editor__columns { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(20rem, 0.92fr); gap: 1.25rem; align-items: start; }
.rubric-editor__details,
.rubric-evidence { display: grid; gap: 0.875rem; min-width: 0; }
.rubric-editor__pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(10rem, 0.8fr); gap: 0.875rem; }
.rubric-bands { display: grid; gap: 0.625rem; padding: 0; border: 0; }
.rubric-bands__title { padding: 0; color: var(--ink-heading); font-size: 0.9375rem; font-weight: 600; }
.rubric-bands__rows { display: grid; gap: 0.5rem; }
.rubric-band { display: grid; grid-template-columns: minmax(0, 1fr) minmax(6rem, 0.55fr) auto; gap: 0.5rem; align-items: end; }
.rubric-band__remove { margin-bottom: 0.625rem; color: var(--danger); }
.rubric-bands__add { justify-self: start; }
.rubric-editor__delete { display: flex; justify-content: flex-end; padding-top: 0.25rem; }

.rubric-evidence { position: sticky; top: 1rem; }
.rubric-evidence__head .card__title { max-width: 20rem; }
.rubric-evidence__group { display: grid; gap: 0.25rem; padding: 0.75rem 0 0; border: 0; border-top: 1px solid var(--divider); }
.rubric-evidence__group legend { padding: 0; color: var(--ink-heading); font-size: 0.8125rem; font-weight: 600; }
.rubric-evidence__row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  padding: 0.5rem 0.625rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  cursor: pointer;
}
.rubric-evidence__row:hover { border-color: var(--border); background: var(--surface); }
.rubric-evidence__row.is-selected { border-color: #CCE2F4; background: var(--brand-tint); }
/* The tied group leads the list: a tinted band with the count beside the legend,
   so what a reviewer will actually see is read before the long menu of what they could. */
.rubric-evidence__group--tied { border-top: 0; padding: 0.75rem; border-radius: var(--r-md); background: var(--brand-tint); }
.rubric-evidence__group--tied legend { float: left; width: 100%; margin-bottom: 0.4rem; color: var(--brand); }
.rubric-evidence__group--tied .rubric-evidence__row { background: var(--surface); }
.rubric-evidence__group--tied .field-hint { margin: 0.35rem 0 0; }
.rubric-evidence__count { display: inline-block; min-width: 1.4em; margin-left: 0.35rem; padding: 0 0.4em; border-radius: 999px; background: var(--brand); color: var(--on-brand); font: 600 0.6875rem/1.5 var(--font-mono); text-align: center; vertical-align: 1px; }
.rubric-evidence__copy { display: grid; gap: 0.125rem; min-width: 0; font-size: 0.8125rem; color: var(--ink); }
.rubric-evidence__copy > :first-child { overflow-wrap: anywhere; }
.rubric-evidence__copy .bld-id { width: fit-content; }

@media (max-width: 1199px) { .rubric-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 899px) {
  .rubric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rubric-editor__columns { grid-template-columns: minmax(0, 1fr); }
  .rubric-evidence { position: static; }
}
@media (max-width: 639px) {
  .rubric-settings__row,
  .rubric-editor__pair { grid-template-columns: minmax(0, 1fr); }
  .rubric-grid { grid-template-columns: minmax(0, 1fr); }
  .rubric-band { grid-template-columns: minmax(0, 1fr) minmax(6rem, 0.7fr) auto; }
}

/* ---- Rubric (scoring, queue, detail) ----------------------------------------

   Three surfaces, one vocabulary. The criterion walk (`/submissions/<id>/rubric`),
   the queue's rubric column, and the mini score sheet on the submission page all
   draw the same two things: a number out of a maximum, and a word for what that
   number means. Nothing here invents a colour — every value is a token, and the
   tints only ever repeat what the words beside them already say (WCAG 1.4.1).

   The walk is DESKTOP-ONLY by decision, not by omission: a reviewer reads a
   transcript in one column while choosing a band in another, and a stacked
   version of that on a phone would be a page nobody could score from. It has one
   breakpoint, below which the two columns stack so the page is still readable —
   readable, not workable.

   Why `.walk-*` rather than `.rubric-*`: the builder's Rubric tab already owns
   `.rubric-card`, `.rubric-band`, `.rubric-evidence` and `.rubric-grid` for the
   AUTHORING side of the same feature. Two different cards under one class name is
   how a stylesheet starts lying, so the scoring side is its own namespace and
   only the genuinely shared pieces — `.chip`, `.pill`, `.record`, `.meter` — are
   held in common. */

/* ─── The meter ──────────────────────────────────────────────────────────────
   A score against its maximum, with the threshold drawn on the same scale. Six
   pixels, because it sits inside a table row: any taller and it becomes the
   loudest thing in a sheet whose job is the applicant's name.

   The tick is the threshold. It is what makes "did this clear the bar" legible
   without reading either number — and it is `--warning`, not `--danger`, because
   a threshold is a mark, not a verdict. */
/* The one notice variant this feature needs and the file did not already have:
   "the rubric changed while you were scoring" is information, not a warning —
   nothing is wrong and nothing was lost. Same three values `.notice--warning`
   uses, in brand rather than amber, so the two read as one system. */
.notice--info {
  background: var(--brand-tint);
  border-color: #C7DDF8;
  border-left-color: var(--brand);
}
.notice--info .notice__icon { color: var(--brand); }
.notice--info .notice__title,
.notice--info .notice__body { color: var(--navy); }

.meter {
  position: relative;
  display: block;
  width: 100%;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--surface-2);
  overflow: hidden;
}
.meter__fill {
  display: block;
  height: 100%;
  border-radius: var(--r-full);
  background: var(--brand);
}
.meter__fill--danger { background: var(--danger); }
.meter__mark {
  position: absolute;
  top: -1px;
  bottom: -1px;
  width: 2px;
  margin-left: -1px;
  background: var(--warning);
}

/* ─── The document stub ──────────────────────────────────────────────────────
   A file named on a criterion. Dashed, because unlike the documents card on the
   detail page this is a REFERENCE to a file rather than the place it is managed:
   the solid card is where you replace or remove one, this is where you glance at
   it while scoring. */
.docstub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.625rem 0.75rem;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
}
.docstub + .docstub { margin-top: 0.5rem; }
.docstub__text { display: grid; gap: 0.125rem; min-width: 0; }
.docstub__label { font-size: 0.8125rem; font-weight: 600; color: var(--ink); }
.docstub__file {
  font-size: 0.75rem;
  color: var(--ink-faint);
  overflow-wrap: anywhere;
}
/* Sized down here rather than through a new global `.btn-sm`: this is the only
   place in the console that wants a button smaller than the standard one, and a
   size modifier nobody else uses is a modifier that drifts. */
.docstub .btn { padding: 0.25rem 0.625rem; font-size: 0.75rem; }

/* ─── The criterion walk ─────────────────────────────────────────────────────
   Stepper left, criterion right. The rail is sticky because the whole point of
   the stepper is that it answers "how much is left" at any scroll position of a
   four-page transcript. */
.rubric-walk { display: flex; flex-direction: column; gap: 1.25rem; }
.rubric-walk__layout {
  display: grid;
  grid-template-columns: 17rem minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}
.rubric-walk__rail { position: sticky; top: 1rem; }
.rubric-walk__stage { min-width: 0; }

.rubric-steps {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.rubric-step {
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-top: 1px solid var(--divider);
  color: var(--ink-soft);
  text-decoration: none;
}
.rubric-steps > .rubric-step:first-child { border-top: 0; }
.rubric-step:hover { background: var(--bg); color: var(--ink); }
.rubric-step:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.rubric-step.is-current { background: var(--brand-tint); color: var(--ink); }
.rubric-step__badge {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
  background: var(--surface);
}
/* Filled once scored, outlined in brand while it is the one in hand. The word
   under it ("scored" / "not scored yet") is what a screen reader gets; this is
   the second signal, never the only one. */
.rubric-step.is-scored .rubric-step__badge {
  border-color: var(--success);
  background: var(--success);
  color: var(--on-success);
}
.rubric-step.is-current .rubric-step__badge { border-color: var(--brand); color: var(--brand); }
.rubric-step.is-current.is-scored .rubric-step__badge { color: var(--on-success); }
.rubric-step__text {
  font-size: 0.8125rem;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.rubric-step__points {
  font-size: 0.75rem;
  color: var(--ink-faint);
  white-space: nowrap;
}
.rubric-steps__hint {
  margin-top: 0.625rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* ─── The running head ───────────────────────────────────────────────────────
   Total, verdict, exit, submit — the four things that are true of the whole card
   while the page shows one twelfth of it. It sits in `page-head__actions`, which
   is already a flex row, so this only sets the alignment of its own parts. */
.rubric-head { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.rubric-head__score {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-heading);
}
.rubric-head__score b { font-size: 1.375rem; font-weight: 600; }
.rubric-head__of { font-size: 0.875rem; color: var(--ink-faint); }
.rubric-head__filed { font-size: 0.8125rem; color: var(--ink-faint); }

/* ─── One criterion ──────────────────────────────────────────────────────────
   Evidence takes the width it needs; scoring is a fixed 24rem so the band tiles
   stay the same size from criterion to criterion — a target that moves between
   steps is a target people mis-click. */
.walk-card { padding: 0; overflow: hidden; }
.walk-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.125rem 1.25rem;
  border-bottom: 1px solid var(--divider);
}
.walk-card__heading { min-width: 0; }
.walk-card__title {
  margin-top: 0.375rem;
  font-family: var(--font-heading);
  font-size: 1.25rem;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-heading);
}
.walk-card__group {
  margin-top: 0.1875rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}
.walk-card__error { padding: 0.75rem 1.25rem 0; }
.walk-card__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24rem;
  align-items: start;
}
.walk-card__foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1.25rem;
  border-top: 1px solid var(--divider);
  background: var(--bg);
}
.walk-card__foot > :last-child { justify-self: end; }
.walk-card__hint { font-size: 0.75rem; color: var(--ink-faint); text-align: center; }

.walk-evidence { padding: 1.25rem; min-width: 0; }
.walk-evidence__label {
  margin-top: 1.125rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.walk-evidence > .walk-evidence__label:first-child { margin-top: 0; }
.walk-evidence__none {
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.rubric-answers { margin-top: 0.5rem; display: grid; gap: 0.75rem; }
.rubric-answers__item { min-width: 0; }
.rubric-answers__q { font-size: 0.8125rem; font-weight: 600; color: var(--brand); }
.rubric-answers__a {
  margin-top: 0.125rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* "(hidden)" and "not on version 3" are absences, not answers. */
.rubric-answers__a.is-absent { color: var(--ink-faint); font-style: italic; }

.rubric-guidance {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.rubric-guidance p + p { margin-top: 0.5rem; }
.rubric-guidance ul, .rubric-guidance ol { margin: 0.5rem 0 0 1.125rem; }

.rubric-docs { list-style: none; margin: 0.5rem 0 0; padding: 0; }

/* ─── Scoring ────────────────────────────────────────────────────────────────
   Tinted, so the acting half of the card is visibly not the reading half. */
.walk-score {
  padding: 1.25rem;
  border-left: 1px solid var(--divider);
  background: var(--bg);
  min-width: 0;
}
.walk-bands {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.walk-band {
  display: grid;
  gap: 0.125rem;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  text-align: left;
  cursor: pointer;
}
.walk-band:hover { border-color: var(--border-strong); }
.walk-band:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.walk-band.is-picked {
  border-color: var(--brand);
  background: var(--brand-tint);
  box-shadow: inset 0 0 0 1px var(--brand);
}
.walk-band:disabled { cursor: default; opacity: 0.7; }
/* A descriptive band ("1 point per course") carries no number to pick, so it is
   a caption rather than a control and must not look clickable. */
.walk-band--note { cursor: default; border-style: dashed; background: transparent; }
.walk-band__points {
  font-size: 1.125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-heading);
}
.walk-band.is-picked .walk-band__points { color: var(--brand); }
.walk-band__label { font-size: 0.75rem; line-height: 1.35; color: var(--ink-soft); }

.walk-points { margin-top: 1.125rem; }
.walk-points__row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.25rem; }
.walk-points__row .field-input { width: 5.5rem; }
.walk-points__of { font-size: 0.875rem; color: var(--ink-faint); }
.walk-note { margin-top: 1.125rem; }
.walk-note textarea { width: 100%; margin-top: 0.25rem; }
/* A filed scorecard is a record, and the controls have to look like a record
   rather than like inputs somebody has not typed in yet. */
.walk-score .field-input:disabled {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--ink-soft);
  cursor: default;
}

/* ─── The queue's rubric column ──────────────────────────────────────────────
   Three lines in 16rem: the number, the meter, the word. The word is last
   because it is the one a scanning eye stops on. */
.queue-table__rubric { width: 16rem; }
.rubric-cell { display: grid; gap: 0.25rem; min-width: 8rem; }
.rubric-cell__score { font-size: 0.8125rem; color: var(--ink-heading); }
.rubric-cell__score b { font-size: 1rem; font-weight: 600; }
.rubric-cell__score .of { color: var(--ink-faint); }
.rubric-cell__label { font-size: 0.75rem; color: var(--ink-soft); }
.rubric-cell__label.is-below { color: var(--danger); }

/* ─── The mini score sheet ───────────────────────────────────────────────────
   Two columns of rows above the answers. Two, because twelve criteria in one
   column is a scroll and in two is a glance — and because the row is short: a
   number, a name, a bar and a fraction. */
.sheet-card { padding: 1.125rem 1.25rem 1.25rem; }
.sheet-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.sheet-card__hint {
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-faint);
}
.ms-grid {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.375rem 1.75rem;
}
.ms-row {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr) 4.5rem auto;
  align-items: center;
  gap: 0.625rem;
  padding: 0.3125rem 0;
  border-top: 1px solid var(--divider);
}
.ms-row__num { font-size: 0.6875rem; color: var(--ink-faint); }
.ms-row__title {
  font-size: 0.8125rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ms-row__bar {
  display: block;
  height: 4px;
  border-radius: var(--r-full);
  background: var(--surface-2);
  overflow: hidden;
}
.ms-row__fill { display: block; height: 100%; background: var(--brand); }
.ms-row__points {
  font-size: 0.75rem;
  color: var(--ink-soft);
  white-space: nowrap;
  text-align: right;
}

@media (max-width: 1099px) {
  /* Readable, not workable — see the note at the top of this block. */
  .rubric-walk__layout { grid-template-columns: minmax(0, 1fr); }
  .rubric-walk__rail { position: static; }
  .walk-card__body { grid-template-columns: minmax(0, 1fr); }
  .walk-score { border-left: 0; border-top: 1px solid var(--divider); }
  .ms-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ════════════════════════════════════════════════════════════════════════════
   Payments tab

   The preview deliberately reuses the applicant milestone language: a tinted
   receipt band, a brand rule and mono numerals. The ledger below is a ruled
   record sheet, so it stays on the shared `.modern-table` rhythm. 
   ════════════════════════════════════════════════════════════════════════════ */

.payments-page { display: grid; gap: 1.25rem; max-width: 86rem; }
.payments-builder-grid {
  display: grid;
  grid-template-columns: minmax(20rem, 0.85fr) minmax(24rem, 1.15fr);
  gap: 1.25rem;
  align-items: start;
}
.payment-settings,
.payment-quote { min-width: 0; }
.payment-settings { display: grid; gap: 1rem; }
.payment-settings__head,
.payment-ledger__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.payment-settings__eyebrow,
.payment-ledger__eyebrow {
  margin-bottom: 0.25rem;
  color: var(--ink-faint);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.payment-settings__fields { display: grid; gap: 1rem; }
.payment-settings__amount { display: flex; align-items: center; }
.payment-settings__currency {
  display: grid;
  place-items: center;
  align-self: stretch;
  min-width: 2.5rem;
  border: 1px solid var(--border-field);
  border-right: 0;
  border-radius: var(--r-md) 0 0 var(--r-md);
  background: var(--surface-2);
  color: var(--ink-soft);
  font-family: var(--font-mono);
}
.payment-settings__amount .field-input { border-radius: 0 var(--r-md) var(--r-md) 0; }
.payment-settings__switch-error { margin: -0.625rem 0 0 3.125rem; }
.payment-settings__pass-fees { align-items: flex-start; }

/* How the applicant pays: the two switches at the top of the applicant-view
   card, each saved the moment it is flipped. Set off from the preview below by a
   rule, because they are settings and the preview is not. */
.payment-quote__controls {
  display: grid;
  gap: 0.875rem;
  padding-bottom: 1.25rem;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--border);
}
.payment-quote__controls-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}
.payment-quote__controls-title {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-heading);
}
.square-env { display: grid; gap: 0.375rem; }
.square-env__state { display: block; margin-top: 0.125rem; font-weight: 400; color: var(--ink-soft); }
.square-env__state strong { color: var(--ink); font-weight: 600; }
.square-env__hint { margin-left: 3.125rem; }
.switch > input:disabled + .switch__track { opacity: 0.45; }
.switch:has(> input:disabled) { cursor: not-allowed; }
.switch:has(> input:disabled) .switch__label { color: var(--ink-soft); }
.payment-quote__savenote { font-size: 0.75rem; line-height: 1.5; color: var(--ink-faint); }

/* The preview is WYSIWYG or it is decoration: it draws the applicant's own
   `.milestone` band and `.quote` rows (components above), so the only rules here
   are the two lines that belong to the STAFF reading of it — the note that says
   what the band is, and the net line that says who ends up with the money. */
.payment-quote__note {
  color: var(--ink-faint);
  font-size: 0.8125rem;
  line-height: 1.5;
}
.payment-quote__band { margin-top: 0.75rem; }
.payment-quote__net {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-top: 1rem;
  color: var(--ink-soft);
  font-size: 0.8125rem;
}
.payment-quote__net strong { color: var(--ink); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.payment-quote__hint {
  display: block;
  margin-top: 0.5rem;
  color: var(--ink-faint);
  font-size: 0.75rem;
  line-height: 1.5;
}
.payment-quote__description {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--ink-soft);
  font-size: 0.8125rem;
  line-height: 1.6;
}
.payment-quote__description p + p { margin-top: 0.5rem; }
.payment-quote__description a { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
.payment-quote__empty { margin-top: 1.5rem; color: var(--ink-soft); }
.payment-quote__empty-title { font-size: 0.9375rem; }
.payment-quote__empty .field-error { margin-top: 0.5rem; }

.payment-ledger { display: grid; gap: 1rem; min-width: 0; }
.payment-ledger__env { margin-left: 0.375rem; }
.payment-ledger__sandbox-note { margin-top: -0.5rem; font-size: 0.75rem; color: var(--ink-faint); }
.payment-ledger__title { font-size: 1.25rem; }
.payment-ledger__facets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  align-items: center;
  padding: 0.25rem;
  border-bottom: 1px solid var(--border);
}
.payment-ledger__facet {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.625rem;
  border-radius: var(--r-sm);
  color: var(--ink-soft);
  font-size: 0.8125rem;
  text-decoration: none;
}
.payment-ledger__facet:hover,
.payment-ledger__facet.is-current { background: var(--brand-tint); color: var(--brand); }
.payment-ledger__count { font-family: var(--font-mono); font-size: 0.6875rem; }
.payment-ledger__totals {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--border);
}
.payment-ledger__totals > div {
  display: grid;
  gap: 0.25rem;
  padding: 0.875rem 1rem;
  background: var(--surface);
}
.payment-ledger__totals span { color: var(--ink-faint); font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.payment-ledger__totals strong { color: var(--ink-heading); font-family: var(--font-mono); font-size: 1rem; font-variant-numeric: tabular-nums; }
.payment-ledger__table-wrap { min-width: 0; background: var(--surface); }
/* Eight columns of short values. 56rem is what they need to stay readable and
   it is narrow enough that the whole row — including the refund control — fits
   the console at 1280px, so the scroller is the phone's affordance rather than
   everybody's. */
.payment-ledger__table { min-width: 48rem; }
.payment-ledger__table .modern-table,
.payment-ledger__table td,
.payment-ledger__table th { font-variant-numeric: tabular-nums; }
.payment-ledger__when { white-space: nowrap; color: var(--ink-soft); font-size: 0.75rem; }
/* A floor as well as a ceiling: the table scrolls inside `.table-scroll`, so
   there is no reason for a name to break mid-word ("Hannah Lindqvis / t") when
   the column can simply be wider than the phone. */
.payment-ledger__applicant {
  display: block;
  min-width: 8.5rem;
  max-width: 13rem;
  overflow-wrap: anywhere;
  font-weight: 500;
}
.payment-ledger__table small { display: block; margin-top: 0.125rem; color: var(--ink-faint); font-size: 0.75rem; overflow-wrap: anywhere; }
.payment-ledger__amount { text-align: right !important; white-space: nowrap; }
.payment-ledger__card { white-space: nowrap; color: var(--ink-soft); }
/* The refund disclosure lives in the last column. Closed it is a small button;
   open it needs room for a sentence and a reason field, so the cell is allowed
   to grow and the table (already `min-width`) scrolls inside `.table-scroll`
   rather than the open form being squeezed into a 6rem column. */
.payment-ledger__table .paycard__refund { position: relative; margin-top: 0; }
/* Floated over the rows rather than laid out in the cell: an 17rem form inside
   the narrow actions column re-flows every other column the moment somebody
   opens it, and a ledger that rearranges itself under the pointer is a ledger
   you refund the wrong row from. Anchored to the cell, clipped (and scrolled)
   by `.table-scroll` like everything else in the table. */
.payment-ledger__table .paycard__reason {
  position: absolute;
  top: calc(100% + 0.375rem);
  right: 0;
  z-index: 20;
  width: 17rem;
  margin-top: 0;
  padding: 0.875rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: 0 6px 20px rgba(1, 33, 75, 0.12);
  /* The cell it hangs from keeps its values on one line; the sentence inside
     this panel must not, and neither does it inherit the column's alignment. */
  white-space: normal;
  text-align: left;
}
.payment-ledger__table summary.btn { padding: 0.4rem 0.625rem; font-size: 0.75rem; }
.payment-ledger__pager { display: flex; align-items: center; justify-content: flex-end; gap: 0.75rem; }
.payment-ledger__page { color: var(--ink-soft); font-family: var(--font-mono); font-size: 0.75rem; }

@media (max-width: 899px) {
  .payments-builder-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 639px) {
  .payment-ledger__totals { grid-template-columns: minmax(0, 1fr); }
  .payment-ledger__totals > div { grid-template-columns: 1fr auto; align-items: baseline; }
  .payment-ledger__totals strong { text-align: right; }
  .payment-ledger__pager { justify-content: space-between; }
}

/* ─── Deleting an application ──────────────────────────────────────────────
   The console's ordinary dialog doing its rarest job (plan 2026-09-25 D5). Red
   is kept to edges — the record strip, the "Deleted" ledger's rule — and to
   the one filled control, the submit; everything else stays the console's own
   quiet vocabulary, so the only solid red thing on screen is the thing that acts.

   `.purge` is the memorable part: the plan as two short ledgers side by side,
   what is deleted against what is kept, each line a count and what it counts.
   Each line is one run of text ("2 documents") so it reads the same aloud as
   it does on screen; tabular figures keep a column of counts steady. */
.notice--danger {
  background: var(--danger-soft);
  border-color: #EFCBC9;
  border-left-color: var(--danger);
}
.notice--danger .notice__icon { color: var(--danger); }
.notice--danger .notice__title,
.notice--danger .notice__body { color: #6E1512; }
.notice--danger .notice__body { display: grid; gap: 0.25rem; }

.modal--danger .modal__head { border-bottom-color: #EFCBC9; }
.purge__record { border-left-color: var(--danger); }
.purge__record .record { font-weight: 600; color: var(--ink-heading); }

.purge {
  display: grid;
  gap: 0.75rem;
}
@media (min-width: 560px) {
  .purge { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
}
.purge__group {
  padding: 0.125rem 0 0.125rem 0.875rem;
  border-left: 2px solid var(--border-strong);
}
.purge__group--gone { border-left-color: var(--danger); }
.purge__heading {
  font-family: var(--font-heading);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-heading);
}
.purge__group--gone .purge__heading { color: var(--danger-ink); }
.purge__list {
  display: grid;
  gap: 0.3125rem;
  margin: 0.4375rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.purge__size { font-size: 0.75rem; color: var(--ink-faint); white-space: nowrap; }

/* The launcher at the foot of the detail page: one sentence and one control on
   a line, wrapping under each other on a phone. */
.danger-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding: 1.125rem 1.25rem;
}
.danger-strip__body {
  margin-top: 0.25rem;
  max-width: 38rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.payment-ledger__deleted {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--ink-faint);
}

/* ════════════════════════════════════════════════════════════════════════════
   PrintOut (builder tab, the field-matching page, the submission's Print card)

   Nearly everything these pages draw is borrowed — cards, switches, the
   `.modern-table` rhythm, `.bld-field`, `.bld-check`, `.chip`, `.row-sub`. What
   is here is only the layout those do not already have: a card head, a ruled
   list of PDFs with their tools on the right, and a table whose last column
   holds a control (and sometimes a second one under it) rather than a value.
   ════════════════════════════════════════════════════════════════════════════ */

.printout-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.printout-head .eyebrow { margin-bottom: 0.25rem; }
/* `.field-hint` is styled for a <p> under a control. Inside a switch's label it
   is a <span>, and left inline it runs on from the label's own words. */
.printout-settings .switch__label .field-hint { display: block; }
/* A standing sentence about the list under it, quieter than a `.notice`: the
   PDFs are not broken, they are just not switched on yet. */
.printout-note { font-size: 0.8125rem; line-height: 1.5; color: var(--ink-faint); }

/* One rule per PDF rather than a card each — they already sit inside one. */
.printout-list { list-style: none; margin: 0; padding: 0; display: grid; }
.printout-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.625rem 1rem;
  padding: 0.875rem 0;
  border-top: 1px solid var(--divider);
}
.printout-item__text { flex: 1 1 16rem; min-width: 0; font-size: 0.9375rem; overflow-wrap: anywhere; }
.printout-item__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.875rem; }
.printout-item__actions .bld-tools { margin-top: 0; }

/* The field-matching page: a head, the name, then the sheet of fields. */
/* Both are grids of one column, and that column is `minmax(0, 1fr)` on purpose:
   a grid track is `auto` by default, which never shrinks below its content, so
   the table's `min-width` below widened the whole page on a phone (754px at
   390) instead of scrolling inside its own `.table-scroll`. */
.printout-page { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; max-width: 78rem; }
.printout-map { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
/* The sheet is a `.card--flush`, so its heading brings its own gutter — the
   table's 1rem, so the heading and the first column share a left edge. */
.printout-map__head { padding: 1.25rem 1rem 1rem; border-bottom: 1px solid var(--divider); }

/* Below this the control column is too narrow to read an option in, so the box
   scrolls instead (`.table-scroll`). Cells align to the top because the last
   one grows — a fixed-text input or a row of checkboxes — and a field's name
   should stay beside its select, not drift to the middle of that. */
.printout-table { min-width: 46rem; }
.printout-table tbody td,
.printout-table tbody th { padding: 0.75rem 1rem; vertical-align: top; }
.printout-table__no {
  width: 3.5rem;
  padding-top: 1.125rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--ink-faint);
}
/* A row header is a label, not a caption: `<th>` centres and bolds by default. */
.printout-table__field {
  width: 34%;
  text-align: left;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.printout-table__source { min-width: 18rem; }
.printout-table .field-select,
.printout-table .field-input { font-size: 0.875rem; padding-top: 0.4375rem; padding-bottom: 0.4375rem; }
/* The companion under a select: the fixed text, or the answers that tick a box.
   The margin is on the content, so an empty options slot takes no room. */
.printout-fixed,
.printout-options > * { margin-top: 0.5rem; }
/* A multi-page PDF's rows are grouped under the page they are on. */
.printout-table .printout-table__page th {
  padding: 0.5rem 1rem;
  background: var(--surface-2);
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* The submission's Print card: one download per line. */
.printout-links {
  list-style: none;
  margin: 0.625rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
  font-size: 0.875rem;
  overflow-wrap: anywhere;
}
/* Under a PDF's link: the answers that PDF has no room for. `--warning-ink`, not
   `--warning`: this is small text, and only the ink passes AA at this size. */
.printout-links__note { margin-top: 0.125rem; font-size: 0.75rem; line-height: 1.5; color: var(--warning-ink); }
/* ════════════════════════ end of PrintOut ════════════════════════ */

/* ─── Payments: priced questions ─────────────────────────────────────────────
   The part of a fee that depends on the answers (`_payment_items.html`). Each
   priced question is a row of three things: what it is, its price list, and
   the two things that can be done to it.

   The price list is the one drawn element here: answer, dotted leader, price —
   the way a printed price sheet reads, and the reason a list of six options
   can be checked against the office's own flyer at a glance. The leader is a
   border on a flexible spacer rather than a row of full stops, so it is not
   read aloud and does not wrap. Amounts are `.record` (mono, tabular) like
   every other sum of money in the console. */
.price-sheet { display: grid; gap: 1rem; }
.price-sheet__head { display: grid; gap: 0.25rem; }
.price-sheet__lede,
.price-sheet__empty {
  max-width: 44rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
  line-height: 1.5;
}
.price-sheet__list {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--divider);
}
.price-item {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) minmax(14rem, 1.2fr) auto;
  gap: 0.5rem 2rem;
  align-items: start;
  padding: 1rem 0;
  border-bottom: 1px solid var(--divider);
}
.price-item__what { min-width: 0; display: grid; gap: 0.1875rem; }
.price-item__name {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-heading);
  overflow-wrap: anywhere;
}
.price-item__question,
.price-item__how { font-size: 0.8125rem; line-height: 1.45; color: var(--ink-soft); }
.price-item__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: flex-end; }
.price-item__actions .btn { padding: 0.4rem 0.625rem; font-size: 0.75rem; }

.price-list { display: grid; gap: 0.3125rem; margin: 0; min-width: 0; }
.price-list__row {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--ink);
}
.price-list__row dt { min-width: 0; overflow-wrap: anywhere; }
.price-list__row::before {
  content: "";
  order: 1;
  flex: 1 1 1.5rem;
  min-width: 1.5rem;
  border-bottom: 1px dotted var(--border-field);
  transform: translateY(-0.25em);
}
.price-list__row dd { order: 2; flex: none; margin: 0; color: var(--ink-heading); }

.price-sheet__add {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.price-sheet__add .bld-field { flex: 1 1 18rem; max-width: 30rem; }

.price-editor {
  display: grid;
  gap: 0.875rem;
  max-width: 36rem;
  padding: 1rem 1.125rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-lg);
  background: var(--bg);
}
.price-editor__title {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-heading);
  overflow-wrap: anywhere;
}
.price-editor__note { font-size: 0.8125rem; line-height: 1.45; color: var(--warning-ink); }
.price-editor__options { display: grid; gap: 0.5rem; }
.price-editor__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 9.5rem;
  gap: 0.25rem 1rem;
  align-items: center;
}
.price-editor__row label { font-size: 0.875rem; color: var(--ink); overflow-wrap: anywhere; }
.price-editor__row .field-error { grid-column: 1 / -1; }
.price-editor__unit { max-width: 12rem; }

@media (max-width: 899px) {
  .price-item { grid-template-columns: minmax(0, 1fr); }
  .price-item__actions { justify-content: flex-start; }
}
@media (max-width: 479px) {
  .price-editor__row { grid-template-columns: minmax(0, 1fr); }
}

/* The same price list on the application's payment card: what was charged for. */
.paycard__lines { margin: 0.625rem 0 0.25rem; }

/* ════════════════════════════════════════════════════════════════════════════
   ─── Prerequisites ─── (plan 2026-10-24-prerequisites: the builder tab, the
   application's card, the queue's two columns)

   Built from what the Documents and Checklist surfaces already say — the
   `.docs-*` sheet, chips, quick add and `.switch` on the builder tab; `.card`,
   `.modern-table`, `.pill` and the checklist card's action row on the
   application — and what follows is only what none of those could say: the GPA
   panel and the grade-scale grid on the tab, the big GPA figure, the flags and
   the course grid with its inline correction editor on the card, and the GPA
   cell in the queue. Nothing here introduces a colour: every state is a word,
   and the tint is the second signal (WCAG 1.4.1).
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── Builder: the GPA panel ─────────────────────────────────────────────────
   One bordered sheet split in two: the minimum GPA, the two "also ask for"
   questions and the worked example on the left; the grade scale on the right.
   It wraps rather than squeezing: below ~46rem the scale drops under. */
.bld-sheet--wide .prq-panel { border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface); overflow: hidden; }
.bld-sheet--wide .prq-panel__title { padding: 1rem 1.25rem 0; font-size: 1rem; }
.bld-sheet--wide .prq-panel__cols { display: flex; flex-wrap: wrap; }
.bld-sheet--wide .prq-panel__side { flex: 1 1 18.75rem; min-width: 0; display: flex; flex-direction: column; gap: 1.125rem; padding: 1rem 1.25rem 1.25rem; }
.bld-sheet--wide .prq-panel__main { flex: 999 1 27.5rem; min-width: 0; padding: 1rem 1.25rem 1.25rem; border-left: 1px solid var(--divider); }
.bld-sheet--wide .prq-h3 { font-size: 1rem; }
.bld-sheet--wide .prq-courses-head { margin-top: 0.75rem; }
.bld-sheet--wide .prq-mono { font-family: var(--font-mono); font-size: 0.875rem; }
.bld-sheet--wide .prq-code { max-width: 13.75rem; }

.bld-sheet--wide .prq-settings { gap: 1.125rem; }
.bld-sheet--wide .prq-gpa-input { display: flex; align-items: center; gap: 0.625rem; }
.bld-sheet--wide .prq-gpa-input .field-input {
  width: 6.875rem; font-family: var(--font-mono); font-size: 1.125rem; font-weight: 500; color: var(--ink-heading);
}
.bld-sheet--wide .prq-gpa-input__out { font-size: 0.875rem; color: var(--ink-soft); white-space: nowrap; }
.bld-sheet--wide .prq-ask { border: 0; margin: 0; padding: 0; min-width: 0; }
.bld-sheet--wide .prq-ask > legend { padding: 0; margin-bottom: 0.375rem; }
.bld-sheet--wide .prq-ask__grid { display: grid; grid-template-columns: minmax(0, 1fr) 9.375rem; gap: 0.5rem 0.75rem; align-items: center; }
.bld-sheet--wide .prq-ask__grid label { font-size: 0.875rem; color: var(--ink); }
.bld-sheet--wide .prq-ask__grid .field-select { padding-top: 0.5rem; padding-bottom: 0.5rem; font-size: 0.875rem; }
.bld-sheet--wide .prq-settings__foot { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
.bld-sheet--wide .prq-settings__saved { font-size: 0.8125rem; color: var(--ink-soft); }

/* How the GPA is figured: a quiet note with the worked example in mono, because
   the example is arithmetic someone checks digit by digit. */
.bld-sheet--wide .prq-how { padding: 0.75rem 0.875rem; border-radius: var(--r-md); background: var(--bg); font-size: 0.8125rem; color: var(--ink); display: grid; gap: 0.375rem; }
.bld-sheet--wide .prq-how__example { font-family: var(--font-mono); font-size: 0.78125rem; color: var(--ink-heading); overflow-wrap: anywhere; }

/* ─── Builder: the grade scale ───────────────────────────────────────────────
   A ruled grid of name | points | counts | tools, the In progress row set on a
   fainter ground with a lock where the remove button would be. On a phone the
   counts box and the tools drop to a second line under the name and points. */
.bld-sheet--wide .prq-scale-form { gap: 0.625rem; }
.bld-sheet--wide .prq-scale-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.625rem; }
.bld-sheet--wide .prq-scale-head .bld-label { margin: 0; }
.bld-sheet--wide .prq-scale-head__aside { font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .prq-scale { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--surface); }
.bld-sheet--wide .prq-scale__row {
  display: grid; grid-template-columns: minmax(0, 1.3fr) 6.875rem minmax(0, 1.2fr) 6.5rem;
  gap: 0.375rem 0.625rem; align-items: center;
  padding: 0.5rem 0.625rem 0.5rem 0.75rem; border-top: 1px solid var(--divider); background: var(--surface);
}
.bld-sheet--wide .prq-scale__row:first-child { border-top: 0; }
.bld-sheet--wide .prq-scale__row--head { padding-top: 0.5625rem; padding-bottom: 0.5625rem; background: var(--bg); font-size: 0.75rem; font-weight: 600; color: var(--ink-soft); }
.bld-sheet--wide .prq-scale__row.is-in-progress { background: color-mix(in srgb, var(--bg) 40%, var(--surface)); }
.bld-sheet--wide .prq-scale__row .field-input { padding: 0.375rem 0.625rem; font-size: 0.875rem; background: var(--surface); }
.bld-sheet--wide .prq-scale__row .field-input:disabled { background: var(--bg); border-color: var(--border); color: var(--ink-soft); }
.bld-sheet--wide .prq-scale__pts { font-family: var(--font-mono); text-align: right; }
.bld-sheet--wide .prq-scale__none { padding-right: 0.625rem; color: var(--ink-soft); }
.bld-sheet--wide .prq-counts { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; color: var(--ink); cursor: pointer; }
.bld-sheet--wide .prq-counts input { width: 1.125rem; height: 1.125rem; margin: 0; accent-color: var(--brand); flex: none; }
.bld-sheet--wide .prq-counts--never { color: var(--ink-soft); cursor: default; }
.bld-sheet--wide .prq-scale__tools { display: flex; align-items: center; justify-content: flex-end; gap: 0.125rem; }
.bld-sheet--wide .prq-scale__tools svg { width: 0.9375rem; height: 0.9375rem; }
.bld-sheet--wide .prq-lock { cursor: help; }
.bld-sheet--wide .prq-scale__error { grid-column: 1 / -1; margin: 0; }
.bld-sheet--wide .prq-scale__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  padding: 0.625rem 0.75rem; border-top: 1px dashed var(--border-strong); background: var(--surface);
}
.bld-sheet--wide .prq-scale__foot svg { width: 0.875rem; height: 0.875rem; }
.bld-sheet--wide .prq-scale__note { margin-left: auto; font-size: 0.8125rem; color: var(--ink-soft); }

/* ─── Builder: the course sheet ──────────────────────────────────────────────
   The `.docs-*` rows; the course code chip is a record, so it is mono. The
   quick add takes a name AND a code, so its line has one more column. */
.bld-sheet--wide .prq-course-list { list-style: none; margin: 0; padding: 0; }
.bld-sheet--wide .prq-chip-code { font-family: var(--font-mono); font-size: 0.6875rem; color: var(--ink-heading); background: var(--bg); border-color: var(--divider); }
.bld-sheet--wide .prq-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.875rem; }
.bld-sheet--wide .prq-add { grid-template-columns: 2.2rem minmax(0, 3fr) minmax(8rem, 1fr) auto; }
.bld-sheet--wide .prq-add-error { margin: 0; padding: 0.625rem 1rem 0; border-top: 1px dashed var(--border-field); }
.bld-sheet--wide .prq-add-error + .docs-add { border-top: 0; }
.bld-sheet--wide .prq-checks__problems {
  margin: 0; padding: 0.75rem 0.875rem; list-style: none; display: grid; gap: 0.25rem;
  background: var(--danger-soft); color: var(--danger-ink); font-size: 0.875rem;
}

/* A prerequisite any one of several courses meets (2026-10-26, board "Main"):
   the closed row lists its courses under the title with "or" in the brand blue,
   and the editor stacks one row per course, joined by a dashed "or" rule. The
   rule is the one place the OR is drawn; everything else is the sheet as it was. */
.bld-sheet--wide .prq-alts { display: flex; flex-direction: column; gap: 0.25rem; margin: 0.125rem 0 0; padding: 0; list-style: none; }
.bld-sheet--wide .prq-alts li { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--ink); }
.bld-sheet--wide .prq-alts__or { min-width: 1.375rem; font-size: 0.75rem; font-weight: 600; color: var(--brand); }
.bld-sheet--wide .prq-alts__cr { font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .docs-row.is-open .prq-alts { display: none; }
.bld-sheet--wide .docs-sum__title h3.prq-untitled { font-style: italic; font-weight: 500; color: var(--danger-ink); }
.bld-sheet--wide .prq-alts-ed { min-width: 0; margin: 0; padding: 0; border: 0; }
.bld-sheet--wide .prq-alts-ed__legend {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem;
  width: 100%; margin-bottom: 0.5rem; padding: 0;
}
.bld-sheet--wide .prq-alts-ed__legend .bld-label { margin: 0; }
.bld-sheet--wide .prq-alts-ed__note { font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .prq-alts-ed__error { margin: 0; padding: 0 0.75rem 0.625rem; }
.bld-sheet--wide .prq-alts-box { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.bld-sheet--wide .prq-alt { padding: 0.75rem 0.75rem 0.875rem; }
.bld-sheet--wide .prq-alt .bld-label { font-size: 0.75rem; }
.bld-sheet--wide .prq-alt .field-hint,
.bld-sheet--wide .prq-alt .field-error { margin-top: 0.375rem; }
.bld-sheet--wide .prq-alt__grid {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) 6.5rem auto; gap: 0.625rem; align-items: start;
}
.bld-sheet--wide .prq-alt__grid .field-input { padding-top: 0.4375rem; padding-bottom: 0.4375rem; font-size: 0.875rem; }
.bld-sheet--wide .prq-alt__tools { display: flex; gap: 0.125rem; padding-top: 1.625rem; }
.bld-sheet--wide .prq-alt__tools .icon-btn { width: 2rem; height: 2rem; }
.bld-sheet--wide .prq-alt__tools svg { width: 0.9375rem; height: 0.9375rem; }
.bld-sheet--wide .prq-alt-foot .btn { white-space: nowrap; }
.bld-sheet--wide .prq-alt-foot .btn svg { flex: none; width: 0.875rem; height: 0.875rem; }
/* The words column carries the course rows, so the settings column is held to
   the board's width (16.25rem) instead of a third of the editor. */
.bld-sheet--wide .prq-courses .docs-ed__form { grid-template-columns: minmax(0, 1fr) 16.25rem; }
.bld-sheet--wide .prq-or { display: flex; align-items: center; gap: 0.625rem; padding: 0 0.75rem; font-size: 0.75rem; font-weight: 600; color: var(--brand); }
.bld-sheet--wide .prq-or::before,
.bld-sheet--wide .prq-or::after { content: ""; flex: 1 1 auto; border-top: 1px dashed var(--brand-soft); }
.bld-sheet--wide .prq-or span { padding: 1px 10px; border: 1px solid var(--brand-soft); border-radius: var(--r-full); background: var(--brand-tint); }
.bld-sheet--wide .prq-alt-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.625rem;
  padding: 0.625rem 0.75rem; border-top: 1px dashed var(--border-strong);
}
.bld-sheet--wide .prq-alt-foot .field-hint { margin: 0; }

@media (max-width: 1023px) {
  .bld-sheet--wide .prq-panel__main { border-left: 0; border-top: 1px solid var(--divider); }
}
@media (max-width: 639px) {
  .bld-sheet--wide .prq-scale__row { grid-template-columns: minmax(0, 1fr) 5.5rem; }
  .bld-sheet--wide .prq-scale__row--head { display: none; }
  .bld-sheet--wide .prq-scale__row--head + .prq-scale__row { border-top: 0; }
  .bld-sheet--wide .prq-scale__note { margin-left: 0; flex-basis: 100%; }
  .bld-sheet--wide .prq-pair { grid-template-columns: minmax(0, 1fr); }
  .bld-sheet--wide .prq-add { grid-template-columns: minmax(0, 1fr); }
  .bld-sheet--wide .prq-ask__grid { grid-template-columns: minmax(0, 1fr); }
  .bld-sheet--wide .prq-alt__grid { grid-template-columns: minmax(0, 1fr); }
  .bld-sheet--wide .prq-alt__tools { padding-top: 0; }
  .bld-sheet--wide .prq-courses .docs-ed__form { grid-template-columns: minmax(0, 1fr); }
}

/* ─── The application's card ─────────────────────────────────────────────────
   The GPA is the one large number on the page — Space Grotesk at 2.5rem, the
   size of nothing else in the console — because it is the thing a reviewer
   came to read; the minimum beside it is smaller, and the verdict is a pill
   that says Meets or Below in words. */
.prq-card__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.625rem; }
.prq-card__lede { margin-top: 0.25rem; font-size: 0.8125rem; color: var(--ink-soft); }
.prq-gpa {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem 2.25rem;
  margin-top: 1rem; padding: 1rem 1.125rem; border-radius: 10px; background: var(--surface);
}
.prq-gpa__num { font-family: var(--font-heading); font-size: 2.5rem; font-weight: 600; line-height: 1; letter-spacing: -0.01em; color: var(--ink-heading); font-variant-numeric: tabular-nums; }
.prq-gpa__min { font-family: var(--font-heading); font-size: 1.375rem; font-weight: 600; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.prq-gpa__min--none { color: var(--ink-soft); }
.prq-gpa__cap { margin-top: 0.375rem; font-size: 0.8125rem; color: var(--ink-soft); }
.prq-gpa__verdict { padding-bottom: 0.25rem; }
.prq-gpa__verdict .pill { font-size: 0.8125rem; padding: 0.375rem 0.75rem; }
.prq-gpa__basis { flex: 1 1 13.75rem; padding-bottom: 0.25rem; font-size: 0.8125rem; color: var(--ink-soft); }
.prq-flags { list-style: none; margin: 0.75rem 0 0; padding: 0; display: grid; gap: 0.375rem; }
.prq-flags li { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.875rem; color: var(--ink); overflow-wrap: anywhere; }
.prq-flags svg { width: 1rem; height: 1rem; flex: none; margin-top: 0.125rem; color: var(--danger-ink); }

/* The course grid: a real table (the correction editor is a row of its own,
   one cell wide across all of them), scrolling inside its box on a phone. */
.prq-grid-box { margin-top: 1rem; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.prq-grid { min-width: 53.75rem; }
.prq-grid thead th { padding: 0.5625rem 0.875rem; background: var(--bg); }
.prq-grid tbody td,
.prq-grid tbody th { padding: 0.6875rem 0.875rem; font-size: 0.875rem; font-weight: 400; }
.prq-grid tbody tr.is-flagged { background: color-mix(in srgb, var(--danger-soft) 35%, var(--surface)); }
.prq-grid tbody tr.is-editing { background: var(--brand-tint); box-shadow: inset 3px 0 0 var(--brand); }
/* Widths are hints (the layout stays auto, so a form that asks for neither term
   nor school simply has two fewer columns): the course gets the room, the
   record-shaped columns the width of what they hold. */
.prq-grid__col-course { width: 26%; }
.prq-grid__col-credits { width: 4rem; }
.prq-grid__col-grade { width: 8rem; }
.prq-grid__col-term { width: 7rem; }
.prq-grid__col-minimum { width: 8.5rem; }
.prq-grid__col-action { width: 7.5rem; }
.prq-grid__term { white-space: nowrap; }
.prq-grid__code { font-family: var(--font-mono); font-size: 0.78125rem; color: var(--ink-heading); }
.prq-grid__name { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.prq-grid__req { margin-left: 0.375rem; font-size: 0.6875rem; font-weight: 600; color: var(--ink-soft); }
.prq-grid__grade { font-family: var(--font-heading); font-size: 1rem; font-weight: 600; color: var(--ink-heading); }
.prq-grid__none { color: var(--ink-soft); }
.prq-grid__was { display: block; font-size: 0.75rem; color: var(--ink-soft); }
.prq-grid__school { overflow-wrap: break-word; }
.prq-grid__action { text-align: right; white-space: nowrap; }
.prq-grid__btn { padding: 0.4375rem 0.75rem; font-size: 0.8125rem; }

.prq-grid tbody tr.prq-edit-row td {
  padding: 0.75rem 0.875rem 0.875rem; background: var(--brand-tint);
  box-shadow: inset 3px 0 0 var(--brand); border-top: 1px dashed var(--border-strong);
}
.prq-edit { display: grid; gap: 0.75rem; }
.prq-edit__fields { display: grid; grid-template-columns: 9.375rem 10rem minmax(0, 1fr); gap: 0.75rem; }
.prq-edit__note { grid-column: 1 / -1; }
.prq-edit .bld-label { font-size: 0.75rem; }
.prq-edit .prq-opt { font-weight: 400; color: var(--ink-soft); }
.prq-edit .field-input,
.prq-edit .field-select { padding-top: 0.4375rem; padding-bottom: 0.4375rem; font-size: 0.875rem; background: var(--surface); }
.prq-edit .field-error { margin: 0; }
.prq-edit__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
.prq-edit__hint { font-size: 0.8125rem; color: var(--ink-soft); }
.prq-edit__buttons { display: flex; gap: 0.5rem; }

/* 2026-10-26 (board "StaffDetail"): a prerequisite met by any one of several
   courses names the course taken under its title — or, until one is, the
   choices — and the Credits column says what the amount could have been. Its
   editor gains Course taken and Credits, so it wraps instead of the fixed
   three-column grid (a one-course, one-amount prerequisite keeps that grid). */
.prq-grid__took { display: block; margin-top: 2px; font-size: 0.8125rem; color: var(--ink); overflow-wrap: anywhere; }
.prq-grid__took-word { color: var(--ink-soft); }
.prq-grid__alts { display: block; margin-top: 2px; font-size: 0.8125rem; color: var(--ink-soft); }
.prq-grid__of { display: block; font-family: var(--font-sans); font-size: 0.75rem; color: var(--ink-soft); }
.prq-grid--choices .prq-grid__col-course { width: 31%; }
.prq-grid--choices .prq-grid__grade { white-space: nowrap; }
.prq-edit__fields--choice { display: flex; flex-wrap: wrap; }
.prq-edit__fields--choice > .bld-field { flex: 0 0 9.375rem; min-width: 0; }
.prq-edit__fields--choice > .prq-edit__course { flex: 2 1 17.5rem; }
.prq-edit__fields--choice > .prq-edit__credits { flex: 0 0 8.125rem; }
.prq-edit__fields--choice > .prq-edit__school { flex: 1 1 12.5rem; }
.prq-edit__fields--choice > .prq-edit__note { flex: 1 1 100%; }
.prq-edit__static { display: flex; align-items: center; min-height: 2.375rem; font-size: 0.875rem; color: var(--ink); }

/* The fact strip's GPA: the figure in mono beside its short verdict. */
.prq-fact { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.prq-fact .record { font-size: 0.9375rem; color: var(--ink-heading); }

@media (max-width: 719px) {
  .prq-edit__fields { grid-template-columns: minmax(0, 1fr); }
  .prq-edit__fields--choice > * { flex: 1 1 100% !important; }
  .prq-gpa { gap: 0.75rem 1.5rem; }
}

/* ─── The queue's GPA cell ───────────────────────────────────────────────────
   The figure in mono (it is what the sort orders by), its Meets/Below pill,
   then "1 in progress" and "1 below a course minimum" as worded marks. Two more
   columns, so the sheet's floor widens with them. */
.queue-table--prereq { min-width: 64rem; }
.prq-queue-gpa__line { display: inline-flex; align-items: center; gap: 0.375rem; white-space: nowrap; }
.prq-queue-gpa__num { font-size: 0.875rem; font-weight: 500; color: var(--ink-heading); }
.prq-queue-gpa__marks { display: flex; flex-wrap: wrap; gap: 0.125rem 0.625rem; margin-top: 0.25rem; }
.prq-queue-gpa__mark { display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.75rem; color: var(--ink-soft); white-space: nowrap; }
.prq-queue-gpa__mark--flag { color: var(--danger-ink); }
.prq-queue-gpa__mark svg { width: 0.875rem; height: 0.875rem; }
/* ════════════════════════ end of Prerequisites ════════════════════════ */

/* ════════════════════════════════════════════════════════════════════════════
   CONSOLE RAIL: FOLDED TO ICONS (2026-10-27)

   `staff_base.html` draws `.console--rail-collapsed` from the `forms_rail`
   cookie the toggle writes, so a folded rail is folded from the first paint.
   Desktop only: under a laptop the rail lies down above the content as before,
   and the toggle is not shown. Every selector here is new — the rules above for
   the open rail are untouched — and a label hidden by folding stays in the
   accessibility tree (opacity, not display), so every link keeps its name and
   shows it as a tooltip on hover and keyboard focus.
   ════════════════════════════════════════════════════════════════════════════ */
.console[data-rail-cookie-path] .console__rail { z-index: 40; }

.rail__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.25rem; }

.rail__toggle {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  margin-top: 0.125rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
}
.rail__toggle:hover { background: var(--surface); border-color: var(--border); color: var(--ink); }
.rail__toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.rail__toggle-chevron { transition: transform 160ms ease; transform-origin: 10.4px 10px; }

/* The toggle's label is a tooltip in both states; folded, every label is. */
.rail__toggle .rail__label,
.console--rail-collapsed .rail__link .rail__label,
.console--rail-collapsed .rail__signout .rail__label {
  position: absolute;
  left: calc(100% + 0.625rem);
  top: 50%;
  transform: translateY(-50%);
  z-index: 50;
  padding: 0.3125rem 0.5rem;
  border-radius: var(--r-sm);
  background: var(--navy);
  color: #FFFFFF;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
}
.rail__toggle:hover .rail__label,
.rail__toggle:focus-visible .rail__label,
.console--rail-collapsed .rail__link:hover .rail__label,
.console--rail-collapsed .rail__link:focus-visible .rail__label,
.console--rail-collapsed .rail__signout:hover .rail__label,
.console--rail-collapsed .rail__signout:focus-visible .rail__label { opacity: 1; }

@media (min-width: 1024px) {
  .console--rail-collapsed { --rail-width: 4.25rem; }
  .console--rail-collapsed .console__rail { padding: 1rem 0.625rem; align-items: center; }
  .console--rail-collapsed .rail__top { flex-direction: column; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
  .console--rail-collapsed .rail__brand { display: block; padding: 0; }
  .console--rail-collapsed .rail__brand .brandmark__seal { width: 2.25rem; height: 2.25rem; }
  .console--rail-collapsed .rail__brand--logo .brandmark__seal { display: block; }
  .console--rail-collapsed .rail__logo { display: none; }
  .console--rail-collapsed .rail__identity {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .console--rail-collapsed .rail__toggle-chevron { transform: rotate(180deg); }
  .console--rail-collapsed .rail__nav { align-items: center; gap: 0.25rem; }
  .console--rail-collapsed .rail__link,
  .console--rail-collapsed .rail__signout {
    position: relative;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
  }
  .console--rail-collapsed .rail__link .rail__icon,
  .console--rail-collapsed .rail__signout .rail__icon { width: 1.25rem; height: 1.25rem; }
  .console--rail-collapsed .rail__group {
    width: 1.75rem; height: 1px; margin: 0.625rem 0; padding: 0;
    overflow: hidden; color: transparent; background: var(--border);
  }
  .console--rail-collapsed .rail__foot { align-items: center; width: 100%; }
  .console--rail-collapsed .rail__user { padding: 0 0 0.25rem; justify-content: center; }
}
@media (max-width: 1023px) {
  .rail__toggle { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   ONE APPLICATION — rendition C "Verify side by side" (2026-10-27)

   `submissions/detail/`. The page's own head (identity, decision, readiness
   strip) is inside the swapped body and sticks to the top of the window; the
   console's topbar is switched off for this page. What the applicant claimed
   (prerequisites, else the answers) sits beside a dark document dock; the rest
   of the page is rows of white cards on the tinted ground. Every selector is
   `sd-` and new, so no other page moves; inside `.sd` the pills drop their dot
   and the text links are underlined, as the design draws them.
   ════════════════════════════════════════════════════════════════════════════ */
.console__topbar--none { display: none; }
.console:has(.console__content--application) { background: var(--bg); }
.sd__body a:not(.btn):not(.sd-chip):not(.sd-reading__link):not(.sd-dock__pick-item):not(.sd-dock__tab) {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: #9DBFF2;
}
.sd__body a:not(.btn):not(.sd-chip):not(.sd-reading__link):not(.sd-dock__pick-item):not(.sd-dock__tab):hover {
  color: var(--brand-hover);
  text-decoration-color: currentColor;
}
.console__content--application {
  max-width: none;
  padding: 0;
  gap: 0;
  flex: 1 0 auto;
  background: var(--bg);
}

:root { --sd-head-h: 9.5rem; }
.sd { color: var(--ink); font-size: 0.875rem; line-height: 1.25rem; }
.sd .pill { font-size: 0.78125rem; line-height: 1.25rem; padding: 0.125rem 0.625rem; }
.sd .pill::before { display: none; }
.sd .pill-neutral { background: var(--divider); color: #4A5563; }
.sd .pill-brand { background: var(--brand-soft); color: #00449F; }
.sd .pill-warning { color: #8A4108; }
.sd .pill-danger { color: #A82C22; }
.sd .btn-link {
  font-size: 0.84375rem;
  font-weight: 500;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: #9DBFF2;
}
.sd .btn-link:hover { text-decoration-color: currentColor; }
.sd .btn { min-height: 2.25rem; justify-content: center; white-space: nowrap; }
.sd .btn-ghost { background: var(--surface); border-color: var(--border-strong); }
.sd .btn-ghost:hover { border-color: var(--border-field); background: #F8F9FB; }
.sd .btn:disabled { background: var(--bg); color: var(--ink-faint); border-color: var(--border); cursor: not-allowed; }
.sd-btn-sm { min-height: 1.875rem !important; padding: 0.4375rem 0.625rem; font-size: 0.8125rem; }
.sd-btn-dark { background: transparent; color: #FFFFFF; border: 1px solid rgba(255, 255, 255, 0.35); }
.sd-btn-dark:hover { background: rgba(255, 255, 255, 0.1); color: #FFFFFF; border-color: #FFFFFF; }
.sd-btn-danger { color: #B0322A !important; border-color: #E9A7A0 !important; }
.sd .sd-link-danger { color: #B0322A; text-decoration-color: #E9A7A0; }
.sd-muted { color: var(--ink-soft); }
.sd-label { display: block; font-size: 0.78125rem; line-height: 1.125rem; font-weight: 600; color: var(--ink); }
.sd-opt { font-weight: 400; color: var(--ink-soft); }
.sd-field { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.sd .field-select, .sd .field-input { background-color: var(--surface); font-size: 0.875rem; padding-top: 0.4375rem; padding-bottom: 0.4375rem; }
.sd .field-textarea { background: var(--surface); font-size: 0.875rem; }
.sd-file { font-size: 0.8125rem; color: var(--ink-soft); max-width: 100%; }
.sd .field-error { margin: 0; }

/* The head */
.sd-head {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 1rem 2.25rem 0;
}
.sd-head__row { display: flex; align-items: center; gap: 1.5rem; }
.sd-head__who { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.sd-head__crumb { margin: 0; font-size: 0.8125rem; color: var(--ink-soft); }
.sd-head__crumb a { color: var(--ink-soft); text-decoration: none; }
.sd-head__crumb a:hover { color: var(--brand); text-decoration: underline; }
.sd-head__line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.25rem 1rem; }
.sd-head__name {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 1.75rem;
  line-height: 2.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-heading);
}
.sd-head__ref { font-size: 0.875rem; font-weight: 500; color: var(--ink-heading); }
.sd-head__meta { font-size: 0.8125rem; color: var(--ink-soft); }
.sd-head__mail { font-size: 0.84375rem; color: var(--brand); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #9DBFF2; }
.sd-head__decide { margin-left: auto; display: flex; align-items: flex-end; gap: 0.625rem; flex: none; flex-wrap: wrap; justify-content: flex-end; }
.sd-decide { display: flex; flex-direction: column; gap: 0.25rem; }
.sd-decide__controls { display: flex; gap: 0.375rem; }
.sd-select { min-width: 11.25rem; width: auto; height: 2.25rem; }
.sd-select--state { min-width: 8.75rem; font-weight: 600; }
.sd-head__decided { flex-basis: 100%; margin: 0; text-align: right; font-size: 0.78125rem; color: var(--ink-soft); }

.sd-strip {
  display: flex;
  margin-top: 0.875rem;
  border-top: 1px solid var(--divider);
}
.sd-strip__cell {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.625rem 1rem;
  border-right: 1px solid var(--divider);
  color: var(--ink);
  text-decoration: none;
  flex: 1 1 0;
  min-width: 0;
}
.sd-strip__cell:last-child { border-right: 0; }
a.sd-strip__cell:hover { background: var(--bg); color: var(--ink); }
.sd-strip__label { font-size: 0.75rem; line-height: 1.125rem; color: var(--ink-soft); }
.sd-strip__fact { display: flex; align-items: center; flex-wrap: wrap; gap: 0.25rem 0.5rem; }
.sd-strip__value { font-weight: 600; font-variant-numeric: tabular-nums; }
.sd-strip__value.is-below { font-family: var(--font-heading); font-size: 0.9375rem; color: #B0322A; }
.sd-strip__cell:first-child .sd-strip__value { font-family: var(--font-heading); font-size: 0.9375rem; }
.sd .sd-strip__pill { font-size: 0.75rem; padding: 0 0.5rem; }
.sd-strip__note { font-size: 0.75rem; color: var(--ink-soft); }
.sd-strip__cell--links { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 1.125rem; padding-inline: 1.25rem 0.25rem; }
.sd-strip__cell--links a { font-weight: 500; color: var(--brand); }

/* The body */
.sd__body { padding: 1.5rem 2.25rem 4.5rem; display: flex; flex-direction: column; gap: 1.75rem; }
.sd__body > .flash { margin: 0; }

.sd-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.25rem 1.375rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}
.sd-card__head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem; }
.sd-card__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 1.1875rem;
  line-height: 1.625rem;
  font-weight: 600;
  color: var(--ink-heading);
}
.sd-card__tool { margin-left: auto; }
.sd-card__aside { font-size: 0.8125rem; color: var(--ink-soft); }
.sd-card__lede { margin: -0.375rem 0 0; font-size: 0.8125rem; color: var(--ink-soft); }
.sd-card__note { margin: 0; font-size: 0.78125rem; line-height: 1.2rem; color: var(--ink-soft); }
.sd-card__note a { color: var(--brand); }
.sd-card__foot { display: flex; gap: 1rem; flex-wrap: wrap; }
.sd-waived { margin: 0; padding: 0.625rem 0.875rem; border-radius: 10px; background: var(--bg); font-size: 0.8125rem; color: var(--ink-soft); }

.sd-table { width: 100%; border-collapse: collapse; font-size: 0.84375rem; line-height: 1.1875rem; }
.sd-table th {
  font-size: 0.75rem;
  line-height: 1.125rem;
  font-weight: 600;
  color: var(--ink-soft);
  text-align: left;
  padding: 0.4375rem 0.625rem;
  border-bottom: 1px solid var(--border);
  background: #F8F9FB;
}
.sd-table td,
.sd-table tbody th {
  padding: 0.625rem;
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
  text-align: left;
}
.sd-table tbody th { font-size: inherit; line-height: inherit; font-weight: 400; color: var(--ink); background: none; }

/* The split: claims beside the dock, one box */
.sd-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  min-height: 34rem;
}
.sd-split__claims { min-width: 0; }
.sd-split__claims > .sd-card { border: 0; border-radius: 16px 0 0 16px; padding: 1.375rem 1.5rem; gap: 0.875rem; background: transparent; }
.sd-split .sd-card__title { font-size: 1.3125rem; line-height: 1.75rem; }
/* When the answers are the claims they are long, so the two halves part: the
   answers card scrolls and the dock is a card of its own that stays in view. */
.sd-split--answers { gap: 1.25rem; align-items: start; background: transparent; border: 0; border-radius: 0; }
.sd-split--answers .sd-split__claims > .sd-card { border: 1px solid var(--border); border-radius: 16px; background: var(--surface); }
.sd-split--answers .sd-dock {
  position: sticky;
  top: calc(var(--sd-head-h) + 1rem);
  height: max(32rem, calc(100vh - var(--sd-head-h) - 2rem));
  border-radius: 16px;
  overflow: hidden;
}
.sd-split--answers .sd-dock__sticky { position: static; height: 100%; }

/* Prerequisites */
.sd-gpa {
  display: flex;
  align-items: center;
  gap: 1.375rem;
  padding: 0.875rem 1rem;
  border-radius: 12px;
  background: #F8F9FB;
  border: 1px solid var(--divider);
}
.sd-gpa--below { background: #FFF7F5; border-color: #F3D2CC; }
.sd-gpa__num { margin: 0; font-family: var(--font-heading); font-size: 2.5rem; line-height: 2.625rem; font-weight: 600; color: var(--ink-heading); font-variant-numeric: tabular-nums; }
.sd-gpa--below .sd-gpa__num { color: #B0322A; }
.sd-gpa__min { margin: 0; font-family: var(--font-heading); font-size: 1.5rem; line-height: 1.875rem; font-weight: 500; color: var(--ink-heading); font-variant-numeric: tabular-nums; }
.sd-gpa__min--none { color: var(--ink-soft); }
.sd-gpa__cap { margin: 0.25rem 0 0; font-size: 0.75rem; color: var(--ink-soft); }
.sd-gpa__say { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 0.375rem; }
.sd-gpa__basis { font-size: 0.78125rem; line-height: 1.125rem; color: var(--ink-soft); }
.sd-flags { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.84375rem; color: #9A4508; }
.sd-flags li { display: flex; gap: 0.5rem; }
.sd-flags svg { flex: none; width: 15px; height: 15px; margin-top: 3px; }
.sd-prq__grid tr.is-flagged { background: #FFF7F5; }
.sd-prq__grid tr.is-editing,
.sd-prq__edit-row { background: var(--brand-tint); }
.sd-prq__edit-row td { padding: 0.25rem 0.625rem 0.875rem; }
.sd-prq__code { font-size: 0.75rem; color: var(--ink-heading); }
.sd-prq__name { font-weight: 400; }
.sd-prq__sub, .sd-prq__under { display: block; font-size: 0.75rem; line-height: 1.125rem; color: var(--ink-soft); }
.sd-prq__grade { font-weight: 600; }
.sd-prq__grade.is-below { color: #B0322A; }
.sd-prq__none { color: var(--ink-soft); }
.sd-prq__action { text-align: right !important; white-space: nowrap; }
.sd-prq__grid th:nth-child(2) { width: 3.75rem; }
.sd-prq__grid th:nth-child(3) { width: 6.25rem; }
.sd-prq__grid th:nth-child(4) { width: 6.75rem; }
.sd-prq__grid th:nth-child(5) { width: 4.75rem; }
.sd-prq__edit { display: flex; flex-direction: column; gap: 0.625rem; }
.sd-prq__fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: 0.625rem; }
.sd-prq__wide { grid-column: span 2; }
.sd-prq__static { display: flex; align-items: center; min-height: 2.25rem; }
.sd-prq__foot { display: flex; align-items: center; gap: 0.625rem; }
.sd-prq__hint { flex: 1; margin: 0; font-size: 0.78125rem; color: var(--ink-soft); }

/* The dock */
.sd-dock {
  min-width: 0;
  background: #1E2A38;
  border-radius: 0 15px 15px 0;
  color: #C9D3E0;
  display: flex;
  flex-direction: column;
}
.sd-dock__sticky {
  position: sticky;
  top: var(--sd-head-h);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.sd-dock__sticky--open { height: max(32rem, calc(100vh - var(--sd-head-h) - 1.5rem)); }
.sd-dock__tabs {
  list-style: none;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.sd-dock__tab {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
  max-width: 13.5rem;
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  color: #C9D3E0;
  text-decoration: none;
  font-size: 0.8125rem;
  font-weight: 500;
}
.sd-dock__tab:hover { background: rgba(255, 255, 255, 0.07); color: #FFFFFF; }
.sd-dock__tab.is-open { background: #FFFFFF; color: var(--ink-heading); }
.sd-dock__tab-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sd-dock__tab-meta { font-size: 0.71875rem; font-weight: 400; opacity: 0.85; }
.sd-dock__bar { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.875rem; font-size: 0.78125rem; }
.sd-dock__file { color: #FFFFFF; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.sd-dock__size { white-space: nowrap; }
.sd-dock__spacer { flex: 1; }
.sd-dock__stage { flex: 1 1 auto; min-height: 0; padding: 0 0.875rem 0.875rem; }
.sd-dock__frame, .sd-dock__image {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 6px;
  background: #FFFFFF;
}
.sd-dock__image { object-fit: contain; background: #2A3949; }
.sd-dock__empty { padding: 3rem 1.5rem; text-align: center; }
.sd-dock__empty-title { margin: 0 0 0.5rem; color: #FFFFFF; font-weight: 600; }
.sd-dock__empty-body { margin: 0; font-size: 0.84375rem; }
.sd-dock__pick {
  align-self: center;
  width: calc(100% - 3rem);
  max-width: 31.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.375rem;
  padding: 4.5rem 0 2rem;
}
.sd-dock__intro { display: flex; flex-direction: column; align-items: center; gap: 0.625rem; text-align: center; }
.sd-dock__intro svg { width: 44px; height: 44px; color: #8DA2BC; }
.sd-dock__title { margin: 0; font-family: var(--font-heading); font-size: 1.1875rem; line-height: 1.625rem; font-weight: 600; color: #FFFFFF; }
.sd-dock__lede { margin: 0; max-width: 44ch; font-size: 0.84375rem; line-height: 1.25rem; color: #C9D3E0; }
.sd-dock__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.sd-dock__pick-item,
.sd-dock__pick-missing {
  display: flex;
  flex-direction: column;
  gap: 0.1875rem;
  padding: 0.75rem 1rem;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.04);
  color: #FFFFFF;
  text-decoration: none;
}
.sd-dock__pick-item:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.45); color: #FFFFFF; }
.sd-dock__pick-item:focus-visible { outline: 3px solid #8DC8E8; outline-offset: 2px; }
.sd-dock__pick-missing { border-style: dashed; background: transparent; color: #C9D3E0; }
.sd-dock__pick-name { font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; }
.sd-dock__pick-meta { font-size: 0.78125rem; line-height: 1.125rem; color: #C9D3E0; overflow-wrap: anywhere; }

/* Documents */
.sd-docs { display: flex; flex-direction: column; gap: 0.875rem; }
.sd-section-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem; }
.sd-section-head .sd-card__title { font-size: 1.3125rem; line-height: 1.75rem; }
.sd-section-head__count { font-size: 0.8125rem; color: var(--ink-soft); }
.sd-section-head__tools { margin-left: auto; display: flex; align-items: center; gap: 1.125rem; }
.sd-tiles { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr)); gap: 0.875rem; }
.sd-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.125rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  min-width: 0;
}
.sd-tile--wanted { border-color: #EDD5A6; background: #FFFBF3; }
.sd-tile__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem; }
.sd-tile__name { font-weight: 600; }
.sd-tile__kind { font-size: 0.75rem; color: var(--ink-soft); }
.sd-tile__kind .record { margin-left: 0.25rem; }
.sd-tile__line, .sd-tile__file { margin: 0; font-size: 0.8125rem; overflow-wrap: anywhere; }
.sd-tile__file a { color: var(--brand); }
.sd-tile__small { font-size: 0.75rem; line-height: 1.125rem; }
.sd-tile p.sd-muted { margin: 0; }
.sd-tile__tools { margin-top: auto; display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.875rem; }
.sd-tile__tools form { display: inline; }
.sd-replace > summary { list-style: none; cursor: pointer; color: var(--brand); }
.sd-replace > summary::-webkit-details-marker { display: none; }
.sd-replace[open] { flex-basis: 100%; }
.sd-replace__form { display: flex; flex-direction: column; align-items: flex-start; gap: 0.375rem; margin-top: 0.5rem; }
.sd-tile__upload { margin-top: auto; display: flex; flex-direction: column; gap: 0.375rem; }
.sd-tile__upload-row { display: flex; align-items: center; gap: 0.5rem; }
.sd-signers { padding: 1.125rem 1.25rem; gap: 0.875rem; }
.sd-signers__head { justify-content: flex-start; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.875rem; }
.sd-signers__head .sd-tile__name { font-size: 0.9375rem; }
.sd-signers__check { margin-left: auto; }
.sd-signers__sum { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 1rem; }
.sd-places { display: inline-flex; gap: 4px; }
.sd-places__slot { width: 34px; height: 8px; border-radius: 4px; border: 1px dashed var(--border-strong); }
.sd-places__slot.is-filed { background: var(--success); border: 0; }
.sd-places__slot.is-out { background: var(--warning); border: 0; }
.sd-places__slot.is-off { background: var(--border); border: 0; }
.sd-signers__table tr.is-off, .sd-signers__table tr.is-off th { color: var(--ink-faint); }
.sd-signers__mail { font-size: 0.75rem; margin-left: 0.25rem; }
.sd-signers__actions { text-align: right !important; white-space: nowrap; }
.sd-signers__actions > * + * { margin-left: 0.875rem; }
.sd-signers__actions form { display: inline; }
.sd-signers__table a { color: var(--brand); }
.sd-signers__file { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 0.75rem; padding-top: 0.25rem; }
.sd-signers__file .field-select { min-width: 16.25rem; }
.sd-signers__hint { flex: 1 1 18rem; margin: 0; }

/* An upload item that takes several files (2026-10-29, rendition "Forms
   multi-file documents"): the signer block's frame, a state line, a file table
   whose Replace opens as a small panel under its row, and the "places used"
   sentence once all ten are taken. */
.sd-files__tools { margin-left: auto; display: flex; gap: 0.5rem; align-items: center; }
.sd-files__tools form { margin: 0; }
.sd-files__state { margin: 0; font-size: 0.875rem; }
.sd-files__table td.sd-files__by { white-space: nowrap; }
.sd-files__table th a { font-weight: 600; }
.sd-files__replace { display: inline-block; position: relative; }
.sd-files__replace > summary { list-style: none; cursor: pointer; }
.sd-files__replace > summary::-webkit-details-marker { display: none; }
.sd-files__replace[open] > .sd-replace__form {
  position: absolute; right: 0; top: calc(100% + 0.375rem); z-index: 5;
  display: grid; gap: 0.5rem; width: 18rem; padding: 0.75rem;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  box-shadow: 0 8px 24px rgba(1, 33, 75, 0.12); text-align: left; white-space: normal;
}
.sd-files__full {
  margin: 0; padding: 0.75rem; border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg); font-size: 0.875rem;
}

/* Rows of cards */
.sd-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 1.5rem; align-items: start; }
.sd-row > :only-child { grid-column: 1 / -1; }
.sd-row--money { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.sd-row--record { grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr); }

/* Checklist */
.sd-ckl { list-style: none; margin: 0.25rem 0 0; padding: 0; }
.sd-ckl__item { display: grid; grid-template-columns: 1.5rem minmax(0, 1fr) auto; gap: 0.75rem; align-items: center; padding: 0.6875rem 0; border-top: 1px solid var(--divider); }
.sd-ckl__item form { display: flex; }
.sd-ckl__box { width: 22px; height: 22px; border-radius: 6px; border: 2px solid var(--border-strong); display: grid; place-items: center; }
.sd-ckl__box.is-required { border-color: var(--warning); }
.sd-ckl__box.is-done { border: 0; background: var(--success); color: #FFFFFF; }
.sd-ckl__box svg { width: 14px; height: 14px; }
.sd-ckl__body { display: flex; flex-direction: column; }
.sd-ckl__title { font-weight: 600; }
.sd-ckl__meta { font-size: 0.78125rem; color: var(--ink-soft); }

/* Score */
.sd-score__total { margin: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.5rem 0.875rem; }
.sd-score__num { font-family: var(--font-heading); font-size: 2rem; line-height: 2.25rem; font-weight: 600; color: var(--ink-heading); }
.sd-score__of { font-size: 0.8125rem; color: var(--ink-soft); }
.sd-score__rows { list-style: none; margin: 0; padding: 0; }
.sd-score__row { display: grid; grid-template-columns: minmax(0, 1fr) 9.375rem 3.5rem; gap: 0.75rem; align-items: center; padding: 0.4375rem 0; border-top: 1px solid var(--divider); font-size: 0.84375rem; }
.sd-score__crit .sd-muted { font-size: 0.75rem; }
.sd-score__bar { display: block; height: 8px; border-radius: 8px; background: var(--divider); overflow: hidden; }
.sd-score__bar > span { display: block; height: 100%; border-radius: 8px; background: var(--brand); }
.sd-score__pts { text-align: right; font-weight: 600; white-space: nowrap; }

/* Payment */
.sd-pay__body {
  display: grid;
  grid-template-columns: 12.5rem minmax(0, 1fr);
  grid-template-areas: "lead lines" "links lines";
  align-items: start;
  column-gap: 1.5rem;
  row-gap: 0.75rem;
}
.sd-pay__lead { grid-area: lead; display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.sd-pay__links { grid-area: links; display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.sd-pay__lines { grid-area: lines; }
.sd-pay__lead p { margin: 0; }
.sd-pay__amount { margin: 0; font-family: var(--font-heading); font-size: 1.875rem; line-height: 2.125rem; font-weight: 600; color: var(--ink-heading); }
.sd-pay__receipt { font-size: 0.84375rem; color: var(--brand); }
.sd-pay__id { font-size: 0.71875rem; }
.sd-pay__lines { font-size: 0.84375rem; }
.sd-pay__dl { margin: 0; }
.sd-pay__note { margin-top: 0.375rem; }
.sd-pay__line { display: flex; justify-content: space-between; gap: 0.75rem; padding: 0.4375rem 0; border-bottom: 1px solid var(--divider); }
.sd-pay__line dd { margin: 0; white-space: nowrap; }
.sd-pay__line--total { border-bottom: 0; font-weight: 600; }
.sd-reading__aside .sd-pay__body { grid-template-columns: minmax(0, 1fr); grid-template-areas: "lead" "lines" "links"; }
.sd-reading__aside .sd-pay__links { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--divider); }
.sd-reading__aside .sd-pay__links .paycard__refund { margin-left: auto; }
.sd-answer__price { margin-top: 0.375rem !important; }
.sd-answer { scroll-margin-top: calc(var(--sd-head-h) + 1rem); }

/* Print */
.sd-print__list { list-style: none; margin: 0; padding: 0; }
.sd-print__list li { padding: 0.5rem 0; border-top: 1px solid var(--divider); }
.sd-print__list a { color: var(--brand); }
.sd-print__cut { display: block; font-size: 0.78125rem; color: #9A4508; }

/* The long read: section list, answers, notes column */
.sd-reading { display: grid; grid-template-columns: 11.875rem minmax(0, 1fr) 22.5rem; gap: 1.75rem; align-items: start; }
.sd-reading__nav { position: sticky; top: calc(var(--sd-head-h) + 1rem); display: flex; flex-direction: column; gap: 0.125rem; padding-top: 3.25rem; }
.sd-reading__link { padding: 0.375rem 0.625rem; border-radius: 8px; font-size: 0.84375rem; color: var(--ink); text-decoration: none; }
.sd-reading__link:hover { background: var(--brand-tint); color: var(--brand); }
.sd-reading__aside { position: sticky; top: calc(var(--sd-head-h) + 1rem); display: flex; flex-direction: column; gap: 1.25rem; }

.sd-answers { padding-bottom: 0.875rem; }
.sd-answers__section { padding: 0.75rem 0 0.25rem; scroll-margin-top: calc(var(--sd-head-h) + 1rem); }
.sd-answers__title { margin: 0 0 0.375rem; font-family: var(--font-heading); font-size: 0.9375rem; line-height: 1.375rem; font-weight: 600; color: var(--ink-heading); }
.sd-answers__list { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.75rem; }
.sd-answer { padding: 0.625rem 0; border-bottom: 1px solid var(--divider); min-width: 0; }
.sd-answer--wide { grid-column: 1 / -1; }
.sd-answer dt { font-size: 0.78125rem; line-height: 1.125rem; color: var(--ink-soft); }
.sd-answer dd { margin: 0.125rem 0 0; }
.sd-answer__value { white-space: pre-line; max-width: 72ch; overflow-wrap: anywhere; }
.sd-answer__hidden { font-style: italic; color: var(--ink-faint); }
.sd-table--answer { margin-top: 0.25rem; border: 1px solid var(--divider); }
.sd-version { margin: 0; padding: 0.625rem 0.875rem; border-radius: 10px; background: var(--warning-soft); color: #6E3506; font-size: 0.84375rem; }
.sd-chips { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.sd-chip { display: inline-flex; align-items: center; height: 1.875rem; padding: 0 0.75rem; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); font-size: 0.8125rem; font-weight: 500; color: var(--ink); text-decoration: none; }
.sd-chip:hover { border-color: var(--brand); color: var(--brand); }

/* Notes and the record */
.sd-notes { display: flex; flex-direction: column; gap: 0.75rem; scroll-margin-top: calc(var(--sd-head-h) + 1rem); }
.sd-notes__form { padding: 0.875rem; gap: 0.5rem; }
.sd-notes__row { display: flex; align-items: center; gap: 0.625rem; }
.sd-notes__row .sd-muted { flex: 1; }
.sd-note { padding: 0.875rem 1rem; gap: 0.375rem; }
.sd-note__meta { margin: 0; font-size: 0.78125rem; color: var(--ink-soft); }
.sd-note__meta b { color: var(--ink); font-weight: 600; }
.sd-note__body { margin: 0; font-size: 0.84375rem; line-height: 1.25rem; white-space: pre-line; overflow-wrap: anywhere; }
.sd-record { padding: 0; gap: 0; overflow: hidden; scroll-margin-top: calc(var(--sd-head-h) + 1rem); }
.sd-record__head { padding: 1.125rem 1.375rem; }
.sd-record__table th:first-child, .sd-record__table td:first-child { padding-left: 1.375rem; }
.sd-record__table th:last-child, .sd-record__table td:last-child { padding-right: 1.375rem; }
.sd-record__table tbody tr:last-child td { border-bottom: 0; }
.sd-record__when { white-space: nowrap; width: 10rem; }
.sd-record__what { font-weight: 600; }
.sd-record__empty { margin: 0; padding: 0 1.375rem 1.25rem; }

.sd-danger { display: flex; align-items: center; gap: 1.25rem; padding: 0.875rem 1.375rem; border: 1px dashed #E9A7A0; border-radius: 14px; }
.sd-danger__title { margin: 0; font-size: 0.875rem; font-weight: 600; color: #B0322A; }
.sd-danger__body { flex: 1; margin: 0; font-size: 0.8125rem; color: var(--ink-soft); }

.sd #prerequisites, .sd #documents, .sd #checklist, .sd #score, .sd #payment, .sd #print, .sd #answers, .sd #verify { scroll-margin-top: calc(var(--sd-head-h) + 1rem); }

/* Under a laptop the page only stacks — halves, rows and the reading columns go
   to one column and the head wraps — so nothing runs off the side. */
@media (max-width: 1023px) {
  .sd-head { position: static; padding: 1rem 1.25rem 0; }
  .sd-head__row { flex-wrap: wrap; }
  .sd-head__decide { flex: 1 1 100%; margin-left: 0; justify-content: flex-start; }
  .sd-decide { flex: 1 1 15rem; min-width: 0; }
  .sd-decide__controls .sd-select { flex: 1 1 auto; min-width: 0; }
  .sd-section-head__tools { margin-left: 0; flex-wrap: wrap; }
  .sd-gpa { flex-wrap: wrap; }
  .sd-tiles { grid-template-columns: minmax(0, 1fr); }
  .sd-signers__file .field-select { min-width: 0; }
  .sd-strip { flex-wrap: wrap; }
  .sd-strip__cell { flex: 1 1 9rem; border-bottom: 1px solid var(--divider); }
  .sd-strip__cell--links { flex: 1 1 100%; flex-wrap: wrap; padding-inline: 1rem; }
  .sd-places { flex-wrap: wrap; }
  .sd-places__slot { width: 22px; }
  .sd__body { padding: 1.25rem 1.25rem 3rem; }
  .sd-split, .sd-row, .sd-row--money, .sd-row--record, .sd-reading, .sd-pay__body { grid-template-columns: minmax(0, 1fr); }
  .sd-pay__body { grid-template-areas: "lead" "lines" "links"; }
  .sd-split__claims > .sd-card { border-radius: 16px 16px 0 0; }
  .sd-dock, .sd-split--answers .sd-dock { position: static; border-radius: 0 0 15px 15px; height: auto; }
  .sd-dock__sticky, .sd-dock__sticky--open { position: static; height: auto; }
  .sd-dock__stage { height: 70vh; }
  .sd-reading__nav, .sd-reading__aside { position: static; padding-top: 0; }
  .sd-reading__nav { flex-direction: row; flex-wrap: wrap; }
  .sd-answers__list { grid-template-columns: minmax(0, 1fr); }
  .sd-danger { flex-wrap: wrap; }
  .sd-signers__actions { white-space: normal; }
}

/* ════════════════════════════════════════════════════════════════════════════
   ─── Prerequisites: courses applicants write in, and the acknowledgement ───
   (plan 2026-10-28-prereq-writein-ack, boards "Main" and "StaffDetail")

   The builder tab's two new panels sit between "GPA and grades" and the sheet,
   in the GPA panel's frame (`.prq-panel`), with a footer bar for the save
   button. The switch is the shared `.switch` (a real checkbox). Everything
   about a written-in course is drawn DASHED in the brand blue — the sheet's
   "or one they write in" chip, the application page's "Written in" pill, the
   code's underline and the correction editor's box — so the dash, not the
   colour alone, is what says "not on your list" (WCAG 1.4.1).
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── Builder: the two panels ─── */
.bld-sheet--wide .prq-wi__form,
.bld-sheet--wide .prq-ack__form { display: block; }
.bld-sheet--wide .prq-wi .bld-label,
.bld-sheet--wide .prq-ack .bld-label { display: block; margin-bottom: 0.375rem; font-size: 0.8125rem; color: var(--ink); }
.bld-sheet--wide .prq-switch { gap: 0.75rem; }
.bld-sheet--wide .prq-switch .switch__track { background: var(--border-field); }
.bld-sheet--wide .prq-switch > input:checked + .switch__track { background: var(--brand); }
.bld-sheet--wide .prq-switch .switch__label { font-size: 0.9375rem; line-height: 1.35; }
.bld-sheet--wide .prq-switch .switch__label .field-hint { display: block; max-width: 38.75rem; margin-top: 0.125rem; line-height: 1.35; }
.bld-sheet--wide .prq-wi__body { display: flex; flex-direction: column; gap: 1rem; padding: 1rem 1.25rem 1.25rem; }
.bld-sheet--wide .prq-wi__grid { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 1rem 1.75rem; }
.bld-sheet--wide .prq-wi__credits { flex: 0 1 18.75rem; min-width: 0; }
.bld-sheet--wide .prq-wi__input { min-height: 2.625rem; background: var(--surface); font-family: var(--font-mono); font-size: 1rem; color: var(--ink-heading); }
.bld-sheet--wide .prq-wi__asks { flex: 1 1 22.5rem; min-width: 0; padding: 0.75rem 0.875rem; border-radius: 10px; background: var(--bg); font-size: 0.8125rem; color: var(--ink); }
.bld-sheet--wide .prq-wi__asks ul { margin: 0.375rem 0 0; padding-left: 1.125rem; list-style: disc; }
.bld-sheet--wide .prq-wi__asks li { margin: 0.125rem 0; }
.bld-sheet--wide .prq-panel__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.625rem;
  padding: 0.75rem 1.25rem; border-top: 1px solid var(--divider); background: #FBFCFE;
}
.bld-sheet--wide .prq-panel__when { margin-left: auto; font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .prq-panel__status { padding: 0.25rem 0.625rem; border-radius: var(--r-md); background: var(--success-soft); color: var(--success); font-size: 0.875rem; }
.bld-sheet--wide .prq-panel__status--error { background: var(--danger-soft); color: var(--danger-ink); }

/* The panel's title sits above both columns; the grey preview column starts
   right under it, as on the board. */
.bld-sheet--wide .prq-ack__cols { display: flex; flex-wrap: wrap; }
.bld-sheet--wide .prq-ack__main { flex: 999 1 27.5rem; min-width: 0; display: flex; flex-direction: column; gap: 1rem; padding: 1rem 1.25rem 1.25rem; }
.bld-sheet--wide .prq-ack__fields { display: flex; flex-direction: column; gap: 1rem; }
.bld-sheet--wide .prq-ack__message { min-height: 9.375rem; resize: vertical; line-height: 1.5; background: var(--surface); }
.bld-sheet--wide .prq-ack__phrase { min-height: 2.625rem; background: var(--surface); }
.bld-sheet--wide .prq-ack__side { flex: 1 1 20.625rem; min-width: 0; padding: 1rem 1.25rem 1.25rem; background: var(--bg); border-left: 1px solid var(--divider); }
.bld-sheet--wide .prq-pv__cap { display: flex; align-items: center; gap: 0.375rem; margin: 0 0 0.5rem; font-size: 0.75rem; font-weight: 600; color: var(--ink-soft); }
.bld-sheet--wide .prq-pv__cap svg { width: 1rem; height: 1rem; flex: none; }
.bld-sheet--wide .prq-pv {
  display: flex; flex-direction: column; gap: 0.625rem; max-width: 22.5rem; padding: 1rem;
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface); font-size: 0.875rem;
}
.bld-sheet--wide .prq-pv__title { margin: 0; font-family: var(--font-heading); font-size: 1.125rem; font-weight: 600; line-height: 1.25; color: var(--ink-heading); }
.bld-sheet--wide .prq-pv__lede { margin: 0; font-size: 0.8125rem; color: var(--ink-soft); }
.bld-sheet--wide .prq-pv__msg {
  display: flex; flex-direction: column; gap: 0.375rem; padding: 0.625rem 0.75rem;
  border: 1px solid var(--border); border-radius: 10px; background: #FBFCFE;
}
.bld-sheet--wide .prq-pv__msg p,
.bld-sheet--wide .prq-pv__paras p { margin: 0; white-space: pre-line; font-size: 0.84375rem; line-height: 1.5; overflow-wrap: anywhere; }
.bld-sheet--wide .prq-pv__paras { display: flex; flex-direction: column; gap: 0.375rem; }
.bld-sheet--wide .prq-pv__msg .prq-pv__empty { color: var(--danger-ink); font-style: italic; }
.bld-sheet--wide .prq-pv__label { margin: 0; font-size: 0.8125rem; font-weight: 600; color: var(--ink); }
.bld-sheet--wide .prq-pv__phrase {
  padding: 0.0625rem 0.375rem; border-radius: var(--r-sm); background: var(--brand-tint);
  font-family: var(--font-mono); font-size: 0.8125rem; color: var(--ink-heading);
  overflow-wrap: anywhere; -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.bld-sheet--wide .prq-pv__field { height: 2.375rem; border: 1px solid var(--border-field); border-radius: var(--r-md); background: var(--surface); }
.bld-sheet--wide .prq-pv__btn {
  display: flex; align-items: center; justify-content: center; height: 2.5rem;
  border-radius: 9px; background: var(--brand); color: var(--on-brand); font-size: 0.875rem; font-weight: 600;
}
.bld-sheet--wide .prq-pv__off { margin: 0; padding: 1.5rem 0; font-size: 0.8125rem; color: var(--ink-soft); }

/* ─── Builder: the sheet ─── */
.bld-sheet--wide .prq-chip-own { border-style: dashed; border-color: #7FA7E6; background: #F7FAFF; color: #00449F; }
.bld-sheet--wide .prq-alts__own { font-size: 0.84375rem; font-style: italic; color: #00449F; }

@media (max-width: 47.99rem) {
  .bld-sheet--wide .prq-ack__side { border-left: 0; border-top: 1px solid var(--divider); }
  .bld-sheet--wide .prq-panel__when { margin-left: 0; flex-basis: 100%; }
}

/* ─── Application page: written-in courses (board "StaffDetail") ─── */
.sd .sd-own { padding: 0.0625rem 0.5625rem; border: 1px dashed #5B8FE0; background: var(--surface); color: #00449F; }
.sd .sd-own--row { margin-left: 0.25rem; font-size: 0.71875rem; line-height: 1.125rem; vertical-align: 1px; }
.sd .sd-strip__pill.sd-own { padding: 0 0.5rem; }
.sd-own-code { color: #00449F; border-bottom: 1px dashed #5B8FE0; }
.sd-flags .sd-flags__own { color: #00449F; }
.sd-prq__grid tr.is-written:not(.is-flagged):not(.is-editing) { background: #F7FAFF; }
.sd-prq__req { font-weight: 400; color: #9A4508; }
/* The correction editor on a write-in version: four columns, as on the board —
   Course taken, the listed course's credits beside it, then the written-in box
   across the row, then grade, term and school. Course taken takes three of the
   four because the card is narrower than the board's, and its longest choice
   ("A course not on the list (written in)") should read whole; the term column
   is a little wider so "Spring 2026" fits beside its arrow. */
.sd-prq__fields--own { grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr); }
.sd-prq__fields--own > .sd-prq__wide:first-child { grid-column: span 3; }
.sd-prq__own {
  grid-column: 1 / -1; display: grid; grid-template-columns: 7.5rem minmax(0, 1fr) 7.5rem; gap: 0.625rem;
  padding: 0.625rem 0.75rem 0.75rem; border: 1px dashed #5B8FE0; border-radius: 10px; background: var(--surface);
}
.sd-prq__own-cap { grid-column: 1 / -1; margin: 0; font-size: 0.78125rem; line-height: 1.125rem; font-weight: 600; color: #00449F; }
.sd-prq__own-code { font-family: var(--font-mono); }

@media (max-width: 47.99rem) {
  .sd-prq__fields--own { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sd-prq__fields--own > .sd-prq__wide:first-child { grid-column: 1 / -1; }
  .sd-prq__own { grid-template-columns: minmax(0, 1fr); }
}

/* ════════════════════════════════════════════════════════════════════════════
   ─── Messages (2026-10-28) — the staff side ────────────────────────────────
   (plan 2026-10-28-messaging; boards "Main", "StaffDetail" and "Queue")

   Three places: the builder's Messages tab (`.msg-tab`), the Messages window
   over the application page and its no-JS page (`.modal--messages`,
   `.msg-body`), and two markers — the strip's Messages cell and the queue's
   "N new messages". Every selector is `msg-`, `queue-msg` or a new `sd-strip`
   modifier, so no other page moves. The pills here drop the console's dot, as
   the boards draw them; each one is still a word, never a colour alone.

   The switches are real checkboxes (`role="switch"`). Their OFF track is
   `--border-field` rather than the board's #BFC4CC: a switch is identified by
   its track, and #BFC4CC is 1.7:1 on white, under WCAG 1.4.11's 3:1 (the
   Prerequisites tab's switch made the same call).
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── Shared pieces ─── */
.msg-ico {
  width: 1.125rem; height: 1.125rem; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.msg-sub { margin: 0; font-size: 0.84375rem; line-height: 1.25rem; color: var(--ink-soft); }
.msg-pill {
  display: inline-flex; align-items: center; padding: 0 0.625rem; border-radius: var(--r-full);
  font-size: 0.71875rem; line-height: 1.125rem; font-weight: 500; white-space: nowrap;
}
.msg-pill--mute { background: var(--divider); color: #4A5563; }
.msg-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 2.25rem; padding: 0 0.875rem; border: 1px solid var(--border-strong); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink); font-family: var(--font-sans);
  font-size: 0.84375rem; font-weight: 500; line-height: 1; white-space: nowrap; text-decoration: none; cursor: pointer;
}
.msg-btn:hover { border-color: var(--border-field); background: #F8F9FB; color: var(--ink); }
.msg-btn--primary { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.msg-btn--primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: var(--on-brand); }
.msg-btn--danger { background: #B0322A; border-color: #B0322A; color: #FFFFFF; }
.msg-btn--danger:hover { background: #8E241C; border-color: #8E241C; color: #FFFFFF; }
.msg-btn--sm { min-height: 1.875rem; padding: 0 0.625rem; font-size: 0.8125rem; }
.msg-lnk {
  display: inline-flex; align-items: center; min-height: 1.875rem; padding: 0; border: 0; background: none;
  color: var(--brand); font-family: var(--font-sans); font-size: 0.84375rem; font-weight: 500; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #9DBFF2;
}
.msg-lnk:hover { color: var(--brand-hover); text-decoration-color: currentColor; }
.msg-lnk--danger { color: #B0322A; text-decoration-color: #E8A9A3; }
.msg-lnk--danger:hover { color: #8E241C; }

/* A real checkbox under a drawn track; the label around both is the target. */
.msg-swt { position: relative; display: inline-flex; align-items: center; gap: 0.625rem; flex: none; cursor: pointer; }
.msg-swt__input { position: absolute; top: 0; left: 0; width: 1px; height: 1px; margin: 0; opacity: 0; }
.msg-swt__track {
  display: inline-flex; align-items: center; flex: none; width: 2.75rem; height: 1.625rem; padding: 3px;
  border-radius: var(--r-full); background: var(--border-field); transition: background-color 150ms ease;
}
.msg-swt__thumb {
  display: block; width: 1.25rem; height: 1.25rem; border-radius: 50%; background: var(--surface);
  box-shadow: 0 1px 2px rgba(1, 33, 75, 0.3); transition: transform 150ms ease;
}
.msg-swt__input:checked + .msg-swt__track { background: var(--brand); }
.msg-swt__input:checked + .msg-swt__track .msg-swt__thumb { transform: translateX(1.125rem); }
.msg-swt__input:focus-visible + .msg-swt__track { outline: 3px solid var(--accent); outline-offset: 2px; }
.msg-swt--sm .msg-swt__track { width: 2.375rem; height: 1.375rem; }
.msg-swt--sm .msg-swt__thumb { width: 1rem; height: 1rem; }
.msg-swt--sm .msg-swt__input:checked + .msg-swt__track .msg-swt__thumb { transform: translateX(1rem); }
.msg-swt__word { font-size: 0.84375rem; color: var(--ink); }
/* The word beside each switch follows the box, with or without a script. */
.msg-swt__input:checked ~ .msg-swt__word--off,
.msg-swt__input:not(:checked) ~ .msg-swt__word--on { display: none; }
@media (prefers-reduced-motion: reduce) {
  .msg-swt__track, .msg-swt__thumb { transition: none; }
}

/* ─── The builder's Messages tab (board "Main") ─── */
.msg-tab { display: flex; flex-direction: column; gap: 1.25rem; max-width: 61.75rem; }
.msg-tab__top { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75rem; }
.msg-tab__intro { flex: 1 1 32.5rem; min-width: 0; }
.msg-tab__title {
  margin: 0; font-family: var(--font-heading); font-size: 1.25rem; line-height: 1.75rem; font-weight: 600;
  letter-spacing: 0; color: var(--ink-heading);
}
.msg-tab__lede { margin: 0.25rem 0 0; max-width: 45rem; font-size: 0.875rem; line-height: 1.25rem; color: var(--ink-soft); }
.msg-chip {
  flex: none; display: inline-flex; align-items: center; padding: 0.125rem 0.625rem; border-radius: var(--r-full);
  background: var(--brand-soft); color: #00449F; font-size: 0.78125rem; line-height: 1.25rem; font-weight: 500; white-space: nowrap;
}
.msg-tab__error {
  margin: 0; padding: 0.625rem 0.875rem; border-radius: 10px; background: var(--danger-soft); color: #6E1512;
  font-size: 0.875rem; line-height: 1.25rem; font-weight: 500;
}
.msg-card { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; }
.msg-card--split { display: flex; flex-wrap: wrap; overflow: hidden; }
.msg-card__main { flex: 1 1 30rem; min-width: 0; display: flex; flex-direction: column; gap: 1rem; padding: 1.25rem 1.375rem; }
.msg-card__title {
  margin: 0; font-family: var(--font-heading); font-size: 1.0625rem; line-height: 1.5rem; font-weight: 600;
  letter-spacing: 0; color: var(--ink-heading);
}
.msg-onoff { display: flex; align-items: flex-start; gap: 0.875rem; }
.msg-onoff__label { display: block; margin: 0; font-size: 0.9375rem; line-height: 1.375rem; font-weight: 600; color: var(--ink); cursor: pointer; }
.msg-onoff__desc { max-width: 32.5rem; }
.msg-checks {
  display: flex; flex-direction: column; gap: 0.5rem; padding: 0.75rem 0.875rem;
  border: 1px solid var(--divider); border-radius: 10px; background: var(--bg);
}
.msg-check { display: flex; align-items: flex-start; gap: 0.5rem; margin: 0; font-size: 0.84375rem; line-height: 1.25rem; color: var(--ink); }
.msg-check > .msg-ico { margin-top: 1px; }
.msg-check b { font-weight: 600; }
.msg-check a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }
.msg-ico--ok { color: var(--success); }
.msg-ico--info { color: var(--brand); }
.msg-ico--warn { color: var(--warning); }
.msg-card__side {
  flex: 1 1 21.25rem; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem;
  padding: 1.25rem 1.375rem; border-left: 1px solid var(--divider); background: #F8F9FB;
}
.msg-pv__cap { display: flex; align-items: center; gap: 0.5rem; margin: 0; font-size: 0.8125rem; line-height: 1.125rem; font-weight: 600; color: var(--ink); }
.msg-pv__cap .msg-ico { color: var(--ink-soft); }
.msg-pv {
  width: 18.75rem; max-width: 100%; display: flex; flex-direction: column; gap: 0.625rem; padding: 0.875rem;
  border-radius: 18px; background: var(--bg); box-shadow: 0 0 0 1px #C9D0DA;
}
.msg-pv__card {
  display: flex; flex-direction: column; gap: 0.625rem; padding: 0.875rem;
  border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface);
}
.msg-pv__row { display: flex; align-items: flex-start; gap: 0.75rem; }
.msg-pv__tile {
  width: 2.375rem; height: 2.375rem; flex: none; display: grid; place-items: center;
  border-radius: 10px; background: var(--brand-tint); color: var(--brand);
}
.msg-pv__title { margin: 0; font-family: var(--font-heading); font-size: 1rem; line-height: 1.375rem; font-weight: 600; color: var(--ink-heading); }
.msg-pv__line { margin: 0.125rem 0 0; font-size: 0.84375rem; line-height: 1.2; color: var(--ink); }
.msg-pv__btn {
  display: flex; align-items: center; justify-content: center; width: 100%; min-height: 2.5rem;
  border-radius: var(--r-md); background: var(--brand); color: var(--on-brand); font-size: 0.84375rem; font-weight: 500;
}
.msg-pv__note { font-size: 0.78125rem; line-height: 1.0625rem; }
.msg-pv--off {
  min-height: 9.375rem; justify-content: center; align-items: center; text-align: center;
  border: 2px dashed #BFC4CC; box-shadow: none; background: var(--surface);
}
.msg-pv--off .msg-sub { max-width: 13.75rem; }
.msg-who { display: flex; flex-direction: column; gap: 0.875rem; padding: 1.25rem 1.375rem; }
.msg-who__top { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75rem; }
.msg-who__intro { flex: 1 1 30rem; min-width: 0; }
.msg-who__intro .msg-sub { max-width: 42.5rem; }
.msg-who__all { flex: none; display: flex; gap: 1rem; }
.msg-note-off { padding: 0.625rem 0.75rem; border-radius: var(--r-md); background: var(--warning-soft); color: #7A3A06; }
.msg-people__wrap { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; overflow-x: auto; }
.msg-people { width: 100%; border-collapse: collapse; font-size: 0.875rem; line-height: 1.25rem; }
/* The row headers wear the column headers' tint and type, as on the board. */
.msg-people th {
  padding: 0.5rem 0.875rem; border-bottom: 1px solid var(--border); background: #F8F9FB;
  text-align: left; font-size: 0.78125rem; line-height: 1.125rem; font-weight: 600; color: var(--ink-soft);
}
.msg-people tbody th { padding: 0.6875rem 0.875rem; border-bottom-color: var(--divider); white-space: nowrap; }
.msg-people tbody th .msg-pill { margin-left: 0.25rem; }
.msg-people td { padding: 0.6875rem 0.875rem; border-bottom: 1px solid var(--divider); vertical-align: middle; color: var(--ink); }
.msg-people tbody tr:last-child td,
.msg-people tbody tr:last-child th { border-bottom: 0; }
.msg-people__switch { width: 9.375rem; }
.msg-people__email { font-size: 0.8125rem; }
.msg-who__foot { font-size: 0.8125rem; }
.msg-tab__save { display: flex; flex-wrap: wrap; align-items: center; gap: 0.875rem; }
/* Live before anything is saved: the preview, the note and the rows follow the
   switch. Both previews are in the page; this shows the one it says. */
.msg-tab:has(#messaging-enabled:checked) .msg-pv--off,
.msg-tab:has(#messaging-enabled:checked) .msg-note-off,
.msg-tab:not(:has(#messaging-enabled:checked)) .msg-pv--on { display: none; }
.msg-tab:not(:has(#messaging-enabled:checked)) .msg-people td { color: var(--ink-soft); }

@media (max-width: 47.99rem) {
  .msg-card__side { border-left: 0; border-top: 1px solid var(--divider); }
}

/* ─── The Messages window (board "StaffDetail") ─── */
.modal.modal--messages {
  width: min(47.5rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2 * clamp(1rem, 7.3vh, 6rem));
  margin: clamp(1rem, 7.3vh, 6rem) auto auto;
  border: 0;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: 0 24px 60px rgba(1, 33, 75, 0.35);
  overflow: hidden;
}
.modal--messages::backdrop { background: rgba(1, 33, 75, 0.45); }
/* The dialog takes focus itself when it opens (a screen reader hears its name);
   the ring belongs to the controls inside it. */
.modal--messages:focus { outline: none; }
.msg-dlg__head { flex: none; display: flex; align-items: flex-start; gap: 0.75rem; padding: 1.125rem 1.375rem 0.875rem; border-bottom: 1px solid var(--divider); }
.msg-dlg__intro { min-width: 0; }
.msg-dlg__title {
  margin: 0; font-family: var(--font-heading); font-size: 1.3125rem; line-height: 1.75rem; font-weight: 600;
  letter-spacing: 0; color: var(--ink-heading);
}
.msg-dlg__about { margin: 0; font-size: 0.84375rem; line-height: 1.1875rem; color: var(--ink-soft); }
.msg-ref { color: var(--ink-heading); letter-spacing: 0; }
.msg-x {
  margin-left: auto; flex: none; width: 2.5rem; height: 2.5rem; display: grid; place-items: center;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--ink); cursor: pointer;
}
.msg-x:hover { background: var(--bg); }

.msg-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.msg-body .msg-sub { font-size: 0.8125rem; line-height: 1.1875rem; }
.msg-thread {
  position: relative; flex: 0 1 auto; min-height: 0; overflow-y: auto; list-style: none;
  margin: 0; padding: 1.125rem 1.375rem; display: flex; flex-direction: column; gap: 1rem; background: #F8F9FB;
}
.modal--messages .msg-thread { max-height: 45rem; }
.msg-thread:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; border-radius: 0; }
.msg-row { display: flex; flex-direction: column; gap: 1rem; }
.msg-empty { padding: 1rem 0; text-align: center; font-size: 0.875rem; color: var(--ink-soft); }
.msg-newline { display: flex; align-items: center; gap: 0.625rem; font-size: 0.78125rem; line-height: 1rem; font-weight: 600; color: var(--brand); }
.msg-newline::before,
.msg-newline::after { content: ""; flex: 1; height: 1px; background: #9DBFF2; }
.msg { display: flex; flex-direction: column; gap: 0.375rem; max-width: 78%; }
.msg--them { align-self: flex-start; align-items: flex-start; }
.msg--us { align-self: flex-end; align-items: flex-end; }
/* The 13px above and below a byline are the board's (its bylines kept the
   paragraph's default margin), and they are what separates one message from
   the next as much as the gap does. */
.msg-by {
  margin: 0.8125rem 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem 0.5rem;
  font-size: 0.8125rem; line-height: 1.125rem; color: var(--ink-soft);
}
.msg-by b { font-weight: 600; color: var(--ink); }
.msg-av {
  width: 1.625rem; height: 1.625rem; flex: none; display: grid; place-items: center; border-radius: 50%;
  font-size: 0.6875rem; line-height: 1; font-weight: 600;
}
.msg-av--app { background: var(--warning-soft); color: #7A3A06; }
.msg-av--staff { background: var(--navy); color: #FFFFFF; }
/* `pre-line`: the applicant's line breaks are kept, and the `<p>` holds the text
   and nothing else, so the template's own whitespace never shows. */
.msg-bubble {
  margin: 0; padding: 0.75rem 0.875rem; border-radius: 14px; font-size: 0.9375rem; line-height: 1.4375rem;
  color: var(--ink); white-space: pre-line; overflow-wrap: anywhere;
}
.msg-bubble--them { background: var(--surface); border: 1px solid var(--border); border-top-left-radius: 4px; }
.msg-bubble--us { background: var(--brand-tint); border: 1px solid #C5DAF9; border-top-right-radius: 4px; }
.msg-bubble.is-new { box-shadow: 0 0 0 2px #9DBFF2; }
.msg-gone {
  margin: 0; padding: 0.625rem 0.875rem; border: 1px dashed #BFC4CC; border-radius: 14px; background: transparent;
  font-size: 0.875rem; line-height: 1.25rem; font-style: italic; color: var(--ink-soft);
}
.msg-tools { display: flex; align-items: center; gap: 0.875rem; font-size: 0.78125rem; line-height: 1rem; color: var(--ink-soft); }
.msg-tools .msg-lnk { min-height: 1.75rem; font-size: 0.8125rem; }
.msg-edited { border-bottom: 1px dotted var(--border-field); cursor: help; }
.msg-lbl { display: block; font-size: 0.78125rem; line-height: 1.125rem; font-weight: 600; color: var(--ink); }
.msg-lbl--compose { font-size: 0.84375rem; }
.msg-ta {
  width: 100%; padding: 0.625rem 0.75rem; border: 1px solid var(--border-field); border-radius: 10px;
  background: var(--surface); color: var(--ink); font-family: var(--font-sans); font-size: 0.9375rem; line-height: 1.375rem; resize: vertical;
}
.msg-ta::placeholder { color: var(--ink-faint); }
.msg-ta.is-invalid { border-color: var(--danger); box-shadow: 0 0 0 2px var(--danger-soft); }
.msg-err { margin: 0; font-size: 0.8125rem; line-height: 1.125rem; font-weight: 500; color: #B0322A; }
.msg-edit { width: 27.5rem; max-width: 100%; display: flex; flex-direction: column; gap: 0.375rem; }
.msg-edit__bar { display: flex; align-items: center; gap: 0.5rem; }
.msg-edit__bar .msg-count { margin-left: auto; }
.msg-confirm {
  max-width: 27.5rem; display: flex; flex-direction: column; gap: 0.5rem; padding: 0.75rem 0.875rem;
  border: 1px solid #F0C3BE; border-radius: var(--r-lg); background: var(--danger-soft);
}
.msg-confirm__title { margin: 0; font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; color: #8E241C; }
.msg-body .msg-confirm__body { color: #6B2019; }
.msg-confirm__actions { display: flex; gap: 0.5rem; }
.msg-compose { flex: none; display: flex; flex-direction: column; gap: 0.5rem; padding: 1rem 1.375rem 1.25rem; border-top: 1px solid var(--divider); background: var(--surface); }
.msg-compose__bar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.msg-compose__hint { flex: 1 1 18.75rem; }
.msg-flash { margin: 0; padding: 0.5rem 0.75rem; border-radius: var(--r-md); background: var(--success-soft); color: #0B5E49; font-size: 0.84375rem; line-height: 1.1875rem; font-weight: 500; }
.msg-closed {
  margin: 0; display: flex; align-items: flex-start; gap: 0.625rem; padding: 0.75rem 0.875rem;
  border-radius: 10px; background: var(--divider); color: var(--ink); font-size: 0.875rem; line-height: 1.25rem;
}
.msg-closed > .msg-ico { margin-top: 1px; }
.msg-closed a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }

/* The window on a page of its own (no JavaScript): the same body in a card, the
   conversation as long as it is. */
.msg-page {
  width: 100%; max-width: 47.5rem; overflow: hidden;
  border: 1px solid var(--border); border-radius: 16px; background: var(--surface);
}

@media (max-width: 47.99rem) {
  .msg { max-width: 92%; }
  .msg-dlg__head, .msg-thread, .msg-compose { padding-inline: 1rem; }
}

/* ─── The application page's Messages cell (board "StaffDetail") ─── */
.sd-strip__cell--messages { background: #F7FAFF; }
.sd-strip__cell--messages .sd-strip__label { display: flex; align-items: center; gap: 0.375rem; }
.sd-strip__icon {
  width: 0.875rem; height: 0.875rem; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
/* Never the heading face, even when it is the strip's first cell. */
.sd-strip__cell.sd-strip__cell--messages .sd-strip__value { font-family: var(--font-sans); font-size: inherit; }
.sd .sd-pill-new { background: var(--brand); color: var(--on-brand); font-weight: 600; }

/* ─── The queue's marker (board "Queue") ─── */
.queue-msg { display: block; margin-top: 0.375rem; }
.queue-msg__pill {
  display: inline-flex; align-items: center; gap: 0.3125rem; padding: 0.0625rem 0.5625rem; border-radius: var(--r-full);
  background: var(--brand); color: var(--on-brand); font-size: 0.75rem; line-height: 1.25rem; font-weight: 600; white-space: nowrap;
}
.queue-msg__icon {
  width: 0.8125rem; height: 0.8125rem; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* Review R1 (2026-10-29): "Send a new dashboard link" under the composer, on a
   form whose dashboard is only for messages. */
.msg-newlink { padding: 0 22px 18px; }
.msg-newlink .btn-link { padding: 0; }
.msg-newlink__note { color: var(--ink-soft); }

/* ════════════════════════════════════════════════════════════════════════════
   ─── Prerequisites: one another makes "not needed" (2026-10-29) — staff side
   (plan 2026-10-29-prereq-skip-rules; boards "Main", "StaffDetail" and
   "Staff-states")

   The boards' <helmet> rules, as drawn, with the `cp-` names renamed to `prq-`
   (`cp-rule*` → `prq-rule*`, `cp-chip-*` → `prq-chip-*`, `cp-from`/`cp-to` →
   `prq-num-from`/`prq-num-to`, `cp-ico` → `prq-ico`, `cp-move-error` →
   `prq-move-error`). Placed after the sheet's own `.bld-sheet--wide .docs-chip`
   and `.docs-num` rules, which they tie on specificity and must follow.
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── Builder (board "Main") ─── */
.prq-ico{flex:none;width:14px;height:14px}
.docs-chip.prq-chip-rule{display:inline-flex;align-items:center;gap:5px;border:1px dashed var(--brand);background:var(--brand-tint);color:var(--navy);font-weight:600}
.docs-chip.prq-chip-decides{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--brand-soft);background:var(--surface);color:var(--navy)}
.docs-num.prq-num-from,.docs-num.prq-num-to{position:relative;box-shadow:0 0 0 2px var(--brand-soft)}
.docs-num.prq-num-from::after{content:"";position:absolute;left:calc(50% - 1px);top:calc(100% + 4px);height:28px;border-left:2px dashed var(--brand)}
.prq-rule{display:grid;gap:0.625rem;margin-top:0.25rem;padding-top:1rem;border-top:1px solid var(--divider)}
.prq-rule__box{display:grid;gap:0.5rem;padding:0.75rem;border:1px solid var(--brand-soft);border-radius:10px;background:var(--surface)}
.prq-rule__words{margin:0;font-size:0.875rem;font-weight:500;color:var(--ink)}
.prq-rule__box .field-select{width:100%}
.prq-rule__preview{display:grid;gap:0.25rem;margin:0;padding:0.625rem 0.75rem;border-radius:8px;background:var(--brand-tint);font-size:0.8125rem;line-height:1.45;color:var(--ink)}
.prq-rule__preview b{font-weight:600;color:var(--navy)}
.prq-rule__preview span{display:flex;gap:0.375rem;align-items:flex-start}
.prq-rule__preview svg{margin-top:2px}
.prq-move-error{margin:0 0 0.75rem}
/* Not on the board, which draws the one adjacent pair closed: the thread runs
   from the trigger's number to the next row's only when that row is its
   dependent (`prq-num-thread`, from the server) and the trigger's own row is
   closed (its editor would sit under the number). */
.docs-num.prq-num-from:not(.prq-num-thread)::after,
.docs-row.is-open .docs-num.prq-num-from::after { content: none; }

/* ─── Application page (boards "StaffDetail" and "Staff-states") ─── */
.sd-flags .sd-flags__skip{border:1px dashed var(--border-field);background:var(--surface);color:var(--ink)}
.sd-flags .sd-flags__skip svg{color:var(--brand)}
.sd-prq__grid tr.is-skipped > th,.sd-prq__grid tr.is-skipped > td{background:#F7F8FA}
.sd-prq__grid tr.is-skipped .sd-prq__name,.sd-prq__grid tr.is-skipped .sd-prq__code{color:var(--ink-soft)}
.pill.sd-skip{display:inline-flex;align-items:center;gap:4px;margin-left:4px;border:1px dashed var(--border-field);background:var(--surface);color:var(--navy)}
.sd-prq__kept{display:block;font-size:0.8125rem;color:var(--ink-soft)}
.sd-prq__rule{display:flex;gap:0.375rem;align-items:flex-start;margin-top:0.25rem;font-size:0.8125rem;color:var(--ink-soft)}
.sd-prq__rule svg{margin-top:2px;color:var(--brand)}
.sd-prq__warn{display:flex;gap:0.5rem;align-items:flex-start;margin:0;padding:0.625rem 0.75rem;border-radius:var(--r-md);background:var(--warning-soft);color:var(--warning-ink);font-size:0.875rem;line-height:1.45}
.sd-prq__warn svg{flex:none;width:16px;height:16px;margin-top:1px}


/* What the head says about telling the applicant (2026-10-31, board "StaffStates").
   The head sticks, so `--sd-head-h`, which everything sticky below it reads, grows
   with this line. The hold and the failure are the two a person has to see; the rest
   is one quiet sentence. */
.sd:has(.sd-told) { --sd-head-h: 12rem; }
.sd:has(.sd-told--hold), .sd:has(.sd-told--fail) { --sd-head-h: 13.5rem; }
.sd-told {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.sd-told__ico {
  flex: none;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.sd-told__words { flex: 1 1 18rem; min-width: 0; }
.sd-told__words b { font-weight: 600; }
.sd-told form { margin: 0; }
.sd-told--hold, .sd-told--fail { padding: 0.625rem 0.875rem; border-radius: 10px; }
.sd-told--hold { background: #FBEFD9; border: 1px solid #EFD6A7; color: #6B3A05; }
.sd-told--fail { background: #FBE6E3; border: 1px solid #F0C3BE; color: #7E1F18; }
.sd-told--quiet {
  padding-top: 0.5rem;
  border-top: 1px solid var(--divider);
  font-size: 0.84375rem;
  color: var(--ink-soft);
}
.sd-told + .sd-strip { margin-top: 0.75rem; }
.sd-record__what--told { color: #0B5E49; }
.sd-record__what--bad { color: #A82C22; }

/* The Updates tab (board "Builder"): the Messages tab's parts, one card per column. */
.upd-card { display: flex; flex-direction: column; gap: 0.875rem; padding: 1.25rem 1.375rem; }
.upd-card .msg-onoff__desc { max-width: none; }
.upd-card .msg-checks.upd-checks {
  margin: 0;
  padding: 0.875rem 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--divider);
  border-radius: 0;
}
.msg-people.upd-words tbody th {
  background: none;
  color: var(--ink);
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: top;
}
.upd-words td { vertical-align: top; }
.upd-words .msg-pill { padding: 0.125rem 0.625rem; font-size: 0.78125rem; line-height: 1.25rem; }

/* The builder's strip has twelve tabs since the Updates tab (2026-10-31), which is
   wider than the content at 1280px, and only the queue's strip is meant to sit on an
   edge. Tighter, so all twelve fit a laptop on one line; wrapping below that, so the
   page never scrolls sideways. */
.tabs[aria-label="This form"] { margin-left: 0; flex-wrap: wrap; }
.tabs[aria-label="This form"] .tab { padding-inline: 0.5rem; }

/* Letters of recommendation on the application page (2026-11-05, rendition
   "Forms: Letters of Recommendation", board "Staff"). The block shares the
   multi-signer block's frame (.sd-signers); these are what it adds. */
.sd-letter-msg summary { cursor: pointer; margin-top: 0.25rem; color: var(--brand); font-size: 0.78125rem; font-weight: 500; list-style: none; }
.sd-letter-msg summary::-webkit-details-marker { display: none; }
.sd-letter-msg summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.sd-letter-msg p { margin: 0.375rem 0 0; padding: 0.5rem 0.625rem; border-radius: 8px; background: var(--bg); font-size: 0.8125rem; line-height: 1.45; white-space: pre-line; max-width: 44ch; overflow-wrap: anywhere; font-weight: 400; color: var(--ink); }
.sd-letter-sub { display: block; margin-top: 0.125rem; }
.sd-letter-acts { display: flex; flex-direction: column; align-items: flex-start; gap: 0.375rem; }
.sd-letter-file { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem; padding-top: 0.875rem; border-top: 1px solid var(--divider); }
.sd-letter-file .sd-field { flex: 1 1 15rem; }
.sd-letter-file__hint { flex-basis: 100%; margin: 0; }
.letter-dialog { display: flex; flex-direction: column; gap: 0.75rem; }
.letter-dialog p { margin: 0; font-size: 0.875rem; line-height: 1.5; }
.letter-dialog__then { display: grid; gap: 0.5rem; margin: 0; padding: 0; border: 0; }
.letter-dialog__then .field-hint { display: block; }

/* Letters of recommendation on the Documents tab (2026-11-05, board "Staff:
   Documents tab, a letters item"): the count, the two switches and the size in
   one box, like the agreement's; the preview under it. */
.bld-sheet--wide .docs-chip--letters { background: var(--navy); border-color: var(--navy); color: var(--on-brand); }
.bld-sheet--wide .docs-letters-box {
  display: grid; gap: 0; padding: 0.875rem 1rem;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
}
.bld-sheet--wide .docs-letters-box .bld-field + .docs-switches,
.bld-sheet--wide .docs-letters-box .docs-switches + .bld-field { margin-top: 0.875rem; padding-top: 0.875rem; border-top: 1px solid var(--divider); }
.bld-sheet--wide .docs-letters-box .docs-switches { margin-top: 0.875rem; }
.bld-sheet--wide .docs-preview__empty { color: var(--ink-soft); font-style: italic; }
/* The board draws the dialog's choices as plain radios and a checkbox, not boxed rows. */
.letter-dialog__opt { display: flex; gap: 0.5625rem; align-items: flex-start; font-size: 0.875rem; line-height: 1.45; color: var(--ink); cursor: pointer; }
.letter-dialog__opt input { flex: none; margin: 0.1875rem 0 0; accent-color: var(--brand); width: 1rem; height: 1rem; }
.letter-dialog__opt input:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.letter-dialog__opt .field-hint { display: block; margin-top: 0.0625rem; color: var(--ink-soft); font-size: 0.8125rem; }

/* "When we ask for it" on the Documents tab (2026-11-05, board "Builder"): the
   choice in its own box, green once "Once approved" is picked, with the three-line
   explainer under it; the "Once approved" chip on the row. After the base
   `.bld-sheet--wide .docs-chip` so the chip's colours win. */
.bld-sheet--wide .docs-chip--later { display: inline-flex; align-items: center; gap: 4px; background: #E9F6F1; border-color: #9DD3BF; color: #0B5E49; }
.bld-sheet--wide .docs-chip--later svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.when-box { display: grid; gap: 0.5rem; padding: 0.875rem 1rem; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.when-box.is-later { border-color: #9DD3BF; background: #F4FBF8; }
.when-later { margin: 0.25rem 0 0; padding-top: 0.75rem; border-top: 1px solid var(--divider); display: grid; gap: 0.375rem; font-size: 0.8125rem; line-height: 1.45; color: var(--ink); }
.when-later p { margin: 0; }
.when-later b { color: #0B5E49; }

/* The Updates tab's once-approved line (2026-11-05): the words follow the switch
   before it is saved, like the Messages tab's notes. */
.msg-tab:has(#updates-enabled:checked) .upd-later-off,
.msg-tab:not(:has(#updates-enabled:checked)) .upd-later-on { display: none; }

/* Documents asked once approved, on the application page (2026-11-05, board
   "Staff"): a dashed tile until the applicant is asked, the chip in its kind line,
   and the line saying when they are (or were) asked. */
.sd-tile--later { border-style: dashed; border-color: #9DD3BF; background: #F7FCFA; }
.sd-later {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px;
  border: 1px solid #9DD3BF;
  border-radius: 999px;
  background: #E9F6F1;
  color: #0B5E49;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}
.sd-later svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.sd-later-line { margin: 6px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
