/* ==========================================================================
   hexa.css, Hexa Crew Tools platform design system.
   Source of truth: DESIGN-SPEC.md (Aviation Liquid Glass, dark-only).
   Values are applied verbatim from the spec. Do not reinterpret.
   ========================================================================== */

/* ── Typography: self-hosted Inter (variable, latin subset) ──
   Google Fonts serves Inter as one variable file covering wght 100-900;
   a single @font-face with a weight range replaces three static files. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/platform/assets/fonts/inter-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Core tokens ─────────────────────────────────────────── */
:root {
  --bg: #020D1F;
  --text: #F0F8FF;
  --muted: #C2D8EC;
  --accent: #0080FF;
  --accent-bright: #00AAFF;
  --glow: rgba(0, 170, 255, 0.45);
  --danger: #FF4D5E;

  --glass-bg: rgba(255, 255, 255, 0.08);
  --glass-bg-strong: rgba(255, 255, 255, 0.13);
  --glass-border: rgba(255, 255, 255, 0.22);

  --gold: #EDD600;       /* brand gold, sampled from the logo */
  --gold-soft: rgba(237, 214, 0, 0.16);
  --live-green: #4ade80;
  --orb-cyan: #00D1FF;
  --opaque-fallback: rgba(7, 22, 44, 0.94);

  --ease-emph: cubic-bezier(0.2, 0, 0, 1);
  --ease-decel: cubic-bezier(0.05, 0.7, 0.1, 1);
  --ease-accel: cubic-bezier(0.3, 0, 0.8, 0.15);
  --spring-fast: 0.35s cubic-bezier(0.42, 1.67, 0.21, 0.9);
  --spring-default: 0.5s cubic-bezier(0.38, 1.21, 0.22, 1);

  --r-card: 28px;
  --r-stage: 32px;
  --r-row: 20px;
  --r-box: 18px;
  --r-chip: 14px;
  --r-pill: 999px;
}

/* ── Base ────────────────────────────────────────────────── */
* { box-sizing: border-box; }
html { font-size: 16px; }
body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--text);
  font-family: "Inter", "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
[hidden] { display: none !important; }

a { color: var(--accent-bright); }
a:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; border-radius: 4px; }

/* ── Aurora background ───────────────────────────────────── */
.aurora {
  position: fixed; inset: -20vmax; z-index: -1;
  pointer-events: none; overflow: hidden;
}
.aurora .b {
  position: absolute; border-radius: 50%;
  width: 60vmax; height: 60vmax;
  will-change: transform;
  animation: drift 26s ease-in-out infinite alternate;
}
.aurora .b1 {
  top: -10vmax; left: -8vmax;
  background: radial-gradient(circle, #0059B3 0%, transparent 65%);
}
.aurora .b2 {
  bottom: -14vmax; right: -10vmax; opacity: 0.32;
  background: radial-gradient(circle, #00AAFF 0%, transparent 62%);
  animation-duration: 32s; animation-delay: -8s;
}
.aurora .b3 {
  top: 30%; left: 35%; opacity: 0.5;
  background: radial-gradient(circle, #123C8C 0%, transparent 65%);
  animation-duration: 38s; animation-delay: -16s;
}
@keyframes drift {
  to { transform: translate3d(6vmax, -4vmax, 0) scale(1.15); }
}

/* Calmer in-test surface (D14c): static background, no aurora motion,
   reduced blur so budget devices stay smooth during timed questions. */
body.in-test .aurora .b { animation: none; }
body.in-test .glass,
body.in-test .gbtn {
  -webkit-backdrop-filter: blur(8px) saturate(150%);
  backdrop-filter: blur(8px) saturate(150%);
}

/* ── Layout ──────────────────────────────────────────────── */
.wrap {
  min-height: 100svh;
  display: flex; flex-direction: column; align-items: center;
  padding: max(18px, env(safe-area-inset-top)) 18px max(18px, env(safe-area-inset-bottom));
}
.wrap > header, .wrap > main { width: 100%; max-width: 1060px; }
.wrap > main { display: flex; flex-direction: column; align-items: center; flex: 1; }

.site-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 10px 0 26px;
}
.site-head .brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.site-head .brand-logo { height: 120px; width: auto; display: block; }
.site-head .brand-suffix {
  font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); align-self: center; padding-top: 6px;
}
@media (max-width: 640px) {
  .site-head .brand-logo { height: 96px; }
  .site-head .brand-suffix { display: none; }
}
.site-head nav { display: flex; gap: 14px; align-items: center; }
.site-head nav a {
  color: var(--muted); text-decoration: none; font-size: 14px; font-weight: 600;
}
.site-head nav a:hover { color: var(--text); }

/* ── Type roles ──────────────────────────────────────────── */
h1, .display {
  font-size: clamp(34px, 6vw, 52px);
  font-weight: 300; line-height: 1.08; letter-spacing: -0.01em;
  margin: 0 0 18px; color: var(--text);
}
h1 em, .display em, .display-2 em { font-style: normal; color: var(--accent-bright); }
.display-2 {
  font-size: clamp(30px, 5vw, 40px);
  font-weight: 300; margin: 0 0 18px;
}
h2 { font-size: 20px; font-weight: 600; margin: 0 0 10px; }
.lead {
  font-size: 16px; font-weight: 300; line-height: 1.65;
  color: var(--muted); max-width: 46ch; margin: 0 0 22px;
}
.eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 0.3em;
  text-transform: uppercase; color: var(--accent-bright);
  margin: 0 0 10px;
}
.meta { font-size: 14px; font-weight: 300; line-height: 1.6; color: var(--muted); }
.fineprint { font-size: 12px; font-weight: 300; line-height: 1.6; color: var(--muted); opacity: 0.75; }
/* Video listening player. */
.video-wrap { margin: 4px 0 14px; border-radius: var(--r-box); overflow: hidden; background: #000; }
.video-wrap video { width: 100%; display: block; max-height: 60vh; }

/* Animated ellipsis for "being AI-marked" pending states. */
.hx-dots::after { content: ""; display: inline-block; width: 1.2em; text-align: left; animation: hxdots 1.4s steps(1, end) infinite; }
@keyframes hxdots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }
@media (prefers-reduced-motion: reduce) { .hx-dots::after { content: "..."; animation: none; } }

.card-kicker {
  font-size: 11px; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 8px;
}

/* Test library card: title block on top, meta and action pinned to the base
   so every card lines up regardless of tagline length. */
.test-card { display: flex; flex-direction: column; padding: 24px 24px 20px; }
.test-card-body { flex: 1; }
.test-card-body h2 { margin: 0 0 8px; }
.test-card-body .meta { margin: 0; }
.test-card-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-top: 20px; padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.test-card-meta { font-size: 12.5px; font-weight: 300; color: var(--muted); }

/* Category cards are whole-card links. */
a.cat-card { text-decoration: none; color: inherit; display: flex; }
a.cat-card .test-card-foot .test-card-meta { color: var(--accent-bright); font-weight: 600; }

/* Divider between a social sign-in button and the email form. */
.or-line {
  display: flex; align-items: center; gap: 14px;
  margin: 18px 0; color: var(--muted); font-size: 12.5px;
  text-transform: uppercase; letter-spacing: 0.14em;
}
.or-line::before, .or-line::after {
  content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, 0.12);
}

/* Breadcrumb back to the library. */
.crumb { font-size: 13px; font-weight: 600; margin: 0 0 10px; }
.crumb a { color: var(--muted); text-decoration: none; }
.crumb a:hover { color: var(--text); }

/* ── Glass card ──────────────────────────────────────────── */
.glass {
  position: relative;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  backdrop-filter: blur(20px) saturate(170%);
  border-radius: var(--r-card);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 0 rgba(255, 255, 255, 0.06),
    inset 1px 1px 3px rgba(255, 255, 255, 0.18),
    inset -1px -1px 3px rgba(0, 0, 0, 0.12),
    0 12px 40px rgba(0, 0, 0, 0.35);
  isolation: isolate;
  transform: translateZ(0);
}
.glass::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.08) 40%,
    rgba(255, 255, 255, 0.04) 60%, rgba(255, 255, 255, 0.3) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none;
}

.card { padding: 30px 28px; }
/* A 620px card pinned to the far left of a 1400px screen reads as a
   layout bug. Centre it; long-form pages keep their left alignment. */
.hero-card { max-width: 620px; width: 100%; padding: 44px 40px; margin-left: auto; margin-right: auto; }
@media (max-width: 640px) { .hero-card { padding: 34px 22px; } }

/* Sub-glass panel (nested inside a glass card, no backdrop filter) */
.sub-glass {
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  border-radius: var(--r-box);
  padding: 16px 20px;
}

/* ── Buttons ─────────────────────────────────────────────── */
.gbtn {
  /* One fixed height for every button so rows never look ragged. */
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 44px; padding: 0 24px; border: none; border-radius: var(--r-pill);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28),
              0 4px 16px rgba(0, 0, 0, 0.24);
  color: var(--text); font-family: inherit;
  font-size: 15px; font-weight: 600; letter-spacing: 0.01em;
  cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
  text-decoration: none; white-space: nowrap;
  /* No scale: the footprint stays constant, only lift and brightness move. */
  transition: transform 0.18s var(--ease-emph),
              background 0.18s var(--ease-emph),
              box-shadow 0.18s var(--ease-emph),
              filter 0.18s var(--ease-emph);
}
.gbtn:hover {
  background: rgba(255, 255, 255, 0.16);
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 6px 20px rgba(0, 0, 0, 0.3);
}
.gbtn:active { transform: translateY(0); filter: brightness(0.94); }
.gbtn:disabled { opacity: 0.45; pointer-events: none; }
.gbtn:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }

.gbtn.primary {
  /* Solid, readable accent so the main action stands out on glass. */
  background: color-mix(in srgb, var(--accent) 88%, #ffffff 4%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3),
              0 6px 22px var(--glow);
  color: #ffffff; font-weight: 600;
}
.gbtn.primary:hover {
  background: color-mix(in srgb, var(--accent-bright) 92%, #ffffff 6%);
}
.gbtn.danger {
  background: color-mix(in srgb, var(--danger) 82%, transparent); color: #fff;
}
/* Small inline variant for secondary or in-card actions. */
.gbtn.sm { height: 36px; padding: 0 16px; font-size: 13.5px; }
.gbtn.ghost {
  background: transparent; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}
.gbtn.ghost:hover { background: rgba(255, 255, 255, 0.06); }
.gbtn.share { height: 36px; padding: 0 16px; font-size: 13.5px; }
.gbtn.block { width: 100%; }
.gbtn svg { width: 22px; height: 22px; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; fill: none; }

/* ── Chips and badges ────────────────────────────────────── */
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: var(--r-pill);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted);
}
.chip.accent { color: var(--gold); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 0 0 1px var(--gold-soft); }
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; }

/* ── Card grid with stagger-rise entrance ────────────────── */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 18px; width: 100%;
}
.card-grid > * { animation: rise 0.5s var(--ease-decel) backwards; }
.card-grid > *:nth-child(2) { animation-delay: 0.06s; }
.card-grid > *:nth-child(3) { animation-delay: 0.12s; }
.card-grid > *:nth-child(4) { animation-delay: 0.18s; }
.card-grid > *:nth-child(5) { animation-delay: 0.24s; }
.card-grid > *:nth-child(6) { animation-delay: 0.30s; }
.card-grid > *:nth-child(7) { animation-delay: 0.36s; }
.card-grid > *:nth-child(n+8) { animation-delay: 0.42s; }

.card-interactive {
  transition: transform var(--spring-fast), box-shadow 0.25s var(--ease-emph);
}
.card-interactive:hover {
  transform: translateY(-3px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45),
              0 16px 48px rgba(0, 0, 0, 0.4),
              0 0 40px rgba(0, 170, 255, 0.18);
}
.card-interactive:active { transform: translateY(-1px); transition-duration: 0.1s; }
.card-interactive:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }
.card-interactive.selected {
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, 0.35),
    inset 0 0 0 2px var(--accent-bright),
    inset 0 0 60px rgba(0, 170, 255, 0.22),
    0 12px 40px rgba(0, 0, 0, 0.35);
  transition: box-shadow 0.4s var(--ease-emph);
}

/* ── Sections and entrances ──────────────────────────────── */
@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
.section-enter { animation: rise 0.5s var(--ease-decel) backwards; }
.section-exit {
  animation: exitup 0.2s var(--ease-accel) forwards;
}
@keyframes exitup {
  to { opacity: 0; transform: translateY(-8px); }
}

/* ── Determinate progress bar ────────────────────────────── */
.progress {
  height: 5px; border-radius: var(--r-pill); overflow: hidden;
  background: rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  width: 100%;
}
.progress .fill {
  height: 100%; width: 100%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--accent), var(--orb-cyan), var(--accent));
  box-shadow: 0 0 10px rgba(0, 170, 255, 0.6);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.4s var(--ease-emph);
}

