/* ==========================================================================
   HWC Training Portal
   Palette matches the Trauma & Grief Center site (hwc.mmhpi.org). If you change
   a colour here, change src/brand.js too — certificate.js draws PDFs and cannot
   read CSS, so it keeps its own copy of the same values.
   ========================================================================== */

/* ---- fonts ---------------------------------------------------------------
   Montserrat stands in for Gotham, which is licensed to the main site and not
   ours to redistribute. Self-hosted: no CDN, works on locked-down networks. */
@font-face {
  font-family: 'Montserrat';
  src: url('/public/fonts/montserrat.woff2') format('woff2-variations'),
       url('/public/fonts/montserrat.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---- tokens --------------------------------------------------------------
   One scheme only: blue and white. The app never goes dark — a dark scheme
   turns every surface into another shade of navy, and blue-on-blue is exactly
   what this design forbids. Dark ground exists in two deliberate places (the
   entry hero and the player letterbox), and everything on it is white. */
:root {
  color-scheme: light;

  --navy-900: #0E2436;
  --navy-800: #142E43;
  --navy-700: #1D4363;
  --blue-600: #285F9F;
  --blue-700: #1F4C80;
  --cyan-500: #00B0DA; /* white surfaces only — on navy it is blue-on-blue */
  --grey-050: #FAFBFC;
  --grey-100: #F1F4F7;
  --grey-200: #E1E8ED;
  --grey-300: #C5CBD0;
  --grey-500: #5F7183;

  --ink: var(--navy-700);
  --ink-strong: var(--navy-800);
  --ink-muted: var(--grey-500);
  --ground: #fff;
  --surface: #fff;
  --surface-alt: var(--grey-050);
  --line: var(--grey-200);
  --line-strong: var(--grey-300);
  --action: var(--blue-600);
  --action-hover: var(--blue-700);
  --action-ink: #fff;
  --action-wash: rgba(40, 95, 159, .06);
  --focus: var(--blue-600);

  --ok-bg: #E7F4EA;   --ok-line: #BFE3C6;   --ok-ink: #1D6B2F;
  --warn-bg: #FFF4E0; --warn-line: #F0DDB8; --warn-ink: #8A5A00;
  --err-bg: #FBEAEA;  --err-line: #EECCCC;  --err-ink: #A4262C;

  --font: 'Montserrat', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --step--1: .875rem;
  --step-0: 1rem;
  --step-1: 1.125rem;
  --step-2: 1.375rem;
  --step-3: 1.75rem;
  --step-4: 2.1875rem;
  --lh-tight: 1.2;
  --lh-body: 1.65;

  --sp-1: .25rem; --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.5rem; --sp-6: 2rem;   --sp-7: 3rem;   --sp-8: 4rem;

  --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-pill: 999px;
  --shadow-1: 0 1px 3px rgba(20, 46, 67, .08);
  --shadow-2: 0 4px 12px rgba(20, 46, 67, .10);
  --dur: 160ms;
  --ease: cubic-bezier(.2, .6, .3, 1);

  --measure: 68ch;
  --width: 1080px;
  --width-narrow: 620px;
  --width-wide: 1320px;
}

/* ---- base ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { line-height: var(--lh-tight); margin: 0 0 var(--sp-3); font-weight: 700; }
p { margin: 0 0 var(--sp-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--action); }
a:hover { color: var(--action-hover); }

img, svg { max-width: 100%; }
img { height: auto; }

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.icon { width: 1.15em; height: 1.15em; flex: none; }

/* A closed disclosure stays closed.
   Components style what is inside their own <details> — `.rolechange form` and
   `.actions` both set `display` — and those author rules can outrank the
   browser's hiding of collapsed content. When that happens the panel keeps its
   box, spills past the summary, and paints on top of whatever follows: on the
   learner record one form landed squarely over the next button. Saying it once
   here keeps every disclosure honest, whatever a component sets on its
   children. The open state is styled with `[open]`, which outranks this. */
details:not([open]) > *:not(summary) { display: none; }

/* ---- utilities ----------------------------------------------------------- */
/* public/launcher.js shows the certificate button by removing this class, so it
   has to beat the component rules that set `display` — .btn is declared later in
   this file and would otherwise win on source order. */
.hidden { display: none !important; }
.muted { color: var(--ink-muted); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: var(--sp-4); top: -100px; z-index: 100;
  background: var(--surface); color: var(--ink);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sm);
  box-shadow: var(--shadow-2); text-decoration: none;
  transition: top var(--dur) var(--ease);
}
.skip:focus { top: var(--sp-4); }

.linkish {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  background: none; border: 0; padding: 0;
  font: inherit; color: var(--action); cursor: pointer;
  text-decoration: none;
}
.linkish:hover { color: var(--action-hover); text-decoration: underline; }
.linkish--sm { font-size: var(--step--1); }

/* ---- page chrome --------------------------------------------------------- */
.masthead { border-bottom: 1px solid var(--line); background: var(--surface); }
.masthead__inner {
  max-width: var(--width); margin: 0 auto;
  padding: var(--sp-4) var(--sp-5);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  flex-wrap: wrap;
}
.masthead__brand { display: inline-flex; line-height: 0; }
.masthead__brand img { width: 260px; height: auto; }
.masthead__nav { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.masthead__lang { margin: 0; }
.masthead--admin .masthead__title { font-size: var(--step-2); margin: 0; }
.masthead--admin .masthead__sub { margin: 0; color: var(--ink-muted); font-size: var(--step--1); }

main { max-width: var(--width); margin: 0 auto; padding: var(--sp-6) var(--sp-5) var(--sp-8); }
main.narrow { max-width: var(--width-narrow); }
main.wide { max-width: var(--width-wide); }

.site-footer { border-top: 1px solid var(--line); background: var(--surface-alt); }
.site-footer__inner {
  max-width: var(--width); margin: 0 auto;
  padding: var(--sp-5); color: var(--ink-muted); font-size: var(--step--1);
}
.site-footer__meta { margin: var(--sp-2) 0 0; }

.page__title { font-size: var(--step-4); }
.page__lead { max-width: var(--measure); color: var(--ink-muted); margin-bottom: var(--sp-6); }
/* Two buttons that together run just wider than the narrow column, so the
   second wraps. As inline boxes they wrapped flush against each other with no
   space at all; a flex row keeps the gap whether they sit side by side or
   stack. */
.page__cta {
  margin-top: var(--sp-6);
  display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center;
}

/* ---- card ---------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  box-shadow: var(--shadow-1);
}
.card--center { text-align: center; }
.card__title { font-size: var(--step-3); }
.card__lead { color: var(--ink-muted); max-width: var(--measure); }
.card--center .card__lead { margin-left: auto; margin-right: auto; }

.panel {
  margin-top: var(--sp-7);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line);
}
.panel__title { font-size: var(--step-2); margin-bottom: var(--sp-2); }
.panel__lead { color: var(--ink-muted); font-size: var(--step--1); }
.panel__eyebrow {
  font-size: var(--step--1); font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--sp-2);
}
.panel--next {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: var(--sp-5); margin-top: var(--sp-5);
}

.actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-5); }
.card--center .actions { justify-content: center; }

/* ---- buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 44px;
  padding: var(--sp-3) var(--sp-5);
  border: 1.5px solid transparent;
  border-radius: var(--r-pill);
  font: inherit; font-weight: 600; line-height: 1.2;
  text-decoration: none; cursor: pointer;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn--primary { background: var(--action); color: var(--action-ink); }
.btn--primary:hover { background: var(--action-hover); color: var(--action-ink); }
.btn--ghost { background: transparent; color: var(--action); border-color: var(--action); }
.btn--ghost:hover { background: var(--action-wash); color: var(--action-hover); }
.btn--quiet { background: var(--surface-alt); color: var(--ink); border-color: var(--line); }
.btn--quiet:hover { background: var(--grey-100); color: var(--ink); }
.btn--block { width: 100%; }
.btn--sm { min-height: 36px; padding: var(--sp-2) var(--sp-4); font-size: var(--step--1); }

/* ---- alerts -------------------------------------------------------------- */
.alert {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-4); border-radius: var(--r-md);
  border: 1px solid; margin-bottom: var(--sp-5);
}
.alert--error { background: var(--err-bg); border-color: var(--err-line); color: var(--err-ink); }
.alert--success { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-ink); }
.alert .icon { margin-top: .15em; }

