/* Reset, typography, app shell and the shared component styles.
   Load after tokens.css. Everything here is plain CSS with no build step. */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--on-surface);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-feature-settings: 'cv05' 1, 'cv08' 1, 'ss01' 1;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }
button { font: inherit; color: inherit; }

/* One focus ring for the whole app. Regions rely on this being visible against
   both the white mail card and the tinted hover state. */
:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  border-radius: 6px;
}

/* Skip target for keyboard users, visible only when focused. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--on-surface);
  color: #fff;
  padding: 12px 18px;
  border-radius: 0 0 var(--r-btn) 0;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.material-symbols-outlined {
  font-family: 'Material Symbols Outlined';
  font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 24;
  font-weight: normal;
  font-style: normal;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-size: 20px;
  vertical-align: middle;
  flex: none;
}
.ms-14 { font-size: 14px; }
.ms-16 { font-size: 16px; }
.ms-18 { font-size: 18px; }
.ms-28 { font-size: 28px; }

/* Type scale */

.display {
  font-size: var(--t-display);
  font-weight: 900;
  letter-spacing: -.04em;
  line-height: 1.02;
  margin: 0;
}
.headline {
  font-size: var(--t-headline);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.2;
  margin: 0;
}
.title {
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1.35;
  margin: 0;
}
.label {
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  line-height: 1.4;
}
.lede {
  font-size: var(--t-lede);
  line-height: 1.65;
  color: var(--muted);
  font-weight: 400;
}
.body { font-size: var(--t-body); line-height: var(--lh-body); }
.small { font-size: var(--t-small); line-height: 1.55; color: var(--muted); }
.tnum { font-variant-numeric: tabular-nums; }

/* App shell: page > frame > appbar + sim banner + screen */

.app {
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(16px, 3vw, 40px) clamp(12px, 3vw, 24px);
}

.frame {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  position: relative;
}

/* Unbranded by requirement: a mark, never a logo, and no company name. */
.appbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) clamp(16px, 3vw, 24px);
  background: var(--s-lowest);
  box-shadow: var(--shadow-appbar);
  position: relative;
  z-index: 3;
}
.mark { display: flex; align-items: center; gap: 10px; min-width: 0; }
.mark-glyph {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  flex: none;
  background: linear-gradient(135deg, var(--primary), var(--primary-container));
  display: grid;
  place-items: center;
  color: #fff;
  box-shadow: 0 3px 9px rgba(187, 0, 19, .26);
}
.mark-glyph .material-symbols-outlined {
  font-size: 15px;
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;
}
.mark-text {
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: -.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.appbar-meta {
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* The simulation banner sits at frame level, above every screen, and is never
   conditional. Nobody may mistake a training item for a live attack. */
.sim-banner {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px clamp(16px, 3vw, 24px);
  background: var(--s-mid);
  color: var(--on-variant);
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  position: relative;
  z-index: 2;
}
.sim-banner .material-symbols-outlined { font-size: 16px; }

.screen {
  padding: var(--stage-pad-top) var(--stage-pad-x) var(--stage-pad-bottom);
}

.prompt { margin: 0 0 clamp(20px, 2.6vw, 28px); max-width: 62ch; }
.prompt .headline { margin-bottom: var(--sp-2); }
.prompt .small { margin: 0; }

/* Two-column layout used when feedback renders beside the email. Collapses
   early so the email never gets squeezed narrower than it reads at. */
.split {
  display: grid;
  gap: clamp(18px, 2.4vw, 26px);
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  align-items: start;
}
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
}

/* Buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  border-radius: var(--r-btn);
  font-size: var(--t-body);
  font-weight: 600;
  letter-spacing: -.005em;
  padding: 14px var(--sp-6);
  min-height: 48px;
}
.btn .material-symbols-outlined { font-size: 19px; }
.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--primary-container));
  color: #fff;
  box-shadow: var(--shadow-primary);
}
.btn-primary:hover { box-shadow: var(--shadow-primary-hover); filter: brightness(1.05); }
.btn-quiet { background: var(--s-mid); color: var(--on-surface); }
.btn-quiet:hover { background: var(--s-high); }
.btn-ghost {
  background: transparent;
  color: var(--on-variant);
  padding: 12px 14px;
  min-height: var(--hit-min);
}
.btn-ghost:hover { background: var(--s-mid); color: var(--on-surface); }
.btn-block { width: 100%; }

@media (prefers-reduced-motion: no-preference) {
  .btn {
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
                background-color var(--dur) var(--ease), filter var(--dur) var(--ease);
  }
  .btn-primary:hover, .btn-quiet:hover { transform: translateY(-2px); }
  .btn-primary:active, .btn-quiet:active { transform: scale(.98); }
}

/* Form inputs: no four-sided border, a 2px primary bottom accent on focus.
   The asymmetric radius is what makes the bottom edge read as the accent. */

.field { margin-bottom: var(--sp-5); }
.field label {
  display: block;
  margin-bottom: 9px;
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--on-variant);
}
.input {
  width: 100%;
  background: var(--s-low);
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 10px 10px 4px 4px;
  padding: 15px var(--sp-4);
  font: inherit;
  font-size: .9375rem;
  color: var(--on-surface);
  min-height: 52px;
}
.input::placeholder { color: var(--placeholder); }
.input:hover { background: var(--s-mid); }
.input:focus {
  outline: 0;
  background: var(--s-mid);
  border-bottom-color: var(--primary);
}
.field .help { margin-top: 9px; font-size: var(--t-fine); color: var(--muted); }
@media (prefers-reduced-motion: no-preference) {
  .input { transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
}

/* Status chips. Colour is never alone here — every chip carries an icon and a
   text label, because roughly one man in twelve cannot separate red from green. */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--t-fine);
  font-weight: 600;
  line-height: 1.4;
  padding: 5px 11px;
  border-radius: var(--r-pill);
}
.chip .material-symbols-outlined { font-size: 15px; flex: none; }
.chip-safe { background: rgba(72, 104, 0, .10); color: #3a5400; }
/* The raw --warning token measures 4.38:1 on its own 10% tint, just under the
   floor, so the chip uses the darkened variant. Measured, not estimated. */
.chip-caught { background: rgba(180, 83, 9, .10); color: var(--on-warning-container); }
.chip-lesson { background: var(--s-mid); color: var(--on-variant); }
.chip-danger { background: rgba(186, 26, 26, .10); color: var(--on-error-icon); }

/* Keyboard hint row, used under the hotspot email. */
.region-hint {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin: var(--sp-4) 0 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--s-low);
  border-radius: var(--r-region);
  font-size: var(--t-small);
  color: var(--on-variant);
}
.region-hint .material-symbols-outlined { font-size: 18px; }
.kbd {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: var(--t-label);
  background: var(--s-lowest);
  padding: 2px 7px;
  border-radius: 5px;
  box-shadow: 0 1px 2px rgba(25, 28, 29, .10);
  font-weight: 600;
}