/* ── Countdown ring ──────────────────────────────────────── */
.ring-wrap {
  position: relative; display: inline-flex;
  align-items: center; justify-content: center;
}
.ring-wrap svg { transform: rotate(-90deg); display: block; }
.ring-track { fill: none; stroke: rgba(255, 255, 255, 0.12); }
.ring-fg {
  fill: none; stroke: var(--accent); stroke-linecap: round;
  transition: stroke-dashoffset 1s linear, stroke 0.6s var(--ease-emph);
}
.ring-fg.warn { stroke: var(--gold); }
.ring-fg.crit { stroke: var(--danger); }
.ring-label {
  position: absolute; font-size: 14px; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.timer-inline {
  display: inline-flex; align-items: center; gap: 10px;
  font-variant-numeric: tabular-nums;
}

/* ── Forms ───────────────────────────────────────────────── */
.field { margin: 0 0 18px; }
.field label:not(.f-choice) {
  display: block; font-size: 14px; font-weight: 600;
  color: var(--text); margin: 0 0 8px;
}
.field input[type="text"], .field input[type="email"],
.field input[type="password"], .field input[type="number"],
.field input[type="tel"], .field input[type="date"],
.field input[type="file"],
.field select, .field textarea {
  width: 100%; padding: 14px 18px;
  border-radius: var(--r-box); border: 1px solid var(--glass-border);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  color: var(--text); font-family: inherit; font-size: 16px; font-weight: 300;
}
body:not(.portal) .field input[type="date"] { color-scheme: dark; }
/* The file input wears the glass and its button is one of ours. */
.field input[type="file"] { padding: 10px 14px; cursor: pointer; }
.field input[type="file"]::file-selector-button {
  font-family: inherit; font-size: 13px; font-weight: 600;
  color: var(--text); cursor: pointer;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-pill);
  padding: 8px 18px; margin-right: 14px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
/* The mark of a needed answer: small, red, and enough. */
.f-req { color: #FF5D6E; font-weight: 700; margin-left: 4px; }
/* A grouped question is a fieldset wearing the same clothes as a field. */
fieldset.field { border: none; padding: 0; margin: 0 0 18px; min-width: 0; }
fieldset.field legend {
  display: block; padding: 0; font-size: 12px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 8px;
}
body.portal fieldset.field legend, .fb-preview fieldset.field legend { color: var(--p-ink-2); }
.field input::placeholder, .field textarea::placeholder { color: var(--muted); opacity: 0.6; }
/* An access code is read off a board or out loud, so it is shown the way it
   is spoken: upper case, letters apart. */
.field input.hx-code-input { text-transform: uppercase; letter-spacing: 0.08em; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--accent-bright); outline-offset: 3px;
}
.field .hint { font-size: 12px; font-weight: 300; color: var(--muted); margin: 6px 0 0; }
.form-error {
  border-radius: var(--r-box); padding: 12px 18px; margin: 0 0 18px;
  background: rgba(255, 77, 94, 0.18);
  background: color-mix(in srgb, var(--danger) 18%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  color: #FFB4BB; font-size: 14px;
}
.form-note {
  border-radius: var(--r-box); padding: 12px 18px; margin: 0 0 18px;
  background: rgba(0, 128, 255, 0.14);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  color: var(--muted); font-size: 14px;
}

/* ── Question hierarchy (test engine) ────────────────────── */
/* Stimulus panel: the material to read before answering (passage, note).
   A pane of the site's own glass, and the text inside set to be read at
   length, not glanced at. */
.stimulus {
  background: rgba(255, 255, 255, 0.06);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18),
              inset 0 -1px 0 rgba(255, 255, 255, 0.04);
  border-radius: var(--r-box); padding: 18px 22px; margin: 0 0 22px;
}
.stimulus .meta {
  font-size: 14.5px; font-weight: 400; line-height: 1.75;
}
.stim-label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--accent-bright); margin: 0 0 8px;
}
/* Question stem: the actual question. Its weight and size alone set it
   apart from the stimulus above and the answers below — no rules, no
   bars, nothing drawn beside the words. */
.q-stem {
  margin: 6px 0 20px;
  font-size: clamp(17px, 2.2vw, 20px); font-weight: 500; line-height: 1.5;
  letter-spacing: -0.005em;
  color: var(--text);
}
.q-hint {
  font-size: 13px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--muted); margin: 0 0 14px;
}

/* ── Question navigator (test engine) ────────────────────── */
.qnav-wrap { margin-top: 22px; padding-top: 16px; border-top: 1px solid rgba(255, 255, 255, 0.1); }
.qnav { display: flex; flex-wrap: wrap; gap: 8px; }
.qnav-btn {
  width: 38px; height: 38px; border-radius: 10px;
  border: 1px solid var(--glass-border); background: rgba(255, 255, 255, 0.04);
  color: var(--muted); font-family: inherit; font-size: 13.5px; font-weight: 600;
  cursor: pointer; transition: background 0.16s var(--ease-emph), color 0.16s var(--ease-emph),
                              box-shadow 0.16s var(--ease-emph);
}
.qnav-btn:hover { background: rgba(255, 255, 255, 0.1); color: var(--text); }
.qnav-btn:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.qnav-btn.done { background: color-mix(in srgb, var(--accent) 34%, transparent); color: var(--text); border-color: transparent; }
.qnav-btn.flagged { box-shadow: inset 0 0 0 2px var(--gold); color: var(--gold); }
.qnav-btn.current { box-shadow: 0 0 0 2px var(--accent-bright); color: var(--text); }
.qnav-key { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin: 12px 0 0; }
.qk { display: inline-flex; align-items: center; gap: 6px; }
.qkey { width: 12px; height: 12px; border-radius: 4px; display: inline-block; border: 1px solid var(--glass-border); }
.qkey.done { background: color-mix(in srgb, var(--accent) 34%, transparent); border-color: transparent; }
.qkey.flag { box-shadow: inset 0 0 0 2px var(--gold); }
.qkey.todo { background: rgba(255, 255, 255, 0.04); }
.gbtn.ghost.on { box-shadow: inset 0 0 0 1px var(--gold); color: var(--gold); }

/* ── Answer option rows (test engine) ────────────────────── */
.opt {
  display: flex; align-items: flex-start; gap: 13px;
  width: 100%; min-height: 50px; padding: 15px 20px; margin: 0 0 12px;
  border-radius: var(--r-box); border: 1px solid var(--glass-border);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.045));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18),
              inset 0 -1px 0 rgba(255, 255, 255, 0.04);
  color: var(--text); font-family: inherit; font-size: 15.5px; font-weight: 400;
  line-height: 1.5;
  text-align: left; cursor: pointer;
  transition: background 0.2s var(--ease-emph), box-shadow 0.4s var(--ease-emph),
              transform var(--spring-fast), border-color 0.2s var(--ease-emph);
}
/* Leading radio (single choice) or checkbox (multi) marker so a row is
   unmistakably a selectable answer, not instruction text. */
.opt::before {
  content: ""; flex: 0 0 auto; width: 20px; height: 20px; margin-top: 1px;
  border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.34);
  transition: border-color 0.18s var(--ease-emph), box-shadow 0.18s var(--ease-emph),
              background 0.18s var(--ease-emph);
}
.opt.opt-check::before { border-radius: 6px; }
.opt.selected::before {
  border-color: var(--accent-bright);
  box-shadow: inset 0 0 0 4px var(--accent-bright);
}
.opt.opt-check.selected::before {
  background: var(--accent-bright); box-shadow: none;
}
.opt > span { flex: 1; }
/* Answer letter on its own small tile of glass, so options can be
   referred to and chosen by key. */
.opt .opt-key {
  flex: 0 0 auto; width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.07);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16);
  font-size: 12px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--muted);
  transition: background 0.18s var(--ease-emph), color 0.18s var(--ease-emph);
}
.opt.selected .opt-key {
  color: #fff;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
}
.opt:hover {
  background: rgba(255, 255, 255, 0.09);
  border-color: rgba(0, 170, 255, 0.4);
  transform: translateY(-1px);
}
.opt:active { transform: scale(0.985); transition-duration: 0.1s; }
.opt:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }
.opt.selected {
  background: linear-gradient(180deg, rgba(0, 170, 255, 0.17), rgba(0, 128, 255, 0.08));
  border-color: rgba(0, 170, 255, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
              inset 0 0 0 2px var(--accent-bright),
              0 6px 24px rgba(0, 128, 255, 0.18);
}
.opt.correct {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14),
              inset 0 0 0 2px var(--accent-bright),
              inset 0 0 60px rgba(0, 170, 255, 0.22);
}
.opt.incorrect {
  background: rgba(255, 77, 94, 0.3);
  background: color-mix(in srgb, var(--danger) 30%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

/* ── Band and score coloring (always glass tints, never solid) ── */
.band-strong { background: color-mix(in srgb, var(--accent-bright) 18%, transparent); color: var(--accent-bright); }
.band-middle { background: color-mix(in srgb, var(--gold) 18%, transparent); color: var(--gold); }
.band-weak   { background: color-mix(in srgb, var(--danger) 18%, transparent); color: #FFB4BB; }
.band-pill {
  display: inline-block; padding: 8px 16px; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* Breakdown rows on results screens */
.breakdown-row { margin: 0 0 14px; animation: rise 0.5s var(--ease-decel) backwards; }
.breakdown-row:nth-child(2) { animation-delay: 0.46s; }
.breakdown-row:nth-child(3) { animation-delay: 0.52s; }
.breakdown-row:nth-child(4) { animation-delay: 0.58s; }
.breakdown-row:nth-child(5) { animation-delay: 0.64s; }
.breakdown-row .bar {
  height: 5px; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.12); overflow: hidden; margin-top: 8px;
}
.breakdown-row .bar .fill {
  height: 100%; border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--accent), var(--orb-cyan), var(--accent));
  box-shadow: 0 0 10px rgba(0, 170, 255, 0.6);
  transform-origin: left;
  animation: barin 0.5s var(--ease-decel) backwards;
}
@keyframes barin { from { transform: scaleX(0); } }

/* ── Toast (aria-live status) ────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: max(24px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  padding: 14px 24px; border-radius: var(--r-pill);
  background: rgba(2, 13, 31, 0.75);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 8px 30px rgba(0, 0, 0, 0.4);
  color: var(--text); font-size: 14px; font-weight: 600;
  z-index: 50;
  animation: toastin var(--spring-default) backwards;
}
@keyframes toastin { from { transform: translate(-50%, 150%); } }

/* ── Accessibility ───────────────────────────────────────── */
:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }

@media (prefers-reduced-transparency: reduce) {
  .glass, .gbtn, .chip, .toast, .opt {
    background: var(--opaque-fallback);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  }
}

/* Reduced motion: decorative animation off, information kept.
   Progress fills and countdown rings are driven by inline styles from JS,
   so killing transitions makes them jump to the current value instantly
   while still rendering; numeric readouts keep updating in JS. */
@media (prefers-reduced-motion: reduce) {
  .aurora .b, .card-grid > *, .section-enter, .section-exit,
  .breakdown-row, .breakdown-row .bar .fill, .toast,
  .gbtn, .card-interactive, .opt {
    animation: none !important;
    transition: none !important;
  }
  .progress .fill, .ring-fg { transition: none !important; }
  .gbtn:hover, .card-interactive:hover { transform: none; }
}
/* In-app reduce-animations toggle mirrors the media query (2.3.3) */
body.reduce-motion .aurora .b, body.reduce-motion .card-grid > *,
body.reduce-motion .section-enter, body.reduce-motion .section-exit,
body.reduce-motion .breakdown-row, body.reduce-motion .breakdown-row .bar .fill,
body.reduce-motion .toast, body.reduce-motion .gbtn,
body.reduce-motion .card-interactive, body.reduce-motion .opt {
  animation: none !important; transition: none !important;
}
body.reduce-motion .progress .fill, body.reduce-motion .ring-fg { transition: none !important; }

/* ── Utility ─────────────────────────────────────────────── */
.stack-10 > * + * { margin-top: 10px; }
.stack-18 > * + * { margin-top: 18px; }
.row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.row.between { justify-content: space-between; }
.center { text-align: center; }
.mt-22 { margin-top: 22px; }
.mt-32 { margin-top: 32px; }