/* ---- forms --------------------------------------------------------------- */
.field { margin-bottom: var(--sp-5); }
.field label, fieldset legend { display: block; font-weight: 600; margin-bottom: var(--sp-2); }
.field__tag {
  font-weight: 400; font-size: var(--step--1); color: var(--ink-muted);
}
.field__note { margin: var(--sp-2) 0 0; font-size: var(--step--1); color: var(--ink-muted); }
.field__note--suggest { color: var(--warn-ink); }

/* Two fields on one line: first/last name, city/state. Collapses at 640px with
   the rest of the form. */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.field-row--state { grid-template-columns: 2fr 1fr; }

/* ---- combobox ------------------------------------------------------------ */
/* The organization search: a text input with a suggestion listbox floated
   beneath it. Free text is always valid — the list offers, never gates. */
.combo { position: relative; }
.combo__list {
  position: absolute; z-index: 40; left: 0; right: 0;
  margin: 2px 0 0; padding: var(--sp-1); list-style: none;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-2);
  max-height: 260px; overflow-y: auto;
}
.combo__option {
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm);
  cursor: pointer; font-size: var(--step--1);
}
.combo__option:hover, .combo__option[aria-selected="true"] {
  background: var(--action-wash); color: var(--action-hover);
}

/* The four password requirements. Unmet is the resting state — a fresh field
   shows all four as things still to do, not as failures, so there is no red on a
   form nobody has typed into yet. */
.pwrules { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: grid; gap: var(--sp-1); }
.pwrule {
  position: relative; padding-left: 22px;
  font-size: var(--step--1); color: var(--ink-muted);
}
.pwrule::before {
  content: ""; position: absolute; left: 4px; top: .45em;
  width: 8px; height: 8px; border-radius: 50%;
  border: 1.5px solid var(--line-strong); box-sizing: border-box;
}
.pwrule[data-met] { color: var(--ok-ink); }
.pwrule[data-met]::before {
  border-color: var(--ok-ink); background: var(--ok-ink);
}

.consent { margin-top: var(--sp-5); }
.consent__box {
  display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3);
  align-items: start; font-weight: 400; margin-bottom: var(--sp-2);
  font-size: var(--step--1); line-height: var(--lh-body); cursor: pointer;
}
.consent__box input { margin: .2em 0 0; width: 20px; height: 20px; accent-color: var(--action); flex: none; }
.consent__box:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 4px; border-radius: var(--r-sm); }
/* The same control at field scale — an alternative answer to the field above it,
   not a term to agree to. */
.consent__box--quiet { margin-top: var(--sp-3); font-size: var(--step--1); color: var(--ink-muted); }
.consent__box--quiet input { width: 16px; height: 16px; }

.entry__who {
  display: flex; align-items: center; gap: var(--sp-2);
  margin: 0 0 var(--sp-4); font-size: var(--step--1); color: var(--ink-muted);
}
.entry__who span { font-weight: 600; color: var(--ink); }

select {
  width: 100%; min-height: 48px; padding: var(--sp-3) var(--sp-4);
  font: inherit; font-size: var(--step-0); color: var(--ink);
  background: var(--surface); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
}
select:hover { border-color: var(--ink-muted); }
select:focus { border-color: var(--action); }

input[type="password"] {
  display: block; width: 100%; min-height: 48px; padding: var(--sp-3) var(--sp-4);
  font: inherit; font-size: var(--step-0); color: var(--ink);
  background: var(--surface); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
}
input[type="password"]:hover { border-color: var(--ink-muted); }
input[type="password"]:focus { border-color: var(--action); }