/* Segmented stage indicator. Rendered by components/stage-progress.js. */

.stepper { margin: 0 0 clamp(24px, 3.6vw, 40px); }
.stepper-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: 11px;
  flex-wrap: wrap;
}
.stepper-top .now { font-size: var(--t-small); font-weight: 700; letter-spacing: -.005em; }
.stepper-top .desc { font-size: var(--t-fine); color: var(--muted); }
.segs { display: flex; gap: 6px; list-style: none; margin: 0; padding: 0; }
.seg { flex: 1; min-width: 0; }
.seg .bar { display: block; height: 5px; border-radius: var(--r-pill); background: var(--s-high); }
.seg-done .bar { background: var(--secondary); }
.seg-now .bar { background: linear-gradient(90deg, var(--primary), var(--primary-container)); }
.seg .cap {
  display: block;
  margin-top: 9px;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seg-now .cap { color: var(--on-surface); }
.seg-done .cap { color: var(--on-variant); }
/* Below 640px five captions cannot fit, so only the current stage keeps one.
   The stage is still named in full by .stepper-top .now, so nothing is lost. */
@media (max-width: 640px) {
  .seg .cap { display: none; }
  .seg-now .cap { display: block; }
}
@media (prefers-reduced-motion: no-preference) {
  .seg .bar { transition: background var(--dur) var(--ease); }
}

/* Email mock-up. Outlook-shaped chrome, semantic HTML underneath.
   Rendered by components/email-view.js. */

.mailcard {
  background: var(--s-lowest);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  position: relative;
}
.mail-chrome {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 10px var(--sp-4);
  background: var(--s-low);
  color: var(--muted);
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.mail-chrome .dot { width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--s-dim); flex: none; }
.mail-chrome .spacer { flex: 1; }
.mail-chrome .material-symbols-outlined { font-size: 16px; }
.mail-chrome .when { white-space: nowrap; }

.mail-body { padding: var(--mail-pad); }

.mail-subject {
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1.35;
  margin: 0 0 var(--sp-4);
}
.mail-from { display: flex; gap: 13px; align-items: flex-start; }
.avatar {
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  flex: none;
  background: var(--s-high);
  color: var(--on-variant);
  display: grid;
  place-items: center;
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: .02em;
}
.from-lines { min-width: 0; flex: 1; }
/* The name and the address are spans, so they need an explicit block to stack.
   The rules under .mail-regions do this for hotspot mode; read mode needs it
   too, or "Priya Marchetti" and her address run together on one line and the
   address — which is where the lookalike domain hides — stops being scannable. */
.from-name, .from-addr, .mail-to { display: block; }
.from-name { font-size: var(--t-body); font-weight: 600; line-height: 1.4; }
/* Monospace because the address is where lookalike domains hide, and a
   proportional face is what makes rn/m and I/l indistinguishable. */
.from-addr {
  font-size: var(--t-small);
  color: var(--muted);
  font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
  word-break: break-all;
  line-height: 1.5;
}
.from-when { font-size: var(--t-fine); color: var(--muted); white-space: nowrap; padding-top: 2px; }
.mail-to { margin-top: 9px; font-size: var(--t-fine); color: var(--muted); }
.mail-hr { height: 1px; background: var(--s-mid); margin: 18px 0; border: 0; }

.mail-text { font-size: var(--t-body); line-height: var(--lh-mail); color: var(--on-surface); }
.mail-text p { margin: 0 0 13px; }
.mail-text p:last-child { margin-bottom: 0; }

/* Every link in a mock-up is inert. The style says "clickable" because the
   lure depends on it looking clickable; the href never goes anywhere. */
.maillink {
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 2px;
  word-break: break-all;
  cursor: pointer;
  -webkit-user-drag: none; /* belt-and-braces alongside anchor.draggable = false in JS */
}

.mail-sig {
  margin-top: 18px;
  padding-top: var(--sp-4);
  font-size: var(--t-small);
  color: var(--muted);
  line-height: 1.65;
  border-top: 1px solid var(--s-low);
}
.mail-sig strong { color: var(--on-surface); font-weight: 600; }

.mail-attach {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: var(--sp-4);
  padding: 10px 14px;
  background: var(--s-low);
  border-radius: 9px;
  font-size: var(--t-small);
  color: var(--on-surface);
  text-decoration: none;
  min-height: var(--hit-min);
}
.mail-attach .size { color: var(--muted); }
.mail-attach + .mail-attach { margin-left: var(--sp-2); }

.mail-headers { margin-top: var(--sp-4); font-size: var(--t-small); }
.mail-headers summary {
  cursor: pointer;
  color: var(--on-variant);
  font-weight: 600;
  padding: 10px 0;
  min-height: var(--hit-min);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.mail-headers dl {
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--s-low);
  border-radius: var(--r-region);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px var(--sp-3);
}
.mail-headers dt { font-weight: 600; color: var(--on-variant); }
.mail-headers dd {
  margin: 0;
  color: var(--muted);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  word-break: break-all;
}

/* Hotspot regions. Each is a <button>, and a button resets the display of its
   children — which is what collapsed the sender name and address onto one line
   in the prototype. The rules below restore the email layout inside a region
   and must not be removed. */

.mail-regions .region {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  cursor: pointer;
  border-radius: var(--r-region);
  padding: 10px 12px;
  margin: -10px -12px;
  min-height: var(--hit-min);
  position: relative;
}
.mail-regions .region + .region { margin-top: var(--sp-1); }
.mail-regions .region .mail-from { display: flex; gap: 13px; align-items: flex-start; }
.mail-regions .region .from-lines { display: block; min-width: 0; flex: 1; }
.mail-regions .region .from-name,
.mail-regions .region .from-addr,
.mail-regions .region .mail-subject,
.mail-regions .region .mail-text,
.mail-regions .region .mail-sig,
.mail-regions .region .mail-to { display: block; }
.mail-regions .region .mail-subject { margin: 0; }
.mail-regions .region .mail-sig { margin-top: 0; border-top: 0; padding-top: 0; }
.mail-regions .region .mail-attach { margin-top: 0; }

/* The region's own name, shown on hover and focus so the learner knows what
   they are about to choose before they choose it. */
.region-tag {
  position: absolute;
  top: 6px;
  right: 10px;
  font-size: .5625rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--on-variant);
  background: var(--s-lowest);
  padding: 2px 7px;
  border-radius: var(--r-pill);
  opacity: 0;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(25, 28, 29, .08);
}
.mail-regions .region:hover,
.mail-regions .region:focus-visible,
.mail-regions .region.is-active {
  background: var(--s-low);
  box-shadow: inset 0 0 0 2px rgba(187, 0, 19, .20);
}
.mail-regions .region:hover .region-tag,
.mail-regions .region:focus-visible .region-tag,
.mail-regions .region.is-active .region-tag { opacity: 1; }