/* ── Print (report basics) ───────────────────────────────── */
@media print {
  body { background: #fff; color: #111; }
  .aurora, .site-head nav, .gbtn, .toast { display: none !important; }
  .glass, .sub-glass, .opt {
    background: #fff; box-shadow: none; border: 1px solid #ccc;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .glass::before { display: none; }
  h1, .display, .display-2, h2, .lead, .meta, .fineprint { color: #111; }
  .eyebrow, .display em, h1 em { color: #005a99; }
  a { color: #005a99; }
}

/* Test library: category tiles, then that category's tests */
.cat-card {
  display: flex; flex-direction: column; gap: 8px;
  text-decoration: none; color: inherit; min-height: 172px;
}
.cat-card h2 { margin: 0; font-size: clamp(20px, 2.4vw, 25px); letter-spacing: -0.01em; }
.cat-card .meta { margin: 0; flex: 1 1 auto; }
.cat-card-foot {
  font-size: 13px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--gold); text-transform: uppercase;
}
.lib-back {
  display: inline-block; margin: 0 0 14px; font-size: 14px; font-weight: 600;
  color: var(--muted); text-decoration: none;
}
.lib-back::before { content: "\2190"; margin-right: 7px; }
.lib-back:hover { color: var(--text); }
.lib-cat-head { margin: 0 0 22px; }
.lib-cat-head h1 { margin: 0 0 6px; }
.lib-cat-head .lead { margin: 0; }

/* Cloudflare Turnstile: only occupies space once the widget renders */
.cf-turnstile { margin: 0 0 16px; }
.cf-turnstile:empty { margin: 0; }

/* Assessment builder: a readable pick list, not a dropdown */
.pick-row { display: flex; gap: 14px; align-items: flex-start; cursor: pointer; padding: 14px 16px; }
.pick-row input { margin-top: 3px; flex: 0 0 auto; }
.pick-body { display: flex; flex-direction: column; gap: 4px; }
.pick-title { font-weight: 600; }
.pick-desc { font-size: 14px; color: var(--muted); }
.pick-meta { font-size: 12.5px; color: var(--muted); opacity: 0.85; }

/* A sign-up sitting flush against a sign-in link reads as one sentence.
   Give it an edge so the eye separates them. */
.nav-cta {
  border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 999px;
  padding: 7px 15px; margin-left: 6px;
}
.nav-cta:hover { background: rgba(255, 255, 255, 0.09); }

/* Short forms are centred: a sign-in box pinned to the left of a wide
   screen looks like a mistake. Content-heavy pages stay left aligned,
   because long text read from a centred column is harder work. */
body.auth-page main > section { margin-left: auto; margin-right: auto; }

/* Answer key review: the scenario text is the thing being judged, so it
   leads. The scale is a compact segmented control underneath, not four
   buttons competing with the sentence above them. */
.key-opt {
  border: 1px solid rgba(255, 255, 255, 0.09); border-radius: 12px;
  padding: 13px 15px 11px; margin: 0 0 9px; background: rgba(255, 255, 255, 0.03);
}
.key-opt-text { margin: 0 0 11px; font-size: 16.5px; font-weight: 500; line-height: 1.5; color: var(--text); }
.key-scale { display: flex; gap: 0; flex-wrap: wrap; }
.key-step { flex: 1 1 0; min-width: 96px; cursor: pointer; }
.key-step input { position: absolute; opacity: 0; pointer-events: none; }
.key-step span {
  display: block; text-align: center; padding: 6px 6px; font-size: 11.5px;
  line-height: 1.25; color: var(--muted);
  border: 1px solid rgba(255, 255, 255, 0.12); border-right-width: 0;
}
.key-step:first-child span { border-radius: 7px 0 0 7px; }
.key-step:last-child  span { border-radius: 0 7px 7px 0; border-right-width: 1px; }
.key-step:hover span { background: rgba(255, 255, 255, 0.07); color: var(--text); }
.key-step input:checked + span {
  background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600;
}
.key-step input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: -2px; }
.key-skip { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; font-size: 13px; color: var(--muted); cursor: pointer; }

/* ── Modal ───────────────────────────────────────────────────
   The first one on the platform. Nothing new is invented: the card is the
   glass card already in use, over a scrim of the same blurred material,
   so the page behind stays visible and stops being reachable.

   The actions are equal columns rather than a flex row because a modal's
   buttons have to be the same size as each other, and "Continue" is a
   longer word than "Back". grid-auto-columns holds that for any number
   of them. */
.dialog-overlay {
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(2, 13, 31, 0.5);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  animation: fadein 0.25s var(--ease-decel);
}
/* display on the overlay would otherwise beat the hidden attribute. */
.dialog-overlay[hidden] { display: none; }
.dialog-card {
  width: 100%; max-width: 520px; padding: 30px 28px; text-align: center;
  max-height: 88svh; overflow-y: auto;
  animation: rise 0.35s var(--ease-decel);
}
.dialog-card .dialog-title { font-size: 20px; font-weight: 600; margin: 0; }
.dialog-card .dialog-text {
  margin: 10px 0 0; font-size: 14px; font-weight: 300; line-height: 1.6; color: var(--muted);
}
/* A briefing is several sentences and is read, not glanced at, so it is
   set left even though the card centres its title and its actions —
   and at reading size, not caption size. */
.dialog-brief { margin-top: 16px; text-align: left; }
.dialog-brief .dialog-text { font-size: 14.5px; font-weight: 400; line-height: 1.7; color: var(--text); }
.dialog-brief .dialog-text + .dialog-text { margin-top: 12px; }
.dialog-actions {
  margin-top: 24px; display: flex; justify-content: flex-end; gap: 12px;
}
body.modal-open { overflow: hidden; }
@media (max-width: 420px) { .dialog-card { padding: 26px 20px; } }
@media (prefers-reduced-transparency: reduce) {
  .dialog-overlay {
    background: rgba(2, 13, 31, 0.94);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .dialog-overlay, .dialog-card { animation: none !important; }
}
body.reduce-motion .dialog-overlay, body.reduce-motion .dialog-card { animation: none !important; }

/* ==========================================================================
   Light glass. Trialled on the answer key review.

   Same construction as the dark theme, inverted: the aurora still sits
   behind everything so the cards have something to refract, the blur and
   saturation are unchanged, and the inner highlight moves from white to
   a soft shadow. Glass on a flat white page is invisible, which is why
   the background keeps its colour blooms rather than going plain.

   Contrast is deliberately not maximal here either. Ink is #1B2733 on a
   card that sits around #F4F8FC, roughly 13:1, rather than pure black on
   pure white, which is as harsh in the other direction.
   ========================================================================== */
body.light {
  --bg: #D5E0EC;
  --text: #16212C;
  --muted: #4C5E6E;
  --glass-bg: rgba(255, 255, 255, 0.52);
  --glass-bg-strong: rgba(255, 255, 255, 0.68);
  background: #D5E0EC;
  color: #1B2733;
}

/* The blooms stay, lightened, so the glass reads as glass. */
body.light .aurora .b1 { background: radial-gradient(circle, #7FAEE4 0%, transparent 65%); opacity: 0.6; }
body.light .aurora .b2 { background: radial-gradient(circle, #8FCFEC 0%, transparent 62%); opacity: 0.46; }
body.light .aurora .b3 { background: radial-gradient(circle, #A9BFE6 0%, transparent 65%); opacity: 0.54; }

body.light .glass,
body.light .glass.card {
  background: var(--glass-bg);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, 0.95),
    0 1px 2px rgba(27, 39, 51, 0.06),
    0 12px 32px rgba(27, 39, 51, 0.10);
}
/* The dark theme paints a light rim on the card edge. On light that rim
   is invisible, so it becomes a soft shadow instead. */
body.light .glass::before {
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.95) 0%, rgba(27, 39, 51, 0.05) 45%, rgba(27, 39, 51, 0.09) 100%);
}

body.light section { max-width: 780px; }
body.light h2 { font-size: 19px; line-height: 1.45; color: #16222E; }
body.light .meta, body.light p { line-height: 1.6; }
body.light .display-2 { color: #14202C; }
body.light .eyebrow { color: #5D7188; }
body.light .fineprint { color: #6B7C8C; }

/* Option cards sit on the glass, so they are a touch more solid. */
body.light .key-opt {
  background: rgba(255, 255, 255, 0.66);
  border: 1px solid rgba(22, 33, 44, 0.12);
}
body.light .key-opt-text { font-size: 16px; font-weight: 400; color: #16222E; }
body.light .key-scale { }
body.light .key-step span {
  border-color: rgba(22, 33, 44, 0.18);
  color: #516473; background: rgba(255, 255, 255, 0.46); font-size: 12px; padding: 7px 6px;
}
body.light .key-step:hover span { background: #fff; color: #1B2733; }
body.light .key-step input:checked + span {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
body.light .key-skip { color: #6B7C8C; }

/* Buttons invert with the surface. */
body.light .gbtn {
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid rgba(27, 39, 51, 0.14);
  color: #1B2733;
}
body.light .gbtn:hover { background: #fff; }
body.light .gbtn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
body.light .bar { background: rgba(27, 39, 51, 0.10); }
body.light .form-note {
  background: rgba(255, 255, 255, 0.8); border: 1px solid rgba(27, 39, 51, 0.12); color: #1B2733;
}

/* The header sits on the same light surface. */
body.light .site-head { background: transparent; }
body.light .site-head nav a { color: #45586A; }
body.light .site-head nav a:hover { color: #14202C; }

/* The logo is a white wordmark, so on a light surface it disappears.
   A dark plate behind it looks like a sticker, and masking it flattens
   the gold. So logo-light-bg.png is a real second asset: the wordmark
   recoloured to the brand navy, the gold hexagons untouched. Generated
   from logo.png, so it stays in step if the original changes. */
body.light .brand { background: none; padding: 0; }
body.light .brand-logo { content: url("/logo-light-bg.png"); }

/* --- Light glass, corrections --------------------------------------------
   Links inherited the dark theme's bright blue, which measures 2:1 on a
   light card and is genuinely unreadable. On light they take a deeper
   blue from the same family, which passes AA at 5.2:1.
   The glass also needed to be MORE transparent, not less: it was reading
   as a solid white box because too little of the background came through.
   -------------------------------------------------------------------- */
body.light a { color: #0B63C5; }
body.light a:hover { color: #08498F; }

body.light .glass,
body.light .glass.card {
  background: rgba(255, 255, 255, 0.42);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.75);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, 0.9),
    0 2px 6px rgba(18, 32, 46, 0.06),
    0 18px 44px rgba(18, 32, 46, 0.13);
}
body.light .key-opt {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.8);
  box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.7);
}
body.light .key-step span { background: rgba(255, 255, 255, 0.38); }
body.light .key-step:hover span { background: rgba(255, 255, 255, 0.85); }

/* The blooms are what the glass refracts, so they need to be visible
   through it rather than washed out. */
body.light .aurora .b1 { opacity: 0.78; }
body.light .aurora .b2 { opacity: 0.62; }
body.light .aurora .b3 { opacity: 0.7; }

/* The test shortcuts were a run-on sentence of links in fineprint. */
body.light .key-jump { margin: 0 0 22px; }
body.light .key-jump-lead { font-size: 13.5px; color: #4C5E6E; margin: 0 0 9px; }
.key-jump-row { display: flex; flex-wrap: wrap; gap: 8px; }
.key-jump-row a {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 6px 12px; border-radius: 999px; font-size: 13px; text-decoration: none;
  border: 1px solid rgba(22, 33, 44, 0.16); background: rgba(255, 255, 255, 0.55);
}
.key-jump-row a:hover { background: #fff; }
.key-jump-row a b { font-weight: 600; }
.key-jump-row a span { opacity: 0.62; font-size: 12px; }

/* --- Light theme: the rest of the company portal --------------------------
   The portal reuses tables, stat tiles, pills and form fields that were all
   drawn for a dark surface, so each needs its light counterpart. Borders
   move from white-on-dark to ink-on-light, and anything that relied on a
   translucent white overlay gets a translucent ink one instead.
   -------------------------------------------------------------------- */
body.light { color-scheme: light; }

body.light .co-table th { color: #4C5E6E; border-bottom-color: rgba(22, 33, 44, 0.14); }
body.light .co-table td { border-bottom-color: rgba(22, 33, 44, 0.09); }
body.light .co-table tr:hover td { background: rgba(255, 255, 255, 0.45); }

body.light .sub-glass {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.8);
  box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.7);
}
body.light .co-stat .n { color: #14202C; }
body.light .co-stat .l { color: #566878; }

/* Status pills: colour carries meaning here, so each keeps its hue and
   only the ground changes. */
body.light .band-pill { border-width: 1px; }
body.light .band-strong { background: rgba(27, 127, 75, 0.12); color: #14603A; border-color: rgba(27, 127, 75, 0.3); }
body.light .band-middle { background: rgba(180, 130, 10, 0.14); color: #7A5600; border-color: rgba(180, 130, 10, 0.32); }
body.light .band-weak   { background: rgba(180, 35, 47, 0.11); color: #8E1D26; border-color: rgba(180, 35, 47, 0.28); }

body.light .chip {
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(22, 33, 44, 0.14);
  color: #3F5364;
}

/* Form fields */
body.light input[type="text"], body.light input[type="email"], body.light input[type="password"],
body.light input[type="search"], body.light input[type="date"], body.light input[type="number"],
body.light select, body.light textarea:not(.fbx-well) {
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid rgba(22, 33, 44, 0.18);
  color: #16212C;
}
body.light input::placeholder, body.light textarea:not(.fbx-well)::placeholder { color: #8496A6; }
body.light input:focus, body.light select:focus, body.light textarea:not(.fbx-well):focus {
  border-color: var(--accent); background: #fff;
}
body.light label { color: #2C3D4D; }
body.light .hint, body.light .fineprint { color: #617385; }

body.light .form-error {
  background: rgba(180, 35, 47, 0.09); border: 1px solid rgba(180, 35, 47, 0.28); color: #8E1D26;
}
body.light .bar { background: rgba(22, 33, 44, 0.12); }
body.light .breakdown-row .bar { background: rgba(22, 33, 44, 0.12); }

/* Header and footer sit on the light ground. */
body.light .site-head nav a { color: #45586A; }
body.light .site-head nav a:hover { color: #14202C; }
body.light .nav-cta { border-color: rgba(22, 33, 44, 0.2); }
body.light .nav-cta:hover { background: rgba(255, 255, 255, 0.7); }
body.light .site-foot, body.light footer { color: #617385; }

/* The library's category tiles and test cards, if a company ever sees them. */
body.light .cat-card, body.light .test-card { color: #16212C; }
body.light .cat-card-foot { color: #8A6D00; }
body.light .pick-desc, body.light .pick-meta { color: #566878; }

/* ==========================================================================
   THE CANDIDATE'S LEFT COLUMN
   ==========================================================================
   A signed-in candidate navigates from a column on the left, the way the
   company portal does. Everything here is the dark glass the rest of this
   file is built from: the rail is a pane of it standing on the aurora, not
   a panel borrowed from the light portal. Signed out and mid-test there is
   no rail at all, so none of this is reachable from those pages.
   ========================================================================== */

.cand-shell {
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr);
  min-height: 100svh;
}

.cand-nav {
  grid-column: 1;
  position: sticky; top: 0; align-self: start;
  height: 100svh;
  display: flex; flex-direction: column; gap: 6px;
  padding: 18px 12px max(18px, env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.055);
  -webkit-backdrop-filter: blur(26px) saturate(170%);
  backdrop-filter: blur(26px) saturate(170%);
  border-right: 1px solid rgba(255, 255, 255, 0.12);
  z-index: 20;
  /* Short windows scroll the rail. The scroll sits here rather than on
     .cand-links so the marker on the current row, which sits in the rail's
     padding, is not clipped by a scroll container. */
  overflow-y: auto;
}

/* The trimmed mark, not the wordmark on its 16:9 canvas: at rail size the
   canvas is mostly transparent padding and the logo disappears. */
.cand-brand { display: block; padding: 2px 10px 16px; }
.cand-brand img { height: 34px; width: auto; display: block; }

.cand-links { display: flex; flex-direction: column; gap: 3px; }

.cand-link {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  height: 40px; padding: 0 12px;
  border-radius: 12px;
  color: var(--muted); text-decoration: none;
  font-size: 14px; font-weight: 600; letter-spacing: -0.005em;
  white-space: nowrap;
  transition: background 0.18s var(--ease-emph), color 0.18s var(--ease-emph);
}
.cand-link svg {
  flex: 0 0 auto; width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0.82;
}
.cand-link:hover { background: var(--glass-bg); color: var(--text); }
.cand-link:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.cand-link.is-current {
  background: var(--glass-bg-strong); color: var(--text);
  box-shadow: inset 0 0 0 1px var(--glass-border);
}
.cand-link.is-current svg { color: var(--accent-bright); opacity: 1; }
/* The marker on the current row, so the state survives a glance. */
.cand-link.is-current::before {
  content: ""; position: absolute; left: -12px; top: 10px; bottom: 10px;
  width: 3px; border-radius: 0 3px 3px 0;
  background: var(--accent-bright); box-shadow: 0 0 10px var(--glow);
}

/* Below the rule: who you are signed in as, one reference page, and the
   way out. None of it is somewhere a candidate goes to do something. */
.cand-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, 0.12); }
.cand-who { padding: 2px 12px 10px; min-width: 0; }
.cand-who-me {
  display: block; font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cand-who-sub {
  display: block; font-size: 11.5px; color: var(--muted); opacity: 0.7; margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cand-quiet { height: 34px; font-size: 13.5px; font-weight: 500; opacity: 0.85; }
.cand-quiet:hover { opacity: 1; }

/* ── Content column ──────────────────────────────────────── */
.cand-body { grid-column: 2; display: flex; flex-direction: column; min-width: 0; }
.cand-main {
  flex: 1; width: 100%; max-width: 1060px; margin: 0 auto;
  padding: 30px 26px 12px;
  display: flex; flex-direction: column; align-items: center;
}
.cand-fine {
  width: 100%; max-width: 1060px; margin: 0 auto; text-align: center;
  padding: 30px 26px max(26px, env(safe-area-inset-bottom));
}

/* ── Narrow screens ──────────────────────────────────────────
   Below 900px the rail becomes a sticky top bar and the rows become a line
   of pills that scrolls sideways. No hamburger and no JavaScript, so the
   current page stays visible instead of hiding behind a menu. Laid out to
   work down to 320px. */
@media (max-width: 900px) {
  /* Block, not grid: a sticky grid item can only stick inside its own grid
     area, so the bar would scroll away with row one. */
  .cand-shell { display: block; }
  .cand-nav {
    grid-column: 1; height: auto; position: sticky; top: 0;
    flex-direction: row; align-items: center; gap: 8px;
    padding: max(8px, env(safe-area-inset-top)) 12px 8px;
    overflow: visible;
    border-right: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  }
  .cand-brand { padding: 0 2px 0 0; flex: 0 0 auto; }
  .cand-brand img { height: 24px; }
  .cand-links {
    flex-direction: row; gap: 4px; flex: 1 1 auto; min-width: 0;
    overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; -ms-overflow-style: none;
    padding: 2px 0;
  }
  .cand-links::-webkit-scrollbar { display: none; }
  .cand-link { height: 34px; padding: 0 11px; font-size: 13.5px; }
  .cand-link.is-current::before { display: none; }
  .cand-link.is-current { box-shadow: inset 0 0 0 1px rgba(0, 170, 255, 0.5); }
  .cand-foot {
    display: flex; align-items: center; gap: 2px; flex: 0 0 auto;
    margin-top: 0; padding-top: 0; padding-left: 8px;
    border-top: 0; border-left: 1px solid rgba(255, 255, 255, 0.12);
  }
  .cand-who { display: none; }
  .cand-foot .cand-link span { display: none; }
  .cand-foot .cand-link { padding: 0 9px; }
  .cand-body { grid-column: 1; }
  .cand-main { padding: 22px 16px 10px; }
  .cand-fine { padding: 24px 16px max(22px, env(safe-area-inset-bottom)); }
}

/* Printing a result should not print the navigation. */
@media print {
  .cand-nav, .cand-fine { display: none !important; }
  .cand-shell { display: block; }
  .cand-main { max-width: none; padding: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cand-link { transition: none !important; }
}

/* ==========================================================================
   THE COMPANY PORTAL
   ==========================================================================
   Everything below is scoped to body.portal, which only company/_shared.php
   sets. The candidate side never carries that class, so nothing here can
   reach it. It is placed last in the file deliberately: several rules have
   the same specificity as the body.light rules above and need to win on
   source order.

   The portal is a work surface. Someone sits in it for an hour reading
   results, so it is quieter than the marketing side: tighter radii, a
   still background, less bloom, denser type. The glass construction is
   kept, but dialled down to where it reads as a product chrome rather
   than a showpiece.
   ========================================================================== */

body.portal {
  /* One calm ground. The blooms still sit behind the glass, but at a
     third of the strength the marketing pages use, and they do not move:
     a drifting gradient under a table of candidate scores is noise. */
  --bg: #E9EFF6;
  background: #E9EFF6;

  /* Portal ink scale. Four steps is enough for every screen here. */
  --p-ink:   #16212C;   /* headings, values, primary rows        */
  --p-ink-2: #46596B;   /* body copy, secondary cells            */
  --p-ink-3: #6C7E8F;   /* labels, captions, column heads        */
  --p-line:   rgba(20, 32, 44, 0.09);
  --p-line-2: rgba(20, 32, 44, 0.16);
  --p-surface: rgba(255, 255, 255, 0.72);
  --p-hover:   rgba(255, 255, 255, 0.92);
  --p-accent:  #0B63C5;
  --p-accent-soft: rgba(11, 99, 197, 0.10);
  --p-shadow: 0 1px 2px rgba(18, 32, 46, 0.05), 0 8px 24px rgba(18, 32, 46, 0.07);
  --p-shadow-lift: 0 2px 4px rgba(18, 32, 46, 0.06), 0 14px 34px rgba(18, 32, 46, 0.12);

  /* A product does not have 28px corners on everything. */
  --r-card: 18px;
  --r-stage: 20px;
  --r-row: 14px;
  --r-box: 12px;
  --r-chip: 10px;
}
body.portal .aurora .b { animation: none; }
body.portal .aurora .b1 { opacity: 0.34; }
body.portal .aurora .b2 { opacity: 0.26; }
body.portal .aurora .b3 { opacity: 0.30; }
/* The marketing light theme caps every section at 780px. The portal sets
   its own column width on .portal-main, so that cap has to come off. */
body.portal section { max-width: none; }

/* ── Shell: fixed left rail, content to the right ─────────── */
.portal-shell {
  display: grid;
  grid-template-columns: 244px minmax(0, 1fr);
  min-height: 100svh;
}

.portal-nav {
  grid-column: 1;
  position: sticky; top: 0; align-self: start;
  height: 100svh;
  display: flex; flex-direction: column;
  gap: 6px;
  padding: 16px 12px max(16px, env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.78);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  border-right: 1px solid var(--p-line);
  z-index: 20;
  /* Short windows scroll the rail. The scroll lives here rather than on
     .portal-links so the accent marker on the current row, which sits in
     the rail's padding, is not clipped by a scroll container. */
  overflow-y: auto;
}

/* Two swaps in one line. logo.png is a white wordmark on a 16:9 canvas that
   is two thirds transparent padding, which is why the marketing header has
   to run it at 120px. The portal takes the trimmed light-background build
   instead: same artwork, no dead space, so it reads at rail size. */
.portal-brand { display: block; padding: 4px 10px 14px; }
.portal-brand img { height: 38px; width: auto; display: block; content: url("/logo-mark-light-bg.png"); }

.portal-links { display: flex; flex-direction: column; gap: 2px; }

.portal-link {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  height: 38px; padding: 0 11px;
  border-radius: 10px;
  color: #4A5C6E; text-decoration: none;
  font-size: 14px; font-weight: 600; letter-spacing: -0.005em;
  white-space: nowrap;
  transition: background 0.15s var(--ease-emph), color 0.15s var(--ease-emph);
}
.portal-link svg {
  flex: 0 0 auto; width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0.85;
}
.portal-link:hover { background: rgba(255, 255, 255, 0.85); color: var(--p-ink); }
.portal-link:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 1px; }
.portal-link.is-current {
  background: #fff; color: var(--p-ink);
  box-shadow: 0 1px 2px rgba(18, 32, 46, 0.06), 0 4px 12px rgba(18, 32, 46, 0.07);
}
.portal-link.is-current svg { color: var(--p-accent); opacity: 1; }
/* The marker on the current row, so the state survives a glance. */
.portal-link.is-current::before {
  content: ""; position: absolute; left: -12px; top: 9px; bottom: 9px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--p-accent);
}

/* Sign out is not navigation, so it sits at the far end behind a rule. */
.portal-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--p-line); }
.portal-who { padding: 2px 11px 10px; min-width: 0; }
.portal-who-co {
  display: block; font-size: 13px; font-weight: 600; color: var(--p-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.portal-who-me {
  display: block; font-size: 11.5px; color: var(--p-ink-3); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.portal-signout { color: var(--p-ink-3); font-weight: 500; }

/* ── Content column ──────────────────────────────────────── */
.portal-body { grid-column: 2; display: flex; flex-direction: column; min-width: 0; }
.portal-main {
  flex: 1;
  width: 100%; max-width: 800px;
  margin: 0 auto;
  padding: 34px 30px 12px;
}
.portal-main.wide { max-width: 1140px; }
/* The fine print lines up with the column above it, whichever width it is. */
.portal-fine {
  max-width: 800px; margin: 0 auto; width: 100%;
  padding: 26px 30px max(26px, env(safe-area-inset-bottom));
  font-size: 12px; line-height: 1.6; color: #7C8C9B;
}
.portal-main.wide + .portal-fine { max-width: 1140px; }

/* Signed out: no rail, just the wordmark and a single column. */
.portal-plain { min-height: 100svh; display: flex; flex-direction: column; align-items: center;
                padding: 26px 20px max(26px, env(safe-area-inset-bottom)); }
.portal-plain .portal-brand { padding: 0 0 26px; }
.portal-plain .portal-brand img { height: 52px; margin: 0 auto; }
.portal-plain > main { width: 100%; max-width: 460px; flex: 1; }
.portal-plain > footer { padding-top: 26px; }

/* ── Page header: heading, and a subtitle only when it earns it ── */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
  margin: 0 0 22px;
}
.page-head-text { min-width: 0; }
.page-title {
  margin: 0;
  font-size: clamp(23px, 2.6vw, 29px); font-weight: 600;
  line-height: 1.15; letter-spacing: -0.018em; color: var(--p-ink);
}
.page-title em { font-style: normal; color: inherit; }
.page-sub { margin: 8px 0 0; font-size: 14.5px; line-height: 1.55; color: var(--p-ink-2); max-width: 66ch; }
.page-actions { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.page-back {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 0 9px;
  font-size: 13px; font-weight: 600; color: var(--p-ink-3); text-decoration: none;
}
.page-back::before { content: "\2190"; font-size: 14px; }
.page-back:hover { color: var(--p-ink); }

/* ── Stat tiles. A number a recruiter cannot click is a number they
      cannot use, so the tile is an anchor and says so. ────────── */
.stat-tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 12px; margin: 0 0 22px;
}
.stat-tile {
  position: relative;
  display: flex; flex-direction: column; gap: 6px;
  padding: 16px 18px 15px;
  border-radius: 14px;
  background: var(--p-surface);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--p-shadow);
  color: inherit; text-decoration: none;
  transition: transform 0.18s var(--ease-emph), background 0.18s var(--ease-emph),
              box-shadow 0.18s var(--ease-emph);
}
a.stat-tile::after {
  content: ""; position: absolute; top: 17px; right: 16px;
  width: 6px; height: 6px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); opacity: 0.28;
  transition: opacity 0.18s var(--ease-emph), transform 0.18s var(--ease-emph);
}
a.stat-tile:hover { background: var(--p-hover); transform: translateY(-2px); box-shadow: var(--p-shadow-lift); }
a.stat-tile:hover::after { opacity: 0.6; transform: rotate(-45deg) translate(2px, 2px); }
a.stat-tile:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; }
.stat-tile-n {
  font-size: 30px; font-weight: 600; line-height: 1;
  letter-spacing: -0.025em; color: var(--p-ink);
  font-variant-numeric: tabular-nums;
}
.stat-tile-l {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--p-ink-3);
}
/* Work waiting on a person is the one tile allowed to shout. */
.stat-tile.is-alert {
  background: rgba(255, 250, 232, 0.9);
  border-color: rgba(180, 130, 10, 0.32);
}
.stat-tile.is-alert .stat-tile-n { color: #8A6D00; }
.stat-tile.is-alert .stat-tile-l { color: #7A5600; }

/* ── Filter and search bar ───────────────────────────────── */
.filter-bar {
  display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap;
  padding: 14px 16px; margin: 0 0 18px;
  border-radius: 14px;
  background: var(--p-surface);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--p-shadow);
}
.filter-field { display: flex; flex-direction: column; gap: 6px; flex: 1 1 170px; min-width: 0; }
.filter-field.grow { flex: 2 1 250px; }
.filter-field > label {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--p-ink-3);
}
body.portal .filter-field input,
body.portal .filter-field select {
  width: 100%; height: 40px; padding: 0 12px;
  border-radius: 10px; border: 1px solid var(--p-line-2);
  background: #fff; color: var(--p-ink);
  font-family: inherit; font-size: 14px; font-weight: 400;
  box-shadow: none;
}
body.portal .filter-field input:focus, body.portal .filter-field select:focus {
  border-color: var(--p-accent); outline: none;
  box-shadow: 0 0 0 3px var(--p-accent-soft);
}
/* Search gets a magnifier so it is recognisable before it is read. */
body.portal .filter-field input.filter-search {
  padding-left: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236C7E8F' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: 10px 50%; background-size: 15px 15px;
}
.filter-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

/* Category and state chips, for filters that are one click rather than
   a control you have to open. */
.filter-chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 16px; }
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 13px; border-radius: 999px;
  border: 1px solid var(--p-line-2); background: rgba(255, 255, 255, 0.7);
  color: var(--p-ink-2); text-decoration: none;
  font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background 0.15s var(--ease-emph), color 0.15s var(--ease-emph);
}
.filter-chip:hover { background: #fff; color: var(--p-ink); }
.filter-chip .n { font-weight: 500; opacity: 0.6; font-variant-numeric: tabular-nums; }
.filter-chip.is-on {
  background: var(--p-accent); border-color: var(--p-accent); color: #fff;
}
.filter-chip.is-on .n { opacity: 0.75; }

/* ── List rows: results, candidates, assessments, tests ──── */
.list {
  display: flex; flex-direction: column;
  border-radius: 16px; overflow: hidden;
  background: var(--p-surface);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--p-shadow);
}
.list-head {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--p-line);
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--p-ink-3);
}
.list-row {
  position: relative;
  display: flex; align-items: center; gap: 16px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--p-line);
  color: inherit; text-decoration: none;
  transition: background 0.14s var(--ease-emph);
}
.list-row:last-child { border-bottom: none; }
a.list-row:hover, .list-row.is-link:hover { background: var(--p-hover); }
a.list-row:focus-visible { outline: 2px solid var(--p-accent); outline-offset: -2px; }
a.list-row::after {
  content: ""; flex: 0 0 auto; width: 6px; height: 6px; margin-left: 2px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); opacity: 0.25;
}
.list-row-main { flex: 1 1 auto; min-width: 0; }
/* The position of a row in a ranked list, first thing on the row. Only a
   row that has been scored has a position, so the element is rendered
   empty on the others rather than left out: the names stay in one column
   whether or not the person above them has sat the test yet. */
.list-rank {
  flex: 0 0 24px; align-self: center;
  font-size: 13px; font-weight: 600; color: var(--p-ink-3);
  font-variant-numeric: tabular-nums; text-align: right;
}
.list-title {
  margin: 0; font-size: 14.5px; font-weight: 600; color: var(--p-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.list-sub { margin: 3px 0 0; font-size: 13px; line-height: 1.45; color: var(--p-ink-2); }
.list-meta { flex: 0 0 auto; font-size: 13px; color: var(--p-ink-2); font-variant-numeric: tabular-nums; }
.list-meta strong { font-weight: 600; color: var(--p-ink); }
.list-end { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; margin-left: auto; }
/* A list dropped inside a panel is already framed by it. */
.panel > .list, .panel-body > .list {
  border: 0; box-shadow: none; background: transparent; border-radius: 0;
}

/* ── Panel: a titled block of content ────────────────────── */
.panel {
  border-radius: 16px;
  background: var(--p-surface);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--p-shadow);
  overflow: hidden;
}
.panel + .panel, .panel + .list, .list + .panel { margin-top: 18px; }
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding: 14px 18px;
  border-bottom: 1px solid var(--p-line);
}
.panel-title { margin: 0; font-size: 14.5px; font-weight: 600; color: var(--p-ink); }
.panel-body { padding: 18px; }
.panel-body > :first-child { margin-top: 0; }
.panel-body > :last-child { margin-bottom: 0; }

/* ── Card grid ───────────────────────────────────────────── */
body.portal .card-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
body.portal .card-grid.tight { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.card-tile {
  display: flex; flex-direction: column; gap: 7px;
  padding: 18px;
  border-radius: 14px;
  background: var(--p-surface);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--p-shadow);
  color: inherit; text-decoration: none;
  transition: transform 0.18s var(--ease-emph), background 0.18s var(--ease-emph),
              box-shadow 0.18s var(--ease-emph);
}
.card-tile-title { margin: 0; font-size: 15px; font-weight: 600; color: var(--p-ink); }
.card-tile-sub { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--p-ink-2); flex: 1 1 auto; }
.card-tile-meta {
  margin: 0; font-size: 12.5px; color: var(--p-ink-3);
  padding-top: 10px; border-top: 1px solid var(--p-line);
}
a.card-tile:hover { background: var(--p-hover); transform: translateY(-2px); box-shadow: var(--p-shadow-lift); }
a.card-tile:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; }

/* ── Empty state: one line and one action, nothing else ──── */
.empty {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 44px 24px; text-align: center;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.5);
  border: 1px dashed var(--p-line-2);
}
.empty p { margin: 0; font-size: 14.5px; color: var(--p-ink-2); max-width: 46ch; }
.panel .empty, .panel-body .empty { border: 0; background: transparent; padding: 34px 18px; }

/* ── Status pills ────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 23px; padding: 0 9px; border-radius: 999px;
  border: 1px solid transparent;
  font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; white-space: nowrap;
}
.pill-neutral   { background: rgba(20, 32, 44, 0.06);  color: #56687A; border-color: rgba(20, 32, 44, 0.14); }
.pill-invited   { background: rgba(20, 32, 44, 0.06);  color: #56687A; border-color: rgba(20, 32, 44, 0.14); }
.pill-started   { background: rgba(11, 99, 197, 0.09); color: #0B5AAF; border-color: rgba(11, 99, 197, 0.26); }
.pill-review    { background: rgba(180, 130, 10, 0.13);color: #7A5600; border-color: rgba(180, 130, 10, 0.32); }
.pill-validated { background: rgba(27, 127, 75, 0.11); color: #14603A; border-color: rgba(27, 127, 75, 0.30); }

/* ── Outcome chips ───────────────────────────────────────────
   A workflow pill says where a candidate has got to. An outcome says how
   they did, and the two must never be told in the same shape: a capsule
   is a state, a squared chip is a result. The chip is the 23px box the
   report uses for a band figure, so a row in the portal and a line in the
   printed report are recognisably the same object.

   The three fills come off the report's six-band ramp: green above the
   midpoint, yellow at it, orange below. Nothing here is red, and nothing
   here ever will be. A low score is a result, not a moral failure, and
   red would read as a verdict on the person rather than on the paper. */
.pill.is-good, .pill.is-warn, .pill.is-bad {
  border-radius: 6px; letter-spacing: 0.04em;
}
.pill.is-good { background: #D6EEDD; color: #125634; border-color: rgba(27, 127, 75, 0.28); }
.pill.is-warn { background: #FBEFC9; color: #6B5310; border-color: rgba(180, 130, 10, 0.30); }
.pill.is-bad  { background: #FAE3CC; color: #7A470F; border-color: rgba(196, 110, 26, 0.32); }

/* ── Meter: one value on a fixed scale ───────────────────────
   Track and fill, at the geometry and in the colours of .prof-track /
   .prof-fill in hexa-report.css, so a trait profile read on screen and
   the same profile printed tell one visual story. The fill carries the
   band; the figure beside it repeats it in words, so the bar is decorative
   and should be hidden from screen readers.

   The fill's width is the one inline style this vocabulary allows. A
   meter's length is the datum, not a decision about styling, and there is
   no honest way to express it in a class. */
.meter {
  flex: 0 0 118px; align-self: center;
  position: relative; display: block; height: 10px;
  border-radius: 5px; background: #E7EDF4; overflow: hidden;
}
.meter-fill { display: block; height: 100%; border-radius: 5px; background: var(--p-accent); }
.meter-fill.band-high   { background: #14713C; }
.meter-fill.band-good   { background: #1B8A4B; }
.meter-fill.band-mid    { background: #BFC13E; }
.meter-fill.band-fair   { background: #E8B93B; }
.meter-fill.band-low    { background: #E58A2E; }
.meter-fill.band-lowest { background: #D2711C; }

/* ── Toolbar: actions sitting above a list ───────────────── */
.toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 0 0 14px;
}
.toolbar-count { font-size: 13.5px; color: var(--p-ink-2); }
.toolbar-count strong { color: var(--p-ink); font-weight: 600; }

/* ── Detail layout: the thing, and a column of facts beside it ── */
.cols { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 18px; align-items: start; }
.cols-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
@media (max-width: 900px) { .cols { grid-template-columns: minmax(0, 1fr); } }

/* Facts: the short labelled values that describe one test or one result. */
.facts { display: flex; flex-direction: column; gap: 0; margin: 0; }
.fact {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 9px 0; border-bottom: 1px solid var(--p-line);
}
.fact:last-child { border-bottom: none; }
.fact-l { font-size: 12.5px; font-weight: 600; color: var(--p-ink-3); }
.fact-v { font-size: 13.5px; font-weight: 600; color: var(--p-ink); text-align: right; }

/* A genuinely tabular thing stays a table; it just needs somewhere to go
   on a narrow screen. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Buttons, portal proportions ─────────────────────────── */
body.portal .gbtn {
  height: 38px; padding: 0 16px; border-radius: 10px;
  font-size: 14px; font-weight: 600;
  background: #fff; border: 1px solid var(--p-line-2); color: var(--p-ink);
  box-shadow: 0 1px 2px rgba(18, 32, 46, 0.05);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
body.portal .gbtn:hover { background: #fff; border-color: rgba(20, 32, 44, 0.28); transform: none;
                          box-shadow: 0 2px 6px rgba(18, 32, 46, 0.10); }
body.portal .gbtn:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; }
body.portal .gbtn.primary {
  background: var(--p-accent); border-color: var(--p-accent); color: #fff;
  box-shadow: 0 1px 2px rgba(11, 99, 197, 0.28), 0 6px 16px rgba(11, 99, 197, 0.20);
}
body.portal .gbtn.primary:hover { background: #0A57AE; border-color: #0A57AE; }
body.portal .gbtn.ghost { background: transparent; border-color: var(--p-line-2); box-shadow: none; }
body.portal .gbtn.ghost:hover { background: rgba(255, 255, 255, 0.8); }
body.portal .gbtn.quiet {
  background: transparent; border-color: transparent; box-shadow: none;
  color: var(--p-ink-2); padding: 0 10px;
}
body.portal .gbtn.quiet:hover { background: rgba(255, 255, 255, 0.85); color: var(--p-ink); }
body.portal .gbtn.danger { background: #B4232F; border-color: #B4232F; color: #fff; }
body.portal .gbtn.sm { height: 31px; padding: 0 12px; font-size: 13px; border-radius: 8px; }
body.portal .gbtn svg { width: 17px; height: 17px; }

/* ── Cards and fields inherited from the marketing theme ─── */
body.portal .glass, body.portal .glass.card {
  background: var(--p-surface);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: var(--p-shadow);
}
body.portal .card { padding: 20px; }
body.portal .hero-card { padding: 30px 28px; }
body.portal h1, body.portal .display-2 {
  font-size: clamp(23px, 2.6vw, 29px); font-weight: 600;
  letter-spacing: -0.018em; line-height: 1.15; margin: 0 0 14px;
}
body.portal h1 em, body.portal .display-2 em { color: inherit; }
body.portal h2 { font-size: 14.5px; font-weight: 600; color: var(--p-ink); }
body.portal .lead { font-size: 14.5px; line-height: 1.55; color: var(--p-ink-2); max-width: 66ch; }
body.portal .meta { font-size: 13.5px; color: var(--p-ink-2); }
body.portal .fineprint { color: #7C8C9B; }
body.portal .field label:not(.f-choice) { font-size: 13px; font-weight: 600; color: #2C3D4D; }
body.portal .field input[type="text"], body.portal .field input[type="email"],
body.portal .field input[type="password"], body.portal .field input[type="number"],
body.portal .field input[type="search"], body.portal .field input[type="date"],
body.portal .field select, body.portal .field textarea, body.portal textarea:not(.fbx-well) {
  border-radius: 10px; border: 1px solid var(--p-line-2);
  background: #fff; color: var(--p-ink);
  font-size: 14.5px; font-weight: 400; padding: 10px 12px;
  box-shadow: none;
}
body.portal textarea:not(.fbx-well) { width: 100%; min-height: 110px; font: inherit; font-size: 14.5px; resize: vertical; }
body.portal .field .hint { font-size: 12px; color: var(--p-ink-3); }
body.portal .form-note, body.portal .form-error { border-radius: 10px; font-size: 13.5px; }

/* Legacy portal classes. The pages still using tables and the old stat
   block keep working while they are rebuilt on the vocabulary above. */
.co-wrap { width: 100%; margin: 0 auto; }
.co-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.co-table th {
  text-align: left; font-weight: 700; color: var(--p-ink-3); padding: 9px 12px;
  border-bottom: 1px solid var(--p-line); font-size: 11.5px;
  text-transform: uppercase; letter-spacing: 0.06em;
}
.co-table td { padding: 11px 12px; border-bottom: 1px solid var(--p-line); vertical-align: middle; }
.co-table tr:last-child td { border-bottom: none; }
body.portal .co-table tr:hover td { background: rgba(255, 255, 255, 0.55); }
.co-stat { text-align: left; padding: 16px 18px; }
.co-stat .n { font-size: 30px; font-weight: 600; letter-spacing: -0.025em; color: var(--p-ink); display: block;
              font-variant-numeric: tabular-nums; }
.co-stat .l { font-size: 11.5px; font-weight: 700; color: var(--p-ink-3); text-transform: uppercase; letter-spacing: 0.07em; }
body.portal .glass.co-stat-alert,
body.portal .co-stat-alert { border-color: rgba(180, 130, 10, 0.32); background: rgba(255, 250, 232, 0.9); }
.co-stat-alert .n { color: #8A6D00; }
.co-grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; }
.invite-link { font-family: ui-monospace, Menlo, monospace; font-size: 12px; word-break: break-all; color: var(--p-ink-2); }

/* A control that has to exist for the keyboard and the form, but that a
   label somewhere else is the visible half of. Not display:none: a file
   input that is not rendered cannot always be opened by its label. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ── Make box: one field, two ways to fill it ────────────────
   A company either says what it needs or hands over the test it already
   has, so there is one box and one button rather than two doors. */
.makebox {
  border-radius: 16px; overflow: hidden;
  background: #fff; border: 1px solid var(--p-line-2);
  box-shadow: var(--p-shadow);
  transition: border-color 0.15s var(--ease-emph), box-shadow 0.15s var(--ease-emph);
}
.makebox:focus-within { border-color: var(--p-accent); box-shadow: 0 0 0 3px var(--p-accent-soft), var(--p-shadow); }
body.portal .makebox textarea {
  display: block; width: 100%; min-height: 86px;
  padding: 16px 18px 6px; border: 0; border-radius: 0;
  background: transparent; font-size: 15.5px; line-height: 1.55;
  box-shadow: none; outline: none;
}
.makebox-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 12px 12px 14px;
}
.makebox-note {
  margin: 0; min-width: 0; flex: 1 1 auto;
  font-size: 12.5px; color: var(--p-ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.makebox-foot .gbtn.primary { flex: 0 0 auto; margin-left: auto; }
.makebox + form { margin: 0; }
/* The examples under the box are chips, and a chip row sets its own
   margins, so the gap to the box has to be put back. */
.makebox-examples { margin-top: 16px; }

/* ── Wizard: one question per step, then the work ────────────
   A brief that names the role, the length and the level writes a better
   test than a sentence does, and asking for all four at once is a form.
   So: small steps, one decision each, and a panel that shows the work
   while it runs. */
.wiz {
  width: min(540px, calc(100vw - 32px));
  padding: 0; border: 0; border-radius: 18px;
  background: #fff; color: var(--p-ink);
  box-shadow: 0 24px 64px rgba(18, 32, 46, 0.24);
}
.wiz::backdrop { background: rgba(16, 26, 36, 0.45); }
.wiz-body { padding: 24px 24px 22px; }
.wiz-eyebrow {
  margin: 0 0 10px; min-height: 15px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--p-ink-3);
}
body.portal .wiz-q { margin: 0 0 4px; font-size: 20px; font-weight: 600; letter-spacing: -0.015em; }
.wiz-sub { margin: 8px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--p-ink-2); }
.wiz-label {
  margin: 18px 0 8px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--p-ink-3);
}
.wiz-opts { display: grid; gap: 9px; margin: 18px 0 0; }
.wiz-opt {
  display: block; width: 100%; text-align: left;
  padding: 13px 15px; border-radius: 12px;
  border: 1px solid var(--p-line-2); background: #fff;
  font-family: inherit; cursor: pointer;
  transition: border-color 0.15s var(--ease-emph), background 0.15s var(--ease-emph);
}
.wiz-opt:hover { border-color: rgba(20, 32, 44, 0.3); background: rgba(255, 255, 255, 0.9); }
.wiz-opt:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; }
.wiz-opt.is-on { border-color: var(--p-accent); background: var(--p-accent-soft); }
.wiz-opt-t { display: block; font-size: 15px; font-weight: 600; color: var(--p-ink); }
.wiz-opt-s { display: block; margin-top: 3px; font-size: 13px; line-height: 1.45; color: var(--p-ink-2); }
.wiz-actions { display: flex; align-items: center; gap: 9px; margin: 22px 0 0; }
.wiz-actions .gbtn.primary { margin-left: auto; }
body.portal .wiz .field { margin: 16px 0 12px; }
body.portal .wiz input[type="text"] {
  width: 100%; height: 42px; padding: 0 13px;
  border-radius: 10px; border: 1px solid var(--p-line-2);
  background: #fff; color: var(--p-ink); font-family: inherit; font-size: 15px;
}
body.portal .wiz input[type="text"]:focus {
  border-color: var(--p-accent); outline: none; box-shadow: 0 0 0 3px var(--p-accent-soft);
}
/* Chips are the vocabulary's one-click choice, and a choice inside the
   wizard is a button rather than a link. */
button.filter-chip { font-family: inherit; cursor: pointer; }
.wiz-run { list-style: none; margin: 20px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.wiz-run-step {
  display: flex; align-items: center; gap: 11px;
  font-size: 14.5px; color: var(--p-ink-3);
}
.wiz-run-step::before {
  content: ""; flex: 0 0 auto; width: 9px; height: 9px;
  border-radius: 50%; background: var(--p-line-2);
}
.wiz-run-step.is-now { color: var(--p-ink); font-weight: 600; }
.wiz-run-step.is-now::before { background: var(--p-accent); box-shadow: 0 0 0 4px var(--p-accent-soft); }
.wiz-run-step.is-done { color: var(--p-ink-2); }
.wiz-run-step.is-done::before { background: #1B8A4B; }

/* ── Test preview: the paper, printed ────────────────────────
   A buyer chooses a test by reading it, so the detail page prints every
   question of one paper. Nothing here is a control: an option is a
   marker and a line of text, so a preview cannot be answered, and the
   markup of every option in a question is identical — a page that
   styled the right one differently would be the answer key. */
/* The count and the set-swap sit under the summary columns, and a toolbar
   sets its own margins, so the gap between the two has to be put back. */
.cols + .toolbar { margin-top: 30px; }
.qprev { list-style: none; margin: 0; padding: 0; }
.qprev-item { padding: 18px 0; border-top: 1px solid var(--p-line); }
.qprev-item:first-child { padding-top: 4px; border-top: 0; }
.qprev-item:last-child { padding-bottom: 0; }
.qprev-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 8px; }
.qprev-n {
  min-width: 18px; font-size: 12.5px; font-weight: 700; color: var(--p-ink-3);
  font-variant-numeric: tabular-nums;
}
.qprev-type {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--p-ink-3);
}
/* Several stems carry the passage they are about, separated by a blank
   line, so the line breaks the author wrote have to survive. */
.qprev-stem {
  margin: 0 0 12px; font-size: 14.5px; line-height: 1.6;
  color: var(--p-ink); white-space: pre-line;
}
.qprev-note { margin: 0 0 10px; font-size: 12.5px; color: var(--p-ink-3); }
.qprev-opts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.qprev-opt {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 13px; border-radius: 10px;
  background: rgba(255, 255, 255, 0.6); border: 1px solid var(--p-line);
  font-size: 14px; line-height: 1.5; color: var(--p-ink-2);
}
.qprev-opt::before {
  content: ""; flex: 0 0 auto; width: 15px; height: 15px; margin-top: 3px;
  border-radius: 50%; border: 1.5px solid var(--p-line-2); background: #fff;
}
.qprev-opts.is-multi .qprev-opt::before { border-radius: 5px; }
.qprev-key {
  flex: 0 0 auto; width: 13px;
  font-size: 12px; font-weight: 700; color: var(--p-ink-3); padding-top: 1px;
}
/* The five points of a self-report scale, printed once for the section
   they run through rather than under every statement. */
.qprev-opts.is-scale { flex-direction: row; flex-wrap: wrap; margin: 0 0 6px; }
.qprev-opts.is-scale .qprev-opt { flex: 1 1 150px; }
/* A pool a candidate is given one of: nothing is being chosen from it. */
.qprev-opts.is-given .qprev-opt::before { display: none; }
/* Where the candidate writes or speaks instead of choosing. */
.qprev-blank {
  display: flex; align-items: flex-start;
  min-height: 40px; padding: 11px 13px; margin: 0;
  border-radius: 10px; border: 1px dashed var(--p-line-2);
  background: rgba(255, 255, 255, 0.45);
  font-size: 13px; color: var(--p-ink-3);
}
.qprev-blank.is-tall { min-height: 92px; }
.qprev-blank + .qprev-note { margin-top: 12px; }

/* ── Narrow screens ──────────────────────────────────────────
   Below 900px the rail becomes a sticky top bar and the links become a
   row of pills that scrolls sideways. No hamburger, no JavaScript, and
   the current page stays visible instead of hiding behind a menu. It is
   laid out to work down to 320px. */
@media (max-width: 900px) {
  /* Block, not grid: a sticky grid item can only stick inside its own grid
     area, so a two-row grid would pin the bar to the top of row one and let
     it scroll away. As blocks, the bar's containing block is the whole
     shell and it stays put. */
  .portal-shell { display: block; }
  .portal-nav {
    grid-column: 1; height: auto; position: sticky; top: 0;
    flex-direction: row; align-items: center; gap: 10px;
    padding: 8px 12px; overflow: visible;
    border-right: 0; border-bottom: 1px solid var(--p-line);
  }
  .portal-brand { padding: 0 2px 0 0; flex: 0 0 auto; }
  .portal-brand img { height: 26px; }
  .portal-links {
    flex-direction: row; gap: 4px; flex: 1 1 auto; min-width: 0;
    overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; -ms-overflow-style: none;
    padding: 2px 0;
  }
  .portal-links::-webkit-scrollbar { display: none; }
  .portal-link { height: 34px; padding: 0 11px; font-size: 13.5px; }
  .portal-link.is-current::before { display: none; }
  .portal-link.is-current { box-shadow: inset 0 0 0 1px rgba(11, 99, 197, 0.35); }
  .portal-foot {
    margin-top: 0; padding-top: 0; padding-left: 10px;
    border-top: 0; border-left: 1px solid var(--p-line); flex: 0 0 auto;
  }
  .portal-who { display: none; }
  .portal-signout span { display: none; }
  .portal-signout { padding: 0 9px; }
  .portal-body { grid-column: 1; }
  .portal-main { padding: 22px 16px 10px; }
  .portal-fine { padding: 22px 16px max(22px, env(safe-area-inset-bottom)); }
}
@media (max-width: 620px) {
  .page-head { align-items: flex-start; gap: 12px; }
  .list-row { flex-wrap: wrap; gap: 8px 14px; }
  .list-row-main { flex: 1 1 100%; }
  /* A rank belongs beside the name it ranks, so where there is one the
     name stops taking the whole line and sits next to it. The values
     still wrap underneath, as they do on every other row. */
  .list-rank { flex: 0 0 20px; }
  .list-rank + .list-row-main { flex: 1 1 calc(100% - 40px); }
  .list-end { margin-left: 0; }
  .list-head { display: none; }
  .meter { flex: 0 0 96px; }
  .filter-bar { padding: 12px; }
  .filter-field, .filter-field.grow { flex: 1 1 100%; }
  .filter-actions { flex: 1 1 100%; }
  .filter-actions .gbtn { flex: 1 1 auto; }
  .stat-tiles { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
  .stat-tile { padding: 13px 14px; }
  .stat-tile-n { font-size: 25px; }
}

/* Printing a result should not print the navigation. */
@media print {
  .portal-nav, .portal-fine, .page-actions, .filter-bar, .toolbar { display: none !important; }
  .portal-shell { display: block; }
  .portal-main { max-width: none; padding: 0; }
  .panel, .list, .stat-tile, .card-tile { box-shadow: none; border: 1px solid #ccc; background: #fff; }
}

@media (prefers-reduced-motion: reduce) {
  .stat-tile, .card-tile, .list-row, .portal-link { transition: none !important; }
  a.stat-tile:hover, a.card-tile:hover { transform: none; }
}

/* ── Test runner motion ──────────────────────────────────────
   Answering a question used to do almost nothing and moving between
   them was a jump, so a candidate had no sense of their own progress
   without reading the counter. Everything here is direction-aware:
   forward and back look different, because that is the one thing the
   counter cannot tell you at a glance.

   All of it is decoration over state that is already announced in text.
   The reduce-motion rules at the end of this block are not an
   afterthought: a candidate sitting a timed test with vestibular
   sensitivity must be able to turn the whole thing off and lose
   nothing. */

/* One movement, not many. Animating every child of a question meant six
   elements arriving on six different clocks, which reads as a page
   flickering rather than a page turning. The question moves as the one
   object it is, and only its direction of travel changes. */
@keyframes q-in       { from { opacity: 0; transform: translate3d(0, 18px, 0); filter: blur(5px); } }
@keyframes q-in-back  { from { opacity: 0; transform: translate3d(0, -18px, 0); filter: blur(5px); } }

#q-body.q-enter,
#q-body.q-enter-back {
  animation: q-in 0.34s var(--ease-decel) backwards;
  will-change: transform, opacity;
}
#q-body.q-enter-back { animation-name: q-in-back; }

/* Choosing an answer. The ring is drawn outside the option so it cannot
   shift the text, and it is removed by the script once it has played. */
@keyframes opt-ring {
  from { opacity: 0.55; transform: scale(1); }
  to   { opacity: 0;    transform: scale(1.035); }
}
.opt { position: relative; }
.opt.just-picked::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  border: 1.5px solid var(--accent-bright);
  pointer-events: none;
  animation: opt-ring 0.5s var(--ease-decel) forwards;
}

/* The mark itself lands rather than appearing. */
.opt.selected::before { transition: transform var(--spring-fast), background 0.18s var(--ease-emph); }
.opt.just-picked::before { transform: scale(1.16); }

/* The bar is the only thing on screen that moves on its own, so it is
   the one a candidate learns to read without looking at it. */
.progress .fill { transition: transform 0.45s var(--ease-emph); transform-origin: left; }

/* The counter chip ticks when it changes, so the eye catches the change
   without leaving the question. */
@keyframes chip-tick { 50% { transform: translateY(-2px); } }
.chip.chip-ticked { animation: chip-tick 0.3s var(--ease-emph); }

/* ── The test on glass ───────────────────────────────────────
   The room the questions are asked in. The card breathes a little wider
   than the site's usual column, the small print is set to be read, and
   each new section is greeted by one sweep of light across the pane —
   the same light the rest of the site catches. */
body.in-test #quiz-card {
  max-width: 700px;
  border-radius: var(--r-stage);
  padding: 46px 44px;
}
@media (max-width: 640px) {
  body.in-test #quiz-card { padding: 30px 20px; border-radius: var(--r-card); }
}
body.in-test .fineprint { font-size: 13px; opacity: 0.9; }

/* The progress is a groove in the glass, and the light inside it moves:
   how far along you are, told by the one element that is always alive. */
body.in-test .progress {
  height: 7px;
  background: rgba(255, 255, 255, 0.07);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35), inset 0 -1px 0 rgba(255, 255, 255, 0.06);
  border-radius: var(--r-pill);
  overflow: hidden;
}
body.in-test .progress .fill { position: relative; }
body.in-test .progress .fill::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  background-size: 200% 100%;
  animation: prog-light 2.8s linear infinite;
}
@keyframes prog-light {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

/* Answers take their places one after the other — one element type on
   one clock, a hand dealing cards, not a page flickering. Only when the
   question itself arrives; answering re-renders without the deal. */
#q-body.q-enter button.opt,
#q-body.q-enter-back button.opt { animation: opt-in 0.4s var(--ease-decel) backwards; }
@keyframes opt-in {
  from { opacity: 0; transform: translateY(10px); }
}
#q-body.q-enter button.opt:nth-of-type(2), #q-body.q-enter-back button.opt:nth-of-type(2) { animation-delay: 0.05s; }
#q-body.q-enter button.opt:nth-of-type(3), #q-body.q-enter-back button.opt:nth-of-type(3) { animation-delay: 0.10s; }
#q-body.q-enter button.opt:nth-of-type(4), #q-body.q-enter-back button.opt:nth-of-type(4) { animation-delay: 0.15s; }
#q-body.q-enter button.opt:nth-of-type(5), #q-body.q-enter-back button.opt:nth-of-type(5) { animation-delay: 0.20s; }
#q-body.q-enter button.opt:nth-of-type(n+6), #q-body.q-enter-back button.opt:nth-of-type(n+6) { animation-delay: 0.24s; }
body.in-test .sub-glass {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
body.in-test .sub-glass .meta { font-size: 15px; line-height: 1.7; }

body.in-test .glass.hero-card { position: relative; overflow: hidden; }
body.in-test .glass.hero-card.section-enter::after {
  content: "";
  position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
  background: linear-gradient(105deg,
    transparent, rgba(255, 255, 255, 0.07) 45%,
    rgba(255, 255, 255, 0.13) 50%, rgba(255, 255, 255, 0.07) 55%,
    transparent);
  transform: skewX(-16deg);
  pointer-events: none;
  animation: quiz-sheen 1.2s ease 0.35s both;
}
@keyframes quiz-sheen {
  from { left: -60%; opacity: 1; }
  to   { left: 140%; opacity: 0.6; }
}

@media (prefers-reduced-motion: reduce) {
  #q-body.q-enter, #q-body.q-enter-back,
  body.in-test .glass.hero-card.section-enter::after,
  #q-body.q-enter button.opt, #q-body.q-enter-back button.opt,
  body.in-test .progress .fill::after,
  .opt.just-picked::after, .opt.just-picked::before, .chip.chip-ticked {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
  .progress .fill { transition: none !important; }
}
body.reduce-motion #q-body.q-enter,
body.reduce-motion #q-body.q-enter-back,
body.reduce-motion .glass.hero-card.section-enter::after,
body.reduce-motion #q-body.q-enter button.opt,
body.reduce-motion #q-body.q-enter-back button.opt,
body.reduce-motion .progress .fill::after,
body.reduce-motion .opt.just-picked::after,
body.reduce-motion .opt.just-picked::before,
body.reduce-motion .chip.chip-ticked {
  animation: none !important; transition: none !important; transform: none !important;
}
body.reduce-motion .progress .fill { transition: none !important; }

/* ── Result vignette ─────────────────────────────────────────
   The last thing on a practice result: a closing remark on numbers the
   candidate has already read. Not a speech bubble and not a character
   talking, at the owner's direction. It is a quiet panel that ends the
   page, and the artwork sits in it rather than delivering it.

   The sentences come from the attempt itself (see coach.php). The motion
   only decides the order they arrive in, so they are read rather than
   scanned.

   The art slot is :empty until the artwork exists, and an :empty slot is
   display:none, so the page is finished at every stage. */

.vignette {
  display: flex;
  align-items: center;
  gap: 20px;
  margin: 34px -6px -6px;
  padding: 24px 26px;
  border-radius: var(--r-row);
  border: 1px solid var(--glass-border);
  /* Darker than the card it closes, so it reads as an aside rather than as
     another section competing with the breakdown above it. */
  background:
    radial-gradient(120% 140% at 0% 50%, rgba(0, 170, 255, 0.10), transparent 60%),
    rgba(0, 0, 0, 0.18);
  animation: rise 0.5s var(--ease-decel) 0.35s backwards;
}

.vignette-art {
  flex: 0 0 auto;
  width: 104px;
  margin: 0;
  line-height: 0;
}
.vignette-art:empty { display: none; }
.vignette-art > img,
.vignette-art > svg {
  width: 100%;
  height: auto;
  display: block;
  /* The spring curve is written out rather than taken from --spring-default,
     which bundles a duration with its easing. In the animation shorthand that
     duration becomes a second time value and the delay a third, which is
     invalid, and the browser drops the whole declaration silently. */
  animation: coach-in 0.6s cubic-bezier(0.38, 1.21, 0.22, 1) 0.45s backwards;
}
@keyframes coach-in {
  from { opacity: 0; transform: translateY(10px) scale(0.94); }
}

.vignette-body { flex: 1 1 auto; min-width: 0; }
.vignette-line {
  margin: 0;
  /* Each line waits for the one above it, so the remark is read in order
     rather than landing as a block of text. */
  animation: rise 0.45s var(--ease-decel) calc(0.5s + var(--coach-i, 0) * 0.45s) backwards;
}
.vignette-line + .vignette-line { margin-top: 12px; }

@media (max-width: 560px) {
  .vignette { flex-direction: column; align-items: flex-start; gap: 16px; padding: 20px; }
  .vignette-art { width: 84px; }
}

@media (prefers-reduced-motion: reduce) {
  .vignette, .vignette-line, .vignette-art > img, .vignette-art > svg {
    animation: none !important;
  }
}
body.reduce-motion .vignette, body.reduce-motion .vignette-line,
body.reduce-motion .vignette-art > img, body.reduce-motion .vignette-art > svg {
  animation: none !important;
}

/* ── The leg: one part of a test, finished ───────────────────
   A test with five parts is five legs of one route. Finishing a part
   draws the leg that was just flown and lands the aircraft on the next
   waypoint, which is the one piece of progress a score line cannot show:
   how much of the route is behind you. The same component closes the
   route when the last part is done, and opens the results page.

   It sits above everything, is announced in text for a screen reader,
   and is skipped entirely when motion is reduced. */

.hx-leg {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  background: rgba(2, 13, 31, 0.72);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  animation: leg-in 0.28s var(--ease-decel);
}
.hx-leg.out { animation: leg-out 0.3s var(--ease-accel) forwards; }
@keyframes leg-in  { from { opacity: 0; } }
@keyframes leg-out { to   { opacity: 0; } }

.hx-leg-inner { width: min(620px, 88vw); text-align: center; }

.hx-route { width: 100%; height: auto; display: block; overflow: visible; }

/* The route as planned, and the route as flown. */
.hx-route .rt-base {
  fill: none;
  stroke: rgba(255, 255, 255, 0.22);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 1 9;
}
.hx-route .rt-flown {
  fill: none;
  stroke: var(--gold);
  stroke-width: 2.5;
  stroke-linecap: round;
  filter: drop-shadow(0 0 6px var(--gold-soft));
  transition: stroke-dashoffset 0.85s var(--ease-emph);
}

/* Waypoints: passed, being reached, still ahead. */
.hx-route .wp {
  fill: var(--bg);
  stroke: rgba(255, 255, 255, 0.3);
  stroke-width: 2;
  transition: stroke 0.3s var(--ease-emph), fill 0.3s var(--ease-emph);
}
.hx-route .wp.done { fill: var(--gold); stroke: var(--gold); }
/* An SVG shape scales about the user-space origin unless it is told
   otherwise, which sends the waypoint across the screen instead of
   growing where it stands. */
.hx-route .wp.now  {
  fill: var(--gold);
  stroke: var(--gold);
  transform-box: fill-box;
  transform-origin: center;
  animation: wp-land 0.55s var(--ease-decel) 0.62s backwards;
}
@keyframes wp-land {
  0%   { transform: scale(0.6); opacity: 0.4; }
  60%  { transform: scale(1.35); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.hx-route .wp-ring {
  fill: none;
  stroke: var(--gold);
  stroke-width: 2;
  transform-box: fill-box;
  transform-origin: center;
  animation: wp-ring 0.9s var(--ease-decel) 0.66s backwards;
}
@keyframes wp-ring {
  from { transform: scale(0.5); opacity: 0.7; }
  to   { transform: scale(2.6); opacity: 0; }
}

/* The aircraft, which flies the leg that was just completed. */
.hx-route .rt-plane {
  fill: var(--text);
  transition: transform 0.85s var(--ease-emph);
}
.hx-route .rt-plane.arrived { fill: var(--gold); }

.hx-leg-title {
  margin: 26px 0 0;
  font-size: clamp(26px, 4.6vw, 40px);
  font-weight: 300;
  letter-spacing: -0.01em;
  color: var(--text);
  animation: leg-text 0.5s var(--ease-decel) 0.5s backwards;
}
.hx-leg-title em { font-style: normal; color: var(--gold); }
.hx-leg-sub {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 15px;
  animation: leg-text 0.5s var(--ease-decel) 0.62s backwards;
}
@keyframes leg-text { from { opacity: 0; transform: translateY(10px); } }

/* The results page opens out of its own arrival, so the page under the
   overlay must not be readable through it before the overlay leaves.
   The reveal is an animation with a delay rather than something the
   script switches on: if the script never runs, the page still appears
   on its own, and a result is never left hidden behind a bug. */
body.hx-arriving main { animation: hx-page-in 0.5s var(--ease-decel) 1.75s backwards; }
@keyframes hx-page-in { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .hx-leg, .hx-leg *, .hx-route * { animation: none !important; transition: none !important; }
  body.hx-arriving main { animation: none !important; }
}
body.reduce-motion .hx-leg, body.reduce-motion .hx-leg *, body.reduce-motion .hx-route * {
  animation: none !important; transition: none !important;
}
body.reduce-motion.hx-arriving main { animation: none !important; }

/* ── Upload target (journey CV stage) ────────────────────────
   Same box a field would have, but it takes a file. */
.dropzone {
  border: 1.5px dashed var(--glass-border);
  border-radius: var(--r-box);
  background: var(--glass-bg);
  padding: 30px 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.2s var(--ease-emph), background 0.2s var(--ease-emph);
}
.dropzone:hover, .dropzone:focus-visible, .dropzone.over {
  border-color: var(--accent-bright);
  background: var(--glass-bg-strong);
}
.dropzone .dz-line { margin: 0 0 6px; color: var(--text); font-weight: 500; }
.dropzone .fineprint { margin: 0; }

/* ── Forms: the builder, the inbox, the public page ──────────
   Liquid glass on every surface, in the portal's light: frosted panes
   with a lit top edge, wells of glass for every input, questions as
   cards of glass that lift as they are touched. The builder reads as a
   place where something is made, starting with the invitation to make
   the first question. */
.fbx {
  background: rgba(255, 255, 255, 0.58);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 20px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95),
              inset 0 -1px 0 rgba(255, 255, 255, 0.35),
              0 14px 38px rgba(23, 48, 77, 0.10);
}
body .fbx-well {
  border: 1px solid rgba(23, 48, 77, 0.14);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 1px 3px rgba(23, 48, 77, 0.07), inset 0 -1px 0 rgba(255, 255, 255, 0.8);
  font-family: inherit; color: var(--p-ink);
  padding: 10px 13px; outline: none; width: 100%;
  transition: border-color 0.16s var(--ease-emph), box-shadow 0.16s var(--ease-emph);
}
body .fbx-well:focus, body.light .fbx-well:focus {
  border-color: var(--p-accent);
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 1px 3px rgba(23, 48, 77, 0.07), 0 0 0 3px rgba(11, 99, 197, 0.16);
}

.fb-share {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 14px; padding: 12px 18px; margin-bottom: 16px;
}
.fb-share .list-meta { flex: 1 1 240px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-share .row { flex: 0 0 auto; }
.fb-head { display: flex; flex-direction: column; gap: 12px; padding: 20px 22px; margin-bottom: 16px; }
.fb-title {
  border: none; background: transparent; width: 100%;
  font-family: inherit; font-size: 23px; font-weight: 650; color: var(--p-ink);
  outline: none; padding: 2px 0;
}
.fb-title::placeholder { color: var(--p-ink-3); }
.fb-intro { min-height: 54px; resize: vertical; font-size: 14px; line-height: 1.55; }
.fb-state { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.fb-state input[type="date"] { width: auto; }

/* A switch of glass: the track a well, the knob a bead of light. */
.fb-toggle { display: inline-flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--p-ink-2); cursor: pointer; }
.fb-toggle input {
  appearance: none; -webkit-appearance: none;
  width: 40px; height: 23px; border-radius: 999px; cursor: pointer;
  background: rgba(23, 48, 77, 0.16);
  box-shadow: inset 0 1px 3px rgba(23, 48, 77, 0.2);
  position: relative; outline: none; margin: 0;
  transition: background 0.2s var(--ease-emph);
}
.fb-toggle input::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 19px; height: 19px; border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 4px rgba(23, 48, 77, 0.3);
  transition: left 0.2s var(--ease-emph);
}
.fb-toggle input:checked { background: var(--p-accent); }
.fb-toggle input:checked::after { left: 19px; }
.fb-toggle input:focus-visible { outline: none; box-shadow: inset 0 1px 3px rgba(23,48,77,0.2), 0 0 0 3px rgba(11, 99, 197, 0.2); }

/* One question, one pane of glass. */
.fb-field { padding: 16px 20px; margin-bottom: 14px;
  transition: transform 0.18s var(--ease-emph), box-shadow 0.18s var(--ease-emph); }
.fb-field:hover { transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(255, 255, 255, 0.35),
              0 18px 44px rgba(23, 48, 77, 0.13); }
.fb-field-top { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
@media (max-width: 560px) {
  .fb-field-top .fb-label { flex: 1 1 100%; order: 2; }
  .fb-tools { margin-left: auto; }
}
.fb-kind {
  flex: 0 0 auto; padding: 5px 11px; border-radius: 999px;
  background: rgba(11, 99, 197, 0.10);
  border: 1px solid rgba(11, 99, 197, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  font-size: 11px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--p-accent);
}
.fb-label {
  flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 600;
  border: none; background: transparent; outline: none;
  font-family: inherit; color: var(--p-ink); padding: 4px 0;
}
.fb-label::placeholder { color: var(--p-ink-3); }
.fb-tools { flex: 0 0 auto; display: inline-flex; gap: 5px; }
.fb-opts { margin-top: 12px; resize: vertical; font-size: 13.5px; line-height: 1.6; }

/* The invitation that replaces an empty page: the first question asked
   for in the middle of a pane, not implied by a lonely button. */
.fb-empty {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 44px 24px; margin-bottom: 14px; text-align: center;
}
.fb-empty p { margin: 0; font-size: 14.5px; color: var(--p-ink-2); }

/* The twelve kinds, offered as tiles of glass. */
.fb-picker {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px; padding: 16px; margin-bottom: 14px;
}
.fb-pick {
  padding: 13px 10px; border-radius: 14px; cursor: pointer;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.95);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 4px 14px rgba(23, 48, 77, 0.07);
  font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--p-ink);
  text-align: center;
  transition: transform 0.16s var(--ease-emph), box-shadow 0.16s var(--ease-emph),
              border-color 0.16s var(--ease-emph);
}
.fb-pick:hover {
  transform: translateY(-2px);
  border-color: rgba(11, 99, 197, 0.35);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 10px 24px rgba(23, 48, 77, 0.12);
}
.fb-foot { display: flex; gap: 10px; margin: 6px 0 12px; }

@media (pointer: coarse) {
  .fb-tools { gap: 8px; }
  .fb-star { width: 40px; height: 40px; padding-top: 10px; }
  .fb-tools .gbtn.sm { height: 40px; min-width: 40px; }
  .fb-intro, .fb-label, .fb-opts { font-size: 16px; }
}

body.portal .fb-pick:focus-visible, body.portal .fb-star:focus-visible,
body.portal .fb-title:focus-visible, body.portal .fb-label:focus-visible,
body.portal .fbx-well:focus-visible {
  outline: 2px solid var(--p-accent); outline-offset: 2px;
}
.fb-rowlink { color: inherit; text-decoration: none; }

/* The inbox: the reading room in the same glass. */
.fi-cols { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 900px) { .fi-cols { grid-template-columns: 1fr; } .fi-list { max-height: 46vh; } }
.fi-list { max-height: 72vh; overflow-y: auto; }
.list-row.is-current { background: var(--p-hover); }
.fi-read { padding: 20px 24px; }
.fi-read-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px;
  padding-bottom: 12px; margin-bottom: 6px;
}
.fi-read-head .list-title { flex: 1 1 100%; min-width: 0; }
.fi-answer { padding: 11px 0; }
.fi-q { margin: 0 0 3px; font-size: 12px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--p-ink-2); }
.fi-a { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--p-ink); overflow-wrap: anywhere; }

/* The public page: choices as rows a thumb can hit, a dropdown in the
   same well every input sits in. */
.f-choice { display: flex; align-items: center; gap: 10px; padding: 9px 2px; font-size: 15px; cursor: pointer; }
.f-choice input {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 auto; width: 19px; height: 19px; margin: 0; cursor: pointer;
  border-radius: 6px;
  border: 1px solid var(--glass-border);
  background: rgba(255, 255, 255, 0.06);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
  transition: background 0.15s var(--ease-emph), box-shadow 0.15s var(--ease-emph);
}
.f-choice input[type="radio"] { border-radius: 50%; }
.f-choice input:checked {
  background: var(--accent-bright);
  box-shadow: inset 0 0 0 4px rgba(2, 13, 31, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.f-choice input:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
body.portal .f-choice input, .fb-preview .f-choice input {
  border-color: rgba(23, 48, 77, 0.25);
  background: rgba(255, 255, 255, 0.6);
  box-shadow: inset 0 1px 2px rgba(23, 48, 77, 0.08);
}
body.portal .f-choice input:checked, .fb-preview .f-choice input:checked {
  background: var(--p-accent);
  box-shadow: inset 0 0 0 4px rgba(255, 255, 255, 0.9);
}
body:not(.portal) select {
  width: 100%; padding: 13px 44px 13px 16px; font-size: 16px; color: var(--text);
  font-family: inherit; border-radius: var(--r-box);
  border: 1px solid var(--glass-border);
  background: rgba(255, 255, 255, 0.05)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C2D8EC' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
    no-repeat right 16px center / 16px 16px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); outline: none;
  appearance: none; -webkit-appearance: none;
  color-scheme: dark;
}
body:not(.portal) select:focus { border-color: var(--accent-bright); }
select.fbx-well {
  appearance: none; -webkit-appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235D7188' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  background-size: 15px 15px;
}

/* The statistics bars: a groove and its fill, no chrome around them. */
.st-bar {
  flex: 0 0 90px; height: 6px; border-radius: var(--r-pill);
  background: color-mix(in srgb, currentColor 12%, transparent);
  overflow: hidden; display: inline-block;
}
.st-bar > span {
  display: block; height: 100%;
  border-radius: var(--r-pill);
  background: var(--p-accent);
}

/* The needed-mark: small, red when it counts, one character. */
.fb-star {
  width: 26px; height: 26px; border-radius: 8px; cursor: pointer;
  border: 1px solid rgba(23, 48, 77, 0.14);
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
  font-family: inherit; font-size: 16px; line-height: 1;
  color: var(--p-ink-2); padding-top: 4px;
  transition: color 0.15s var(--ease-emph), border-color 0.15s var(--ease-emph);
}
.fb-star.is-on { color: #C42B3D; border-color: rgba(196, 43, 61, 0.45); }

/* What is being built, shown inert under the question. */
.fb-preview { margin-top: 12px; pointer-events: none; opacity: 0.82; }
.fb-preview .f-choice { color: var(--p-ink); font-size: 14px; padding: 6px 2px; }
.fb-preview input[type="file"] { padding: 8px 10px; }
.fb-preview input[type="file"]::file-selector-button,
body.portal input[type="file"]::file-selector-button {
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--p-ink); cursor: pointer;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(23, 48, 77, 0.16);
  border-radius: 999px;
  padding: 6px 15px; margin-right: 12px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

/* The quiet way back in, under the sign-in button. */
.forgot-link { font-size: 13px; color: var(--muted); text-decoration: none; }
.forgot-link:hover { color: var(--accent-bright); text-decoration: underline; }
body.portal .forgot-link { color: var(--p-ink-2); }
body.portal .forgot-link:hover { color: var(--p-accent); }