input[type="text"], input[type="email"], input[type="search"] {
  display: block; width: 100%;
  min-height: 48px;
  padding: var(--sp-3) var(--sp-4);
  font: inherit; color: var(--ink);
  background: var(--ground);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
input[type="text"]:hover, input[type="email"]:hover { border-color: var(--ink-muted); }
input[type="text"]:focus, input[type="email"]:focus, input[type="search"]:focus {
  outline: none; border-color: var(--action);
  box-shadow: 0 0 0 3px var(--action-wash);
}
input::placeholder { color: var(--ink-muted); opacity: .8; }

fieldset { border: 0; padding: 0; margin: 0 0 var(--sp-5); }
fieldset legend { padding: 0; }

/* role picker */
.roles__grid { display: grid; gap: var(--sp-3); margin-top: var(--sp-3); }
.role {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: var(--sp-3); align-items: start;
  padding: var(--sp-4);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.role:hover { border-color: var(--line-strong); background: var(--surface-alt); }
.role input { margin: .3em 0 0; width: 20px; height: 20px; accent-color: var(--action); flex: none; }
.role__text { display: block; }
.role__label { display: block; font-weight: 600; }
.role__hint { display: block; font-size: var(--step--1); color: var(--ink-muted); margin-top: var(--sp-1); }
.role__badge {
  align-self: center; white-space: nowrap;
  font-size: var(--step--1); font-weight: 600;
  color: var(--ink-muted); background: var(--surface-alt);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: var(--sp-1) var(--sp-3);
}
.role:has(input:checked) {
  border-color: var(--action); background: var(--action-wash);
  box-shadow: inset 0 0 0 1px var(--action);
}
.role:has(input:checked) .role__badge { color: var(--action); border-color: var(--action); background: var(--surface); }
.role:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }

/* language toggle */
.segmented__track {
  display: inline-flex; gap: var(--sp-1); margin-top: var(--sp-2);
  padding: var(--sp-1);
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.segmented__option { position: relative; margin: 0; }
.segmented__option input {
  position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer;
}
.segmented__option span {
  display: block; padding: var(--sp-2) var(--sp-5);
  border-radius: var(--r-pill); font-size: var(--step--1); font-weight: 600;
  color: var(--ink-muted);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.segmented__option input:checked + span { background: var(--action); color: var(--action-ink); }
.segmented__option input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 2px; }

/* ---- entry page ----------------------------------------------------------
   Split hero: brand panel left, sign-in column right. This page has no masthead
   — the panel is the brand — so it is the one <main> that goes full bleed. The
   card column is a fixed 460px because the field inside it should not stretch
   to a 1400px monitor. */
/* Two thirds / one third. Fractional rather than a fixed 460px column so the
   split holds its proportion on any monitor. The 360px floor only bites below
   1080px, where a true third would leave the selects too narrow; the padding
   drops at the same point so the form still gains room rather than losing it. */
.entry {
  max-width: none;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(360px, 1fr);
  min-height: 100vh;
  min-height: 100svh;
}

/* Sticky and sized to the viewport rather than stretched to the row. Revealing
   the registration fieldset makes the card column ~2000px tall; without this the
   panel grows to match and the mission ends up marooned in the middle of it. */
.hero {
  position: sticky;
  top: 0;
  align-self: start;
  min-height: 100vh;
  min-height: 100svh;
  background: var(--navy-900);
  color: #fff;
  padding: var(--sp-7) var(--sp-7) var(--sp-6);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--sp-7);
}
/* The panel is two thirds of the screen but the copy inside it is measured, so
   left-aligning everything piles all the leftover navy against the card. Centre
   the content as one column instead, and the gap splits evenly either side. The
   brand, the copy and the stats share a max-width so their left edges line up. */
.hero > * { width: 100%; max-width: 760px; margin-inline: auto; }

.hero__brand { display: inline-flex; line-height: 0; }
.hero__brand img { width: 260px; height: auto; }
/* Everything on the navy panel is white — full white for what must be read,
   translucent white for what supports it. Never cyan or a blue-grey: on navy
   those read as blue-on-blue, and this app is blue and white only. */
.hero__eyebrow {
  font-size: var(--step--1); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: rgba(255, 255, 255, .8); margin-bottom: var(--sp-3);
}
/* Measured so the headline wraps to three or four lines instead of running the
   full width of the panel. ch is relative to the font size it sits at, so this
   holds its shape when --step-3 takes over on small screens. */
.hero__title { font-size: 2.375rem; max-width: 30ch; margin-bottom: var(--sp-4); color: #fff; }
.hero__lead { color: rgba(255, 255, 255, .85); max-width: 70ch; line-height: var(--lh-body); margin: 0; }

/* Centred, and each tile centred over its own label. Two tiles left of a wide
   panel read as an unfinished row, so this block breaks the shared left edge
   above it on purpose. */
.hero__stats {
  list-style: none; display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--sp-6); margin: 0 0 var(--sp-5); padding: 0;
}
.hero__stats li { color: rgba(255, 255, 255, .8); font-size: var(--step--1); text-align: center; }
.hero__stats b { display: block; font-size: var(--step-3); color: #fff; line-height: 1.1; }
/* The languages tile names the languages instead of counting them, so its value
   is a phrase, not a numeral. The view breaks it as "English and" / "Spanish"
   with a newline that pre-line renders, and it sits a touch larger so the tile
   holds its own beside the numerals. */
.hero__stat--wide b { font-size: var(--step-1); white-space: pre-line; }
.hero__note { color: rgba(255, 255, 255, .66); font-size: var(--step--1); margin: 0; max-width: 70ch; }
.hero__copyright { margin-top: var(--sp-3); }

.entry__card {
  background: #fff;
  color: var(--ink);
  padding: var(--sp-7);
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* The column is a third of the screen, but the form inside it should not be —
     an email field 600px wide on a large monitor looks broken. Cap the content
     and centre it in whatever the column turns out to be. */
  align-items: center;
}
.entry__card > * { width: 100%; max-width: 460px; }
.entry__eyebrow {
  font-size: var(--step--1); font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--sp-2);
}
.entry__title { font-size: var(--step-3); }
.entry__lead { color: var(--ink-muted); margin-bottom: var(--sp-5); }
.entry__form { margin-top: var(--sp-5); }
.entry__alt { margin-top: var(--sp-4); text-align: center; font-size: var(--step--1); }
.entry__note { margin: var(--sp-4) 0 0; text-align: center; font-size: var(--step--1); color: var(--ink-muted); }
.entry__links {
  display: flex; justify-content: center; gap: var(--sp-5);
  margin-top: var(--sp-6); padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}
.entry__links .masthead__lang { margin: 0; }
.reg { margin: 0; }

/* ---- training history ---------------------------------------------------- */
.history { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.history__row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-3) 0; border-top: 1px solid var(--line);
}
.history__row:first-child { border-top: 0; padding-top: 0; }
.history__course { margin: 0; font-weight: 600; }
.history__date { margin: 2px 0 0; color: var(--ink-muted); font-size: var(--step--1); }

/* ---- profile ------------------------------------------------------------- */
.profile__role { margin-top: var(--sp-5); }
.profile__details { margin: var(--sp-4) 0 0; }
.profile__row {
  display: grid; grid-template-columns: 12rem minmax(0, 1fr);
  gap: var(--sp-3); padding: var(--sp-3) 0; border-top: 1px solid var(--line);
}
.profile__row:first-child { border-top: 0; padding-top: 0; }
.profile__row dt { color: var(--ink-muted); font-size: var(--step--1); }
.profile__row dd { margin: 0; }
@media (max-width: 640px) {
  .profile__row { grid-template-columns: minmax(0, 1fr); gap: var(--sp-1); }
}

/* ---- learning path (design 1a) ------------------------------------------
   Summary panel beside a stack of step cards, from the Training Path handoff.

   The handoff's palette runs a shade cooler than the site's own tokens
   (#1e3a6e against --navy-700 #1D4363). Those values are kept here, scoped to
   this page, rather than edited into :root — the global tokens are mirrored in
   src/brand.js for the certificate PDF, and quietly shifting them would repaint
   the whole product and every certificate to match one screen. */