@media (prefers-reduced-motion: no-preference) {
  .mail-regions .region {
    transition: background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  }
  .region-tag {
    transform: translateY(-2px);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  }
  .mail-regions .region:hover .region-tag,
  .mail-regions .region:focus-visible .region-tag,
  .mail-regions .region.is-active .region-tag { transform: translateY(0); }
}

/* Marked region: the malicious element, in error red. Red describes the email.
   The !important is deliberate — a marked region must beat any hover state
   still sitting on the element when the answer lands.

   NOT scoped to .mail-regions. Feedback screens re-render the email in read
   mode, which has no .mail-regions container, so scoping these rules to it
   meant a marked region resolved correctly and then rendered with no fill and
   no outline — just a pill tag floating mid-sentence with nothing to say which
   text it referred to. */
.region-marked,
.region-marked:hover {
  background: rgba(186, 26, 26, .07) !important;
  box-shadow: inset 0 0 0 2px var(--error) !important;
}
/* Marked regions inside body text (.mail-text) are inline elements — a region
   spanning a run of text fragments across line boxes instead of forming one
   bounded shape. Forcing inline-block gives it a single box to paint the fill
   and outline into. Not applied outside .mail-text: subject/sender regions
   are already block-level and don't need this. */
.mail-text .region-marked,
.mail-text .region-chosen {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 8px;
}
.flag-tag {
  display: flex;
  width: max-content;
  align-items: center;
  gap: 6px;
  margin-top: 9px;
  background: var(--error);
  color: #fff;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--r-pill);
}
.flag-tag .material-symbols-outlined {
  font-size: 14px;
  font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;
}