.tp {
  --tp-navy: #1e3a6e;
  --tp-blue: #2a4d8f;
  --tp-ink: #33415e;
  --tp-soft: #5a6b8c;
  --tp-muted: #8a97b2;
  --tp-quiet: #7d8cab;
  --tp-line: #e6eaf1;
  --tp-outline: #c6d1e6;
  --tp-hover: #b9c6e0;
  --tp-track: #dde3ee;
  --tp-tint: #f4f7fd;
  --tp-panel: #f7f9fc;
  --tp-chip: #f1f4fa;
}

.tp__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  gap: 40px; align-items: start;
}
.tp__main { min-width: 0; }

.tp__eyebrow {
  font-size: 13px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--tp-quiet); font-weight: 700; margin: 0 0 6px;
}
.tp__title { font-size: 30px; color: var(--tp-navy); margin: 0 0 6px; }
.tp__lead { color: var(--tp-soft); font-size: 15px; margin: 0 0 12px; }
.tp__role { font-size: 14px; font-weight: 700; color: var(--tp-navy); margin: 0 0 10px; }

/* ---- minimum recommendations, every discipline ----
   Folded away rather than printed out: to somebody who already knows which
   modules are theirs it is one quiet line, and to somebody who does not it is
   the whole table, one click away and never a second page to go find. */
.tp-recs { margin: 0 0 28px; }
.tp-recs__summary {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13.5px; font-weight: 600; color: var(--tp-blue);
  cursor: pointer; list-style: none; padding: 4px 0;
}
.tp-recs__summary::-webkit-details-marker { display: none; }
.tp-recs__summary::before {
  content: ""; width: .42rem; height: .42rem; flex: none;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-1px) rotate(-45deg);
  transition: transform var(--dur) var(--ease);
}
.tp-recs[open] .tp-recs__summary::before { transform: translateY(-2px) rotate(45deg); }
.tp-recs__summary:hover { color: var(--tp-navy); }
.tp-recs__summary:focus-visible { outline: 2px solid var(--tp-blue); outline-offset: 3px; border-radius: 4px; }

.tp-recs__list {
  list-style: none; margin: 10px 0 0; padding: 0;
  border-top: 1px solid var(--tp-line);
}
.tp-recs__item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 16px; align-items: center;
  padding: 12px 0; border-bottom: 1px solid var(--tp-line);
}
/* The reader's own discipline, marked without shouting. */
.tp-recs__item[data-mine="true"] {
  box-shadow: inset 2px 0 0 var(--tp-blue); padding-left: 12px;
}
.tp-recs__role { grid-column: 1; font-size: 14px; font-weight: 700; color: var(--tp-ink); margin: 0; }
.tp-recs__hint { grid-column: 1; font-size: 12.5px; color: var(--tp-muted); margin: 0; }
.tp-recs__modules {
  grid-column: 2; grid-row: 1 / span 2; justify-self: end;
  font-size: 13px; font-weight: 700; color: var(--tp-navy); white-space: nowrap;
  background: var(--tp-chip); border-radius: 12px; padding: 4px 12px; margin: 0;
}
.tp-recs__tag {
  display: inline-block; font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; font-weight: 700; color: var(--tp-blue);
  background: var(--surface); border: 1px solid var(--tp-outline);
  border-radius: 10px; padding: 0 7px; margin-left: 8px; vertical-align: 1px;
}

/* ---- step cards ---- */
.tp-cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.tp-card {
  border: 1px solid var(--tp-line); border-radius: 10px; padding: 18px 24px;
  display: flex; gap: 18px; align-items: center; background: var(--surface);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tp-card:hover { border-color: var(--tp-hover); box-shadow: 0 2px 10px rgba(30, 58, 110, .08); }

/* The one step the learner is on, opened out. */
.tp-card[data-state="current"] {
  border: 1.5px solid var(--tp-blue); background: var(--tp-tint); padding: 20px 24px;
}
.tp-card[data-state="done"] { background: var(--surface); }

.tp-card__marker {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  border: 2px solid var(--tp-track); color: var(--tp-muted); font-weight: 700;
}
.tp-card__marker .icon { width: 1.1rem; height: 1.1rem; }
.tp-card[data-state="current"] .tp-card__marker {
  background: var(--tp-navy); border-color: var(--tp-navy); color: #fff;
}
.tp-card[data-state="done"] .tp-card__marker {
  background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-ink);
}

.tp-card__body { flex: 1; min-width: 0; }
.tp-card__eyebrow {
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 700; color: var(--tp-muted); margin: 0;
}
.tp-card[data-state="current"] .tp-card__eyebrow { color: var(--tp-blue); }
.tp-card__title { font-size: 17px; font-weight: 700; color: var(--tp-ink); margin: 2px 0 0; }
.tp-card[data-state="current"] .tp-card__title { font-size: 18px; color: var(--tp-navy); margin-bottom: 8px; }

.tp-card__bar { height: 6px; background: var(--tp-track); border-radius: 3px; width: 70%; max-width: 320px; }
.tp-card__bar-fill { height: 6px; background: var(--tp-blue); border-radius: 3px; }

/* Prerequisites are advice, and the chip is deliberately quiet — it replaced an
   amber warning that read as an error beside a button that always worked. */
.tp-card__chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--tp-soft); background: var(--tp-chip);
  border-radius: 12px; padding: 3px 10px; margin: 6px 0 0;
}
.tp-card__chip .icon { width: .95rem; height: .95rem; }
.tp-card__meta { font-size: 12.5px; color: var(--tp-muted); margin: 6px 0 0; }

.tp-card__actions { display: flex; align-items: center; gap: var(--sp-2); flex: none; flex-wrap: wrap; }
.tp-card__actions form { margin: 0; }

/* ---- pill buttons ---- */
.tp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  border-radius: 24px; font-family: inherit; font-size: 14px; font-weight: 600;
  padding: 9px 20px; text-decoration: none; cursor: pointer; white-space: nowrap;
  border: 1.5px solid transparent; transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.tp-btn--solid { background: var(--tp-navy); color: #fff; font-size: 15px; padding: 10px 22px; }
.tp-btn--solid:hover { background: #16305d; color: #fff; }
.tp-btn--outline { background: var(--surface); color: var(--tp-blue); border-color: var(--tp-outline); }
.tp-btn--outline:hover { border-color: var(--tp-hover); color: var(--tp-blue); }
.tp-btn--quiet { background: none; color: var(--tp-soft); border-color: transparent; }
.tp-btn--quiet:hover { color: var(--tp-navy); }
.tp-btn--block { width: 100%; padding-left: 0; padding-right: 0; font-weight: 700; }
.tp-btn .icon { width: 1rem; height: 1rem; }

/* ---- summary panel ---- */
/* margin-top drops the panel to sit level with the first card rather than the
   heading, as drawn. It only applies once the two columns are side by side. */
.tp-summary {
  background: var(--tp-panel); border: 1px solid var(--tp-line);
  border-radius: 12px; padding: 26px; height: fit-content; margin-top: 96px;
}
.tp-ring {
  width: 110px; height: 110px; border-radius: 50%; margin: 0 auto 14px;
  display: grid; place-items: center;
  background: conic-gradient(var(--tp-blue) 0 var(--tp-ring-deg, 0deg), var(--tp-track) var(--tp-ring-deg, 0deg) 360deg);
}
.tp-ring__inner {
  width: 86px; height: 86px; border-radius: 50%; background: var(--tp-panel);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.tp-ring__pct { font-size: 24px; font-weight: 700; color: var(--tp-navy); line-height: 1.1; }
.tp-ring__label { font-size: 11px; color: var(--tp-muted); }
.tp-summary__count { text-align: center; font-size: 14px; color: var(--tp-soft); margin: 0 0 18px; }
.tp-summary__count b { color: var(--tp-navy); }
.tp-summary__actions {
  border-top: 1px solid var(--tp-line); padding-top: 16px;
  display: flex; flex-direction: column; gap: 10px;
}

/* ---- optional modules ---- */
/* Outside the recommended track, so it sits below the path under its own rule. */
.tp-optional { margin-top: var(--sp-7); padding-top: var(--sp-6); border-top: 1px solid var(--tp-line); }
.tp-optional__title { font-size: var(--step-2); color: var(--tp-navy); margin-bottom: var(--sp-2); }
.tp-optional__lead { color: var(--tp-soft); font-size: var(--step--1); margin-bottom: var(--sp-4); }

@media (max-width: 900px) {
  .tp__grid { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
  /* Nothing left to align with once the panel is full width. */
  .tp-summary { margin-top: 0; order: -1; }
}
@media (max-width: 560px) {
  .tp-recs__item { grid-template-columns: minmax(0, 1fr); }
  .tp-recs__modules { grid-column: 1; grid-row: auto; justify-self: start; margin-top: 6px; }
  .tp-card { flex-wrap: wrap; padding: 16px 18px; }
  .tp-card__actions { width: 100%; }
  .tp-btn { flex: 1 1 auto; }
  .tp__title { font-size: var(--step-3); }
}

/* ---- completion ---------------------------------------------------------- */
.done__mark {
  width: 72px; height: 72px; border-radius: 50%;
  display: grid; place-items: center; margin: 0 auto var(--sp-5);
}
.done__mark .icon { width: 2rem; height: 2rem; }
.done__mark[data-state="done"] { background: var(--ok-bg); color: var(--ok-ink); }
.done__mark[data-state="saved"] { background: var(--warn-bg); color: var(--warn-ink); }
.done__course { font-weight: 600; }

/* ---- help ---------------------------------------------------------------- */
.faq { display: grid; gap: var(--sp-5); }
.faq__item {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); padding: var(--sp-5);
}
.faq__q { font-size: var(--step-1); margin-bottom: var(--sp-2); }
.faq__a { color: var(--ink-muted); max-width: var(--measure); margin: 0; }

/* ---- player -------------------------------------------------------------- */
.player { display: flex; flex-direction: column; height: 100vh; background: var(--navy-900); }
.player__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); padding: var(--sp-3) var(--sp-4);
  background: var(--navy-800); color: #fff; flex: none;
}
.player__title { display: flex; align-items: center; gap: var(--sp-4); min-width: 0; }
.player__home { display: inline-flex; align-items: center; gap: var(--sp-2); color: rgba(255, 255, 255, .85); text-decoration: none; flex: none; }
.player__home:hover { color: #fff; }
.player__course {
  font-weight: 600; font-size: var(--step--1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.player__actions { display: flex; align-items: center; gap: var(--sp-3); flex: none; }
.player__learner { color: rgba(255, 255, 255, .85); font-size: var(--step--1); }
.player__frame { flex: 1; width: 100%; border: 0; background: #fff; }
.player .btn--ghost { color: #fff; border-color: rgba(255, 255, 255, .5); }
.player .btn--ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.player .btn--quiet { background: rgba(255, 255, 255, .12); color: #fff; border-color: transparent; }
.player .btn--quiet:hover { background: rgba(255, 255, 255, .2); color: #fff; }

/* ---- admin --------------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-4); }
.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--sp-4);
}
.stat__num { font-size: var(--step-3); font-weight: 700; line-height: 1.1; }
.stat__total { font-size: var(--step-0); color: var(--ink-muted); font-weight: 400; }
.stat__label { color: var(--ink); font-size: var(--step--1); margin: var(--sp-1) 0 0; }
.stat__note { color: var(--ink-muted); font-size: var(--step--1); margin: 2px 0 0; }

/* Staff toolbar. The global input/select rules are sized for learners on
   phones — 48px tall, full width — which in a filter row made every control a
   slab and pushed the selects onto their own line. Here the controls are
   compact and stay inline; the touch sizing still applies everywhere a learner
   fills in a form. */
.toolbar {
  display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}
.toolbar__search { flex: 1 1 240px; }
.toolbar input[type="search"], .toolbar select {
  width: auto; min-height: 0; height: 36px;
  padding: 0 var(--sp-3); font: inherit; font-size: var(--step--1);
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
}
.toolbar select { padding-right: var(--sp-2); max-width: 190px; }
.toolbar input[type="search"]:focus, .toolbar select:focus-visible {
  outline: none; border-color: var(--action); box-shadow: 0 0 0 3px var(--action-wash);
}
.toolbar .btn { height: 36px; }
/* The exports are secondary to filtering — push them to the far end. */
.toolbar__end { margin-left: auto; display: flex; gap: var(--sp-2); flex-wrap: wrap; }

.table-wrap { overflow-x: auto; }
.nowrap { white-space: nowrap; }
.warnish { color: var(--warn-ink); }

.roster__name { font-weight: 600; text-decoration: none; }
.roster__name:hover { text-decoration: underline; }
.roster__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-4);
  font-size: var(--step--1);
}
.roster__pages { display: flex; gap: var(--sp-2); }
.btn.is-disabled { color: var(--line-strong); pointer-events: none; }

/* Row-level progress. Narrower and quieter than .progress, which is the
   learner's own headline number. */
.meter { display: flex; align-items: center; gap: var(--sp-3); }
.meter__track {
  width: 120px; height: 6px; border-radius: var(--r-pill);
  background: var(--grey-200); overflow: hidden; flex: none;
}
.meter__fill { height: 100%; border-radius: var(--r-pill); background: var(--action); }
.meter__label { white-space: nowrap; }

/* ---- admin: one learner ------------------------------------------------- */
.backlink { margin-bottom: var(--sp-4); font-size: var(--step--1); }
.record__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-5);
}
.record__head .page__title { margin-bottom: var(--sp-1); }
.record__head .actions { margin-top: 0; }
.record__role { font-size: var(--step--1); }

.records { display: flex; flex-direction: column; gap: var(--sp-3); margin: var(--sp-6) 0; }
.record {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-4);
  align-items: center; padding: var(--sp-4) var(--sp-5);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
}
.record__title { font-weight: 600; margin: 0 0 var(--sp-1); }
.record__meta { color: var(--ink-muted); font-size: var(--step--1); margin: 0; }
.record__side { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }

.rolechange { margin-bottom: var(--sp-6); }
.rolechange summary { display: inline-flex; list-style: none; cursor: pointer; }
.rolechange summary::-webkit-details-marker { display: none; }
/* Scoped to [open] so it cannot resurrect a collapsed panel — see the
   `details:not([open])` rule in the base layer. */
.rolechange[open] form {
  display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap;
  margin-top: var(--sp-4); padding: var(--sp-4);
  background: var(--surface-alt); border: 1px solid var(--line); border-radius: var(--r-md);
}
.rolechange .field__note { flex: 1 0 100%; margin: 0; }
.rolechange select {
  flex: 1 1 320px; min-height: 44px; padding: var(--sp-2) var(--sp-3);
  font: inherit; font-size: var(--step--1); color: var(--ink);
  background: var(--surface); border: 1.5px solid var(--line-strong); border-radius: var(--r-md);
}

.record__head .actions form { margin: 0; }
.resetlink {
  display: inline-block; margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: var(--step--1);
  word-break: break-all; user-select: all;
}

.trail { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.trail li { font-size: var(--step--1); color: var(--ink-muted); }

/* ---- admin: email studio ------------------------------------------------- */
textarea {
  display: block; width: 100%;
  padding: var(--sp-3) var(--sp-4);
  font: inherit; color: var(--ink);
  background: var(--ground);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  resize: vertical;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
textarea:hover { border-color: var(--ink-muted); }
textarea:focus { outline: none; border-color: var(--action); box-shadow: 0 0 0 3px var(--action-wash); }

.studio {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--sp-6); align-items: start; margin-top: var(--sp-5);
}
.studio__tabs {
  display: flex; gap: var(--sp-5); flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  margin-bottom: var(--sp-5);
}
.studio__form .field label { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.studio__vars { display: inline-flex; gap: var(--sp-1); flex-wrap: wrap; margin-left: auto; }
.studio__var {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .72rem; font-weight: 400;
  color: var(--ink-muted); background: var(--surface-alt);
  border: 1px solid var(--line); border-radius: var(--r-pill); padding: 0 8px;
}
.studio__edited {
  font-size: .68rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--action); border: 1px solid var(--action);
  border-radius: var(--r-pill); padding: 0 8px;
}
.studio__reset { margin-top: var(--sp-4); }
.studio__test { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-3); }
.studio__test input { flex: 1 1 260px; width: auto; }
.studio__mailoff { color: var(--warn-ink); }
.studio__preview { position: sticky; top: var(--sp-4); }
.studio__preview .preview__frame { height: 760px; }

@media (max-width: 1100px) {
  .studio { grid-template-columns: minmax(0, 1fr); }
  .studio__preview { position: static; }
}

/* ---- review mode ----------------------------------------------------------
   Injected for invited reviewers only. Blue and white like everything else:
   blue pins with white numerals, white cards with blue accents. The layer is
   pointer-events:none so it never blocks the page (or the course iframe);
   only the pins and composer re-enable themselves. */
.review-layer {
  position: absolute; top: 0; left: 0; width: 100%;
  pointer-events: none; z-index: 900;
}
.review-pin {
  position: absolute; transform: translate(-50%, -50%);
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--action); color: #fff;
  border: 2px solid #fff; box-shadow: var(--shadow-2);
  font: 700 .8rem/1 var(--font); cursor: pointer;
  pointer-events: auto;
}
.review-pin:hover { background: var(--action-hover); }
.review-pin--done { background: var(--grey-300); color: var(--ink); }

.review-trigger {
  position: fixed; right: var(--sp-5); bottom: var(--sp-5); z-index: 920;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 44px; padding: var(--sp-3) var(--sp-5);
  background: var(--action); color: #fff;
  border: 0; border-radius: var(--r-pill);
  font: 600 var(--step--1)/1.2 var(--font); cursor: pointer;
  box-shadow: var(--shadow-2);
}
.review-trigger:hover { background: var(--action-hover); }
.review-trigger__count {
  background: #fff; color: var(--action);
  border-radius: var(--r-pill); padding: 1px 8px; font-size: .72rem;
}
.review-trigger--bar .review-trigger__count { background: rgba(255, 255, 255, .2); color: #fff; }

.review-banner {
  position: fixed; top: var(--sp-4); left: 50%; transform: translateX(-50%);
  z-index: 940; max-width: min(92vw, 480px); text-align: center;
  background: var(--navy-800); color: #fff;
  padding: var(--sp-3) var(--sp-5); border-radius: var(--r-pill);
  font-size: var(--step--1); box-shadow: var(--shadow-2);
}
.review-shield {
  position: fixed; z-index: 930;
  display: grid; place-items: center; text-align: center;
  background: rgba(255, 255, 255, .85); color: var(--ink);
  border: 2px dashed var(--line-strong);
  font-size: var(--step--1); padding: var(--sp-5);
}
body.review-pinning { cursor: crosshair; }
body.review-pinning a, body.review-pinning button:not([data-review-ui]) { cursor: crosshair; }

.review-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 950;
  width: min(360px, 92vw);
  background: #fff; border-left: 1px solid var(--line); box-shadow: var(--shadow-2);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform var(--dur) var(--ease);
}
.review-panel--open { transform: translateX(0); }
.review-panel__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line);
}
.review-panel__who { margin: 0; font-weight: 600; font-size: var(--step--1); color: var(--ink); }
.review-panel__close {
  background: none; border: 0; cursor: pointer;
  font-size: 1.4rem; line-height: 1; color: var(--ink-muted); padding: var(--sp-1);
}
.review-panel__close:hover { color: var(--ink); }
.review-panel__actions {
  display: grid; gap: var(--sp-2); padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line);
}
.review-panel__list { overflow-y: auto; padding: var(--sp-4) var(--sp-5); flex: 1; }