/* Region the learner clicked when it was not the tell. Amber, because it marks
   the moment rather than the email, and it never appears without the label.
   Unscoped for the same reason as .region-marked above. */
.region-chosen {
  background: rgba(180, 83, 9, .08) !important;
  box-shadow: inset 0 0 0 2px var(--warning) !important;
}
.chosen-tag {
  display: flex;
  width: max-content;
  align-items: center;
  gap: 6px;
  margin-top: 9px;
  background: var(--warning);
  color: #fff;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--r-pill);
}
.chosen-tag .material-symbols-outlined { font-size: 14px; }

/* Revealed invisible characters. Rendered as a visible glyph in a red pill so
   a soft hyphen or zero-width space becomes something the eye can find. */
.invisible-char {
  display: inline-block;
  background: rgba(186, 26, 26, .12);
  color: var(--on-error-icon);
  border-radius: 4px;
  padding: 0 3px;
  margin: 0 1px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-weight: 700;
  font-size: .9em;
}
.reveal-note {
  margin: var(--sp-4) 0 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--s-low);
  border-radius: var(--r-region);
  font-size: var(--t-small);
  color: var(--on-variant);
}
.reveal-note dl { margin: var(--sp-2) 0 0; display: grid; gap: 4px; }
.reveal-note dt { display: inline; font-weight: 700; }
.reveal-note dd { display: inline; margin: 0 0 0 6px; }

/* Feedback panels. Rendered by components/feedback-panel.js. */

.panel {
  border-radius: var(--r-card);
  padding: clamp(18px, 2.6vw, 26px);
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
}
.panel + .panel { margin-top: var(--sp-4); }
.panel-icon {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
}
.panel-body { min-width: 0; flex: 1; }
.panel-body h3 {
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  margin: 0 0 7px;
  line-height: 1.3;
}
.panel-body p { margin: 0; font-size: var(--t-body); line-height: 1.65; }
.panel-body p + p { margin-top: 10px; }
.panel-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: 18px; }

.panel-caught { background: rgba(180, 83, 9, .09); }
.panel-caught .panel-icon { background: rgba(180, 83, 9, .16); color: var(--warning); }
.panel-caught h3 { color: var(--on-warning-container); }
.panel-caught p { color: var(--on-warning-container-body); }

.panel-safe { background: rgba(72, 104, 0, .09); }
.panel-safe .panel-icon { background: rgba(72, 104, 0, .16); color: var(--secondary); }
.panel-safe h3 { color: var(--on-secondary-container); }
.panel-safe p { color: var(--on-secondary-container-body); }