.review-btn {
  min-height: 40px; padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-pill); border: 1.5px solid var(--action);
  background: #fff; color: var(--action);
  font: 600 var(--step--1)/1.2 var(--font); cursor: pointer;
}
.review-btn:hover { background: var(--action-wash); }
.review-btn--primary { background: var(--action); color: #fff; }
.review-btn--primary:hover { background: var(--action-hover); }
.review-btn[disabled] { opacity: .6; cursor: default; }
.review-linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--action); font: inherit; font-size: var(--step--1);
}
.review-linkish:hover { color: var(--action-hover); text-decoration: underline; }

.review-row { padding: var(--sp-3) 0; border-bottom: 1px solid var(--line); }
.review-row__head {
  display: flex; align-items: center; gap: var(--sp-2);
  margin: 0 0 var(--sp-1); font-size: .72rem; color: var(--ink-muted);
}
.review-row__num {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--action); color: #fff; font-weight: 700; flex: none;
}
.review-row__done {
  margin-left: auto; text-transform: uppercase; letter-spacing: .04em;
  font-weight: 600; color: var(--ok-ink);
}
.review-row__body { margin: 0; font-size: var(--step--1); white-space: pre-wrap; }
.review-row__tools { display: flex; gap: var(--sp-4); margin: var(--sp-2) 0 0; }
.review-row--flash { background: var(--action-wash); }
.review-empty { color: var(--ink-muted); font-size: var(--step--1); }

.review-composer {
  position: absolute; z-index: 960; width: 330px; max-width: 92vw;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-2); padding: var(--sp-4);
  pointer-events: auto;
}
.review-composer__title {
  margin: 0 0 var(--sp-2); font-size: .78rem; font-weight: 600; color: var(--ink-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.review-edit {
  width: 100%; min-height: 84px; margin-bottom: var(--sp-2);
  font-size: var(--step--1);
}

/* ---- admin: review inbox -------------------------------------------------- */
.review-inbox__mint { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.review-inbox__mint input { flex: 1 1 260px; width: auto; }
.review-inbox__anchor {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .78rem;
  background: var(--surface-alt); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 1px 6px;
}
.review-inbox__anchor--page { font-family: var(--font); color: var(--ink-muted); }
.review-inbox__body { margin: var(--sp-2) 0; white-space: pre-wrap; }

/* ---- admin: reminder preview -------------------------------------------- */
.preview {
  background: var(--grey-100); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--sp-5); margin-bottom: var(--sp-5);
}
.preview__frame { display: block; width: 100%; height: 620px; border: 0; background: #F1F4F7; }
.preview__subject { font-weight: 600; font-size: var(--step-1); margin-bottom: var(--sp-2); }
.preview code {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .9em;
}
table { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
th, td { text-align: left; padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--line); }
th { color: var(--ink-muted); font-weight: 600; white-space: nowrap; }

.pill {
  display: inline-block; padding: 2px 10px; border-radius: var(--r-pill);
  font-size: var(--step--1); font-weight: 600; white-space: nowrap;
}
.pill[data-state="done"] { background: var(--ok-bg); color: var(--ok-ink); }
.pill[data-state="progress"] { background: var(--warn-bg); color: var(--warn-ink); }
.pill[data-state="new"] { background: var(--surface-alt); color: var(--ink-muted); }

/* ---- feedback ------------------------------------------------------------ */
/* Kind pills in the feedback inbox: bugs and problems read warm, ideas and
   questions stay neutral. */
.pill[data-kind="bug"], .pill[data-kind="problem"] { background: var(--err-bg); color: var(--err-ink); }
.pill[data-kind="idea"], .pill[data-kind="question"] { background: var(--surface-alt); color: var(--ink-muted); }

/* Unread/open counts in the admin nav. */
.nav-badge {
  display: inline-block; margin-left: var(--sp-1);
  min-width: 20px; padding: 1px 6px; border-radius: var(--r-pill);
  background: var(--action); color: #fff;
  font-size: .72rem; font-weight: 700; text-align: center; line-height: 1.5;
}

/* Inbox reply affordances (feedback + review inboxes). */
.fb-inbox__respond { margin-top: var(--sp-3); }
.fb-inbox__respond summary { cursor: pointer; }
.fb-inbox__respond textarea { width: 100%; margin-top: var(--sp-3); font-size: var(--step--1); }
.fb-inbox__respond select { font: inherit; font-size: var(--step--1); padding: var(--sp-2); border: 1px solid var(--line); border-radius: var(--r-sm); }
.fb-inbox__response {
  margin-top: var(--sp-3); padding: var(--sp-3) var(--sp-4);
  background: var(--surface-alt); border-left: 3px solid var(--action); border-radius: var(--r-sm);
}
.fb-inbox__response .review-inbox__body { margin: var(--sp-1) 0 0; }

/* Team replies inside the reviewer panel. */
.review-row__reply {
  margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3);
  background: var(--surface-alt); border-left: 3px solid var(--action); border-radius: var(--r-sm);
}
.review-row__replylabel {
  margin: 0; font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-muted);
}
.review-row__replybody { margin: 2px 0 0; font-size: var(--step--1); white-space: pre-wrap; }

/* ---- responsive ---------------------------------------------------------- */
@media (max-width: 1200px) {
  /* Below this the 360px floor on the entry column starts holding it wider than
     a third. Trim the padding so the extra width goes to the form rather than to
     the margins. Must live here, after the base rules — a media query adds no
     specificity, so declaring it earlier would simply lose. */
  .hero { padding: var(--sp-6) var(--sp-6) var(--sp-5); }
  .entry__card { padding: var(--sp-6) var(--sp-5); }
}

@media (max-width: 900px) {
  /* One column. The panel stays on top rather than moving below the card: it is
     what tells a first-time visitor what this is, and an unexplained email field
     is a worse opening than one screen of scrolling. It gets shorter instead. */
  .entry { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .hero {
    position: static; min-height: 0;
    padding: var(--sp-5) var(--sp-5) var(--sp-6); gap: var(--sp-5);
  }
  .hero__title { font-size: var(--step-3); }
  .hero__stats { gap: var(--sp-5); margin-bottom: var(--sp-4); }
  .entry__card { padding: var(--sp-6) var(--sp-5); }
  .entry__links { margin-top: var(--sp-5); }
}

@media (max-width: 640px) {
  :root { --step-3: 1.5rem; --step-4: 1.75rem; }
  main { padding: var(--sp-5) var(--sp-4) var(--sp-7); }
  .masthead__inner { padding: var(--sp-3) var(--sp-4); }
  .masthead__brand img { width: 200px; }
  .masthead__nav { gap: var(--sp-4); }
  .card, .entry__card { padding: var(--sp-5); }
  .field-row, .field-row--state { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .role { grid-template-columns: auto 1fr; }
  .role__badge { grid-column: 2; justify-self: start; }
  .player__learner { display: none; }
  .player__home span { display: none; }
}

/* ---- admin forms --------------------------------------------------------- */
/* Stacked fields inside a panel — organization details, invitations. Narrower
   than full width so the inputs stay a readable length. */
.stack-form { max-width: 560px; margin-top: var(--sp-4); }
.stack-form .field { margin-bottom: var(--sp-4); }
.stack-form textarea { width: 100%; }
.inline-form { display: inline; }

/* ---- deleting your own account ------------------------------------------- */
/* Folded away, and styled as a consequence rather than an action: the summary
   is a quiet link, and only once opened does anything look like a button. */
.profile__danger { margin-top: var(--sp-5); }
.danger summary { display: inline-flex; list-style: none; cursor: pointer; color: var(--err-ink); }
.danger summary::-webkit-details-marker { display: none; }
.danger__body { margin-top: var(--sp-4); }
.danger__title { font-size: var(--step-1); color: var(--err-ink); margin-bottom: var(--sp-2); }
.danger__lead { color: var(--ink-muted); font-size: var(--step--1); margin-bottom: var(--sp-3); }
.danger__list {
  margin: 0 0 var(--sp-4); padding-left: var(--sp-5);
  color: var(--ink-muted); font-size: var(--step--1); line-height: var(--lh-body);
}
.danger__list strong { color: var(--err-ink); }
.btn--danger { background: var(--err-ink); color: #fff; }
.btn--danger:hover { background: #8a1f24; color: #fff; }

/* ---- recognized partner organization ------------------------------------- */
/* Shown at registration when the email domain belongs to a partner. It states
   a fact, so it reads as confirmation rather than as another question. */
.partner {
  border: 1px solid var(--ok-line); background: var(--ok-bg);
  border-radius: var(--r-md); padding: var(--sp-4); margin-bottom: var(--sp-4);
}
.partner__eyebrow {
  display: flex; align-items: center; gap: var(--sp-2);
  margin: 0; font-size: var(--step--1); font-weight: 600; color: var(--ok-ink);
}
.partner__name { margin: var(--sp-1) 0 0; font-size: var(--step-2); font-weight: 700; }
.partner__note { margin: var(--sp-1) 0 0; font-size: var(--step--1); color: var(--ink-muted); }
.partner .consent__box--quiet { margin-top: var(--sp-3); }

/* ---- org dashboard analytics --------------------------------------------- */
/* Server-rendered SVG/HTML charts. Marks wear the data colors; every piece of
   text — ticks, values, legends — wears ink tokens. Status fills match the
   roster pills' meaning (green done, amber in progress, grey not started);
   the exact fills passed the CVD/contrast validation, so change them together
   or not at all. */
.charts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--sp-4); margin-bottom: var(--sp-5);
}
.chart-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--sp-4) var(--sp-5); min-width: 0;
}
.chart-card--wide { grid-column: 1 / -1; }
.chart-card__title { font-size: var(--step-0); font-weight: 600; margin: 0; }
.chart-card__sub { color: var(--ink-muted); font-size: var(--step--1); margin: 2px 0 var(--sp-4); }

.chart { display: block; width: 100%; height: auto; }
.chart__grid { stroke: var(--grey-100); stroke-width: 1; }
.chart__axis { stroke: var(--grey-200); stroke-width: 1; }
.chart__bar { fill: var(--action); }
.chart__hit { fill: transparent; }
.chart__slot { outline: none; cursor: default; }
.chart__slot:hover .chart__bar, .chart__slot:focus .chart__bar { fill: var(--action-hover); }
.chart__tick { fill: var(--ink-muted); font-size: 11px; }
.chart__val { fill: var(--ink-strong); font-size: 11px; font-weight: 600; }

.chart-table { margin-top: var(--sp-2); font-size: var(--step--1); }
.chart-table summary { color: var(--ink-muted); cursor: pointer; }
.chart-table table { margin-top: var(--sp-2); border-collapse: collapse; }
.chart-table th, .chart-table td { text-align: left; padding: 2px 16px 2px 0; }
.chart-table td:last-child { font-variant-numeric: tabular-nums; }

/* Part-to-whole status bar: 2px surface gaps do the separating, no strokes. */
.stack__bar { display: flex; gap: 2px; height: 22px; border-radius: var(--r-pill); overflow: hidden; }
.stack__seg { display: block; min-width: 3px; }
.stack__seg--done { background: #1D6B2F; }
.stack__seg--progress { background: #B87700; }
.stack__seg--new { background: var(--grey-200); }
.stack__seg:hover, .stack__seg:focus { filter: brightness(1.12); outline: none; }

.legend {
  list-style: none; margin: var(--sp-3) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  font-size: var(--step--1); color: var(--ink-muted);
}
.legend strong { color: var(--ink-strong); }
.legend__swatch {
  display: inline-block; width: 12px; height: 12px; border-radius: 3px;
  margin-right: 6px; vertical-align: -1px;
}
.legend__swatch--done { background: #1D6B2F; }
.legend__swatch--progress { background: #B87700; }
.legend__swatch--new { background: var(--grey-200); }

/* Labelled horizontal bars: modules, campuses. The value is printed at the
   tip; the tooltip only adds the percentage. */
.hbar {
  display: grid; grid-template-columns: minmax(120px, 1.1fr) minmax(0, 1fr) auto;
  gap: var(--sp-3); align-items: center; padding: 5px 0;
}
.hbar:focus { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-sm); }
/* The term in progress — its number is still moving. */
.hbar--current .hbar__label, .hbar--current .hbar__val { font-weight: 600; color: var(--ink-strong); }
.hbar__label { font-size: var(--step--1); min-width: 0; overflow-wrap: anywhere; }
.hbar__track { height: 10px; border-radius: var(--r-pill); background: var(--grey-100); overflow: hidden; }
.hbar__fill { height: 100%; border-radius: var(--r-pill); background: var(--action); }
.hbar__val {
  font-size: var(--step--1); color: var(--ink-muted);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}

.chart-tip {
  position: fixed; z-index: 50; max-width: 280px; padding: 6px 10px;
  border-radius: var(--r-sm); background: var(--navy-800); color: #fff;
  font-size: var(--step--1); pointer-events: none;
  box-shadow: 0 4px 14px rgba(14, 36, 54, .25);
}

@media (max-width: 640px) {
  .hbar { grid-template-columns: minmax(0, 1fr) auto; }
  .hbar__track { grid-column: 1 / -1; order: 3; }
}

/* ---- motion & print ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  .masthead, .site-footer, .actions, .path__tools, .skip { display: none !important; }
  body { background: #fff; color: #000; }
  .card, .faq__item, .panel--next { border: 1px solid #999; box-shadow: none; }
  main { max-width: none; padding: 0; }
  a[href]::after { content: " (" attr(href) ")"; font-size: .8em; color: #555; }
}