.panel-gentle { background: var(--s-mid); }
.panel-gentle .panel-icon { background: rgba(94, 63, 60, .12); color: var(--on-variant); }
.panel-gentle h3 { color: var(--on-surface); }
.panel-gentle p { color: var(--on-variant); }

.panel-rule { background: var(--on-surface); color: #fff; }
.panel-rule .panel-icon { background: rgba(255, 255, 255, .12); color: #fff; }
.panel-rule h3 { color: #fff; }
.panel-rule p { color: rgba(255, 255, 255, .82); }

.social-proof {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: 14px;
  font-size: var(--t-fine);
  color: var(--on-variant);
}
.social-proof .material-symbols-outlined { font-size: 16px; }

@media (prefers-reduced-motion: no-preference) {
  .panel-enter {
    opacity: 0;
    transform: translateY(8px);
    animation: panel-rise var(--dur) var(--ease-out) forwards;
  }
  @keyframes panel-rise { to { opacity: 1; transform: none; } }
}

/* Triage: the two large choices. Rendered by modes/triage.js. */

.choices {
  display: grid;
  gap: 14px;
  margin-top: clamp(20px, 2.8vw, 28px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
}
.choice {
  display: flex;
  align-items: center;
  gap: 15px;
  text-align: left;
  background: var(--s-lowest);
  border: 0;
  cursor: pointer;
  border-radius: var(--r-card);
  padding: 20px 22px;
  min-height: 76px;
  box-shadow: var(--shadow-card);
}
.choice:hover { background: #fff; box-shadow: var(--shadow-lift); }
.choice-icon {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
}
.choice-genuine .choice-icon { background: rgba(72, 104, 0, .10); color: var(--secondary); }
.choice-sus .choice-icon { background: rgba(180, 83, 9, .10); color: var(--warning); }
.choice-txt { min-width: 0; }
.choice-txt strong {
  display: block;
  font-size: .9375rem;
  font-weight: 600;
  letter-spacing: -.005em;
}
.choice-txt span { display: block; font-size: var(--t-fine); color: var(--muted); margin-top: 2px; }

@media (prefers-reduced-motion: no-preference) {
  .choice {
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
                background-color var(--dur) var(--ease);
  }
  .choice:hover { transform: translateY(-2px); }
  .choice:active { transform: scale(.98); }
}

/* Hotspot: the "nothing here" sentinel sits between the email and the keyboard
   hint. It is a real answer, so it gets a real button rather than a link. */

.hotspot-none { margin-top: var(--sp-4); }

/* Inbox: a single-column list at every width. The sort controls sit BENEATH
   each message, never beside it, because at 360px there is no beside. */

.inbox-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(18px, 2.4vw, 24px);
}
.inbox-item {
  background: var(--s-low);
  border-radius: var(--r-lg);
  padding: clamp(12px, 1.6vw, 16px);
}
.inbox-item.is-sorted { background: var(--s-mid); }

/* Three equal actions in a row. They stay a row at 360px because each label is
   one word; the hint line under it is what wraps if anything has to. */
.sort-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.sort-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  background: var(--s-lowest);
  border: 0;
  cursor: pointer;
  border-radius: var(--r-region);
  padding: 10px 6px;
  min-height: var(--hit-min);
  color: var(--on-variant);
  text-align: center;
}
.sort-btn:hover { background: #fff; color: var(--on-surface); }
.sort-btn .material-symbols-outlined { font-size: 20px; }
.sort-label { font-size: var(--t-small); font-weight: 600; }
.sort-hint { font-size: var(--t-micro); color: var(--muted); line-height: 1.3; }

/* The chosen action. Colour is never alone: the chip keeps its icon and its
   word, and the checked state is also on aria-checked for a screen reader. */
.sort-btn.is-chosen {
  background: var(--on-surface);
  color: #fff;
  box-shadow: var(--shadow-card);
}
.sort-btn.is-chosen .sort-hint { color: rgba(255, 255, 255, .72); }

@media (prefers-reduced-motion: no-preference) {
  .sort-btn { transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease); }
}

.inbox-status { margin: var(--sp-4) 0 var(--sp-2); }
.inbox-submit:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; filter: none; }
.inbox-submit:disabled:hover { transform: none; }

.inbox-results { list-style: none; margin: var(--sp-5) 0 0; padding: 0; display: grid; gap: var(--sp-5); }
.inbox-result { display: grid; gap: var(--sp-3); }

/* Scenario: the Stage 5 decisions. Every choice renders identically — no
   colour, no ordering hint, nothing that separates the safe option from the
   unsafe ones. The learner has to decide, which is the whole exercise. */

.scenario-prompt { margin: clamp(20px, 2.6vw, 28px) 0 var(--sp-4); }
.scenario-choices { display: grid; gap: var(--sp-3); }
.scenario-choice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  text-align: left;
  background: var(--s-lowest);
  border: 0;
  cursor: pointer;
  border-radius: var(--r-card);
  padding: 18px 20px;
  min-height: 64px;
  box-shadow: var(--shadow-card);
  color: var(--on-surface);
}
.scenario-choice:hover { background: #fff; box-shadow: var(--shadow-lift); }
.scenario-choice-label { font-size: .9375rem; font-weight: 600; letter-spacing: -.005em; }
.scenario-choice-arrow { color: var(--muted); flex: none; }

@media (prefers-reduced-motion: no-preference) {
  .scenario-choice {
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
                background-color var(--dur) var(--ease);
  }
  .scenario-choice:hover { transform: translateY(-2px); }
  .scenario-choice:active { transform: scale(.99); }
}

/* The consequence of a choice. Neutral tone on purpose: a bad path leads
   onward to what followed, and dressing it in amber would read as a scolding
   on a stage that has no corrective loop. */
.consequence {
  margin-top: clamp(18px, 2.4vw, 24px);
  border-radius: var(--r-card);
  padding: clamp(18px, 2.6vw, 26px);
  background: var(--s-mid);
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
}
.consequence-icon {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
  background: rgba(94, 63, 60, .12);
  color: var(--on-variant);
}
.consequence-body { min-width: 0; flex: 1; }
.consequence-body h3 {
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  margin: 0 0 7px;
  line-height: 1.3;
}
.consequence-body p { margin: 0; font-size: var(--t-body); line-height: 1.65; color: var(--on-variant); }

/* The outcome that closes Stage 5. All three kinds get the same shape; only
   the tint and the icon differ, and each carries its own text heading. */
.outcome {
  border-radius: var(--r-card);
  padding: clamp(18px, 2.6vw, 26px);
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
}
.outcome-icon {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
}
.outcome-body { min-width: 0; flex: 1; }
.outcome-body h3 {
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  margin: 0 0 7px;
  line-height: 1.3;
}
.outcome-body p { margin: 0; font-size: var(--t-body); line-height: 1.65; }

.outcome-safe { background: rgba(72, 104, 0, .09); }
.outcome-safe .outcome-icon { background: rgba(72, 104, 0, .16); color: var(--secondary); }
.outcome-safe h3 { color: var(--on-secondary-container); }
.outcome-safe p { color: var(--on-secondary-container-body); }

.outcome-recovered { background: rgba(72, 104, 0, .09); }
.outcome-recovered .outcome-icon { background: rgba(72, 104, 0, .16); color: var(--secondary); }
.outcome-recovered h3 { color: var(--on-secondary-container); }
.outcome-recovered p { color: var(--on-secondary-container-body); }

.outcome-caught { background: rgba(180, 83, 9, .09); }
.outcome-caught .outcome-icon { background: rgba(180, 83, 9, .16); color: var(--warning); }
.outcome-caught h3 { color: var(--on-warning-container); }
.outcome-caught p { color: var(--on-warning-container-body); }

.scenario-script { margin-top: var(--sp-4); }
.outcome-actions { margin-top: var(--sp-4); }

/* Stage 4: the scripted reveal. Every check passes, one at a time, then the
   verdict lands. */

.reveal {
  background: var(--s-lowest);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.reveal-head { padding: 20px clamp(18px, 2.4vw, 24px) 14px; }
.reveal-head .label { color: var(--muted); }
.reveal-head h3 {
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  margin: 6px 0 0;
}
.checks { list-style: none; margin: 0; padding: 0 clamp(10px, 1.6vw, 14px) 14px; }
.checks li {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 14px;
  border-radius: var(--r-region);
}
.checks li:nth-child(odd) { background: var(--s-low); }
.check-mark {
  width: 26px;
  height: 26px;
  border-radius: var(--r-pill);
  flex: none;
  display: grid;
  place-items: center;
  background: rgba(72, 104, 0, .13);
  color: var(--secondary);
}
.check-mark .material-symbols-outlined {
  font-size: 16px;
  font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;
}
.check-txt { flex: 1; min-width: 0; }
.check-txt strong { display: block; font-size: var(--t-body); font-weight: 600; }
.check-txt span { display: block; font-size: var(--t-fine); color: var(--muted); }
.check-state {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #3a5400;
  background: rgba(72, 104, 0, .10);
  padding: 4px 10px;
  border-radius: var(--r-pill);
  white-space: nowrap;
}
.verdict {
  margin: 0;
  padding: clamp(18px, 2.6vw, 26px);
  background: var(--error-container);
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
}
.verdict-icon {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
  background: rgba(186, 26, 26, .14);
  color: var(--on-error-icon);
}
.verdict h4 {
  margin: 0 0 7px;
  font-size: var(--t-title);
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--on-error-container);
}
.verdict p { margin: 0; font-size: var(--t-body); line-height: 1.65; color: var(--on-error-container-body); }

/* The checks arrive one at a time, which is the whole drama of Stage 4. Under
   reduced motion all four are simply present, never an empty box. */
@media (prefers-reduced-motion: no-preference) {
  .checks li {
    opacity: 0;
    transform: translateY(8px);
    animation: check-rise 420ms var(--ease-out) forwards;
  }
  .checks li:nth-child(1) { animation-delay: 120ms; }
  .checks li:nth-child(2) { animation-delay: 420ms; }
  .checks li:nth-child(3) { animation-delay: 720ms; }
  .checks li:nth-child(4) { animation-delay: 1020ms; }
  @keyframes check-rise { to { opacity: 1; transform: none; } }

  .verdict { opacity: 0; animation: check-rise 420ms var(--ease-out) 1400ms forwards; }
}

/* Remediation notes and the stage summary. */

.remediation-note { margin-bottom: clamp(18px, 2.4vw, 24px); }
.stage-summary { max-width: 62ch; }
.stage-summary-label { display: block; color: var(--muted); margin-bottom: var(--sp-2); }

/* Entry screen. */

.entry {
  display: grid;
  gap: clamp(28px, 4vw, 64px);
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  align-items: center;
}
@media (max-width: 900px) {
  .entry { grid-template-columns: 1fr; align-items: stretch; }
}
.entry-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--s-mid);
  color: var(--on-variant);
  padding: 7px 14px;
  border-radius: var(--r-pill);
  margin-bottom: 22px;
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.entry-eyebrow .material-symbols-outlined { font-size: 16px; }
.entry h1 { max-width: 14ch; }
.entry .lede { margin: 20px 0 0; max-width: 46ch; }
.entry-time-note { margin: var(--sp-3) 0 0; max-width: 46ch; }

.facts { display: flex; gap: clamp(20px, 3vw, 40px); flex-wrap: wrap; margin-top: clamp(26px, 3.4vw, 36px); }
.fact { min-width: 0; }
.fact .n {
  font-size: 1.75rem;
  font-weight: 900;
  letter-spacing: -.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.fact .k {
  display: block;
  margin-top: 7px;
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted);
}

.entry-card {
  background: var(--s-lowest);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: clamp(24px, 3vw, 34px);
}
.field-error {
  margin: 9px 0 0;
  font-size: var(--t-fine);
  color: var(--on-error-container);
  display: flex;
  gap: 6px;
  align-items: flex-start;
}
.field-error[hidden] { display: none; }

.policy { margin-top: 22px; padding: 18px 20px; background: var(--s-low); border-radius: var(--r-region); }
.policy .label { color: var(--on-variant); margin-bottom: 11px; display: block; }
.policy ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.policy li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--on-variant);
}
.policy li .material-symbols-outlined { font-size: 17px; color: var(--secondary); margin-top: 1px; }

/* Resume banner. */

.resume-panel {
  background: var(--s-lowest);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: clamp(22px, 3vw, 32px);
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
  max-width: 62ch;
}
.resume-icon {
  width: var(--hit-min);
  height: var(--hit-min);
  border-radius: 11px;
  flex: none;
  display: grid;
  place-items: center;
  background: var(--s-mid);
  color: var(--on-variant);
}
.resume-body { min-width: 0; flex: 1; }
.resume-body h1 { margin: 0 0 var(--sp-2); }
.resume-body p { margin: 0 0 var(--sp-2); font-size: var(--t-body); line-height: 1.65; }
.resume-body .small { color: var(--muted); }

/* Completion screen. Matches the approved prototype's screen 6. */

.done-wrap {
  display: grid;
  gap: clamp(28px, 4vw, 54px);
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  align-items: center;
}
@media (max-width: 980px) {
  .done-wrap { grid-template-columns: 1fr; }
}
.done-seal {
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: rgba(72, 104, 0, .11);
  color: var(--secondary);
  display: grid;
  place-items: center;
  margin-bottom: 24px;
}
.done-seal .material-symbols-outlined {
  font-size: 34px;
  font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 40;
}
.done-heading { font-size: clamp(2rem, 5vw, 2.75rem); }
.done-lede { max-width: 42ch; margin-top: var(--sp-4); }

.rule-recall {
  margin-top: 26px;
  padding: 20px 22px;
  border-radius: var(--r-card);
  background: var(--on-surface);
  color: #fff;
}
.rule-recall .label { color: rgba(255, 255, 255, .6); display: block; margin-bottom: 9px; }
.rule-recall p { margin: 0; font-size: .9375rem; line-height: 1.6; font-weight: 500; }

/* The recording line. It says what actually happened and never claims a write
   that has not landed. */
.record-status {
  margin-top: var(--sp-4);
  padding: 13px 15px;
  border-radius: var(--r-region);
  font-size: var(--t-small);
  line-height: 1.55;
  display: flex;
  gap: 10px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.record-status .material-symbols-outlined { font-size: 18px; flex: none; margin-top: 1px; }
.record-pending { background: var(--s-mid); color: var(--on-variant); }
.record-ok { background: rgba(72, 104, 0, .10); color: var(--on-secondary-container-body); }
.record-error { background: rgba(186, 26, 26, .09); color: var(--on-error-container-body); }
.record-retry { margin-top: var(--sp-2); flex-basis: 100%; }

.grade-card {
  background: var(--s-lowest);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}
.grade-head {
  display: flex;
  gap: clamp(18px, 2.6vw, 28px);
  align-items: center;
  padding: clamp(26px, 3.4vw, 38px) clamp(24px, 3.4vw, 38px) clamp(22px, 3vw, 30px);
}
.grade-letter-wrap {
  width: clamp(88px, 11vw, 112px);
  height: clamp(88px, 11vw, 112px);
  flex: none;
  border-radius: 20px;
  display: grid;
  place-items: center;
  background: rgba(72, 104, 0, .10);
}
.grade-letter {
  font-size: clamp(2.5rem, 6vw, 3.25rem);
  font-weight: 900;
  letter-spacing: -.05em;
  color: var(--secondary);
  line-height: 1;
}
.grade-head-text { min-width: 0; }
.grade-kicker {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  display: block;
  margin-bottom: 8px;
}
.grade-gloss { margin: 0; font-size: .9375rem; line-height: 1.6; font-weight: 500; }

.grade-private {
  margin: 0 clamp(24px, 3.4vw, 38px);
  padding: 13px 15px;
  border-radius: var(--r-region);
  background: var(--s-low);
  font-size: var(--t-fine);
  line-height: 1.55;
  color: var(--muted);
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.grade-private .material-symbols-outlined { font-size: 16px; color: var(--on-variant); margin-top: 1px; flex: none; }

.grade-rows { list-style: none; margin: clamp(22px, 3vw, 30px) 0 0; padding: 0; }
.grade-row {
  display: grid;
  gap: 4px 16px;
  align-items: center;
  grid-template-columns: auto minmax(0, 1fr) auto;
  padding: 14px clamp(24px, 3.4vw, 38px);
}
/* Zebra tonal shift rather than divider lines, per the style system. */
.grade-row:nth-child(odd) { background: var(--s-low); }
.gr-stage {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.gr-name { font-size: var(--t-body); font-weight: 600; }
.gr-mark {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--t-fine);
  font-weight: 600;
  line-height: 1.4;
  padding: 5px 11px;
  border-radius: var(--r-pill);
}
.gr-mark .material-symbols-outlined { font-size: 15px; flex: none; }
.gr-clear { background: rgba(72, 104, 0, .10); color: #3a5400; }
.gr-fixed { background: rgba(180, 83, 9, .10); color: var(--on-warning-container); }
.gr-lesson { background: var(--s-mid); color: var(--on-variant); }
@media (max-width: 600px) {
  .grade-row { grid-template-columns: 1fr; }
  .gr-mark { justify-self: start; }
}

.grade-next {
  margin: clamp(22px, 3vw, 30px) clamp(24px, 3.4vw, 38px) clamp(26px, 3.4vw, 36px);
  padding: 18px 20px;
  border-radius: var(--r-card);
  background: var(--on-surface);
  color: #fff;
}
.grade-next .grade-kicker { color: rgba(255, 255, 255, .6); }
.grade-next p { margin: 0; font-size: var(--t-body); line-height: 1.6; font-weight: 500; }
.grade-next p + p { margin-top: var(--sp-2); }

.done-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: 24px; }
