/* ============================================================
   TYPEFACE — Inter (variable), self-hosted so the UI never flashes a
   fallback and works fully offline. The system stack stays as a fallback
   inside --font, so if the file is ever missing the UI still renders.
   ============================================================ */
@font-face {
  font-family: "Inter";
  src: url("/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ============================================================
     CORE SEMANTIC TOKENS (design-language §1). EVERYTHING derives
     from this small set; light + dark themes swap ONLY these names
     (dark comes "for free", §5.7). Palette = a refined, SUBTLY WARM
     "warm-graphite" neutral: pure-white sheets on a slightly deeper,
     barely-warm canvas; inks carry a faint warm cast. One accent.
     ============================================================ */
  --bg: #eae7e2;             /* canvas — a touch deeper + subtly warmer than surface */
  --surface: #ffffff;        /* raised surface: cards, content column (clean sheet) */
  --surface-2: #f5f3f0;      /* recessed zone: insets, quiet fills, chrome (warm off-white) */
  --ink: #1f1d1a;            /* primary text — rich warm near-black (≥12:1 on surface) */
  --ink-2: #524e47;          /* secondary text (≥7:1 on surface) */
  --ink-3: #756f66;          /* faint / disabled (≥4.5:1 on surface) */
  --line: #e3dfd8;           /* hairlines + dividers — reads on surface AND bg */
  --accent: #1f5fd6;         /* the single brand accent */
  --accent-strong: #1a52ba;  /* accent hover / pressed */
  --on-accent: #ffffff;      /* text/icon on accent (and on good/bad fills) */
  --good: #1f7a4d;
  --bad: #b4332a;
  --warn: #b26a00;
  --focus: #1f5fd6;          /* focus ring */
  --scrim: rgba(28, 24, 20, 0.45);   /* overlay backdrops (warm-neutral) */
  /* Native controls (date picker glyph, scrollbars) follow the active theme. */
  color-scheme: light;

  /* Soft state/accent backgrounds (a tint of the matching hue), tuned for warm neutrals. */
  --accent-soft: #e8f0fd;
  --good-soft: #e6f2e9;
  --bad-soft: #fbeceb;
  --warn-soft: #fdf1dd;

  /* Subtle interaction tint (list-row hover) — flips in dark. */
  --row-hover: rgba(28, 24, 20, 0.05);

  /* Accent-tinted glow for the primary button's depth (§4/§7). A faint wash of the
     brand hue so the ONE primary reads as pressable without a hard edge; stronger on
     hover, collapsed on press. Tuned per theme (accent hue differs light↔dark). */
  --accent-glow: rgba(31, 95, 214, 0.22);
  --accent-glow-strong: rgba(31, 95, 214, 0.30);

  /* Media well (video / camera preview) — deliberately dark in BOTH themes. */
  --well: #0d1117;
  --on-well: #ffffff;

  /* Type family — Inter with a system fallback (see @font-face above). */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* ============================================================
     BACK-COMPAT ALIASES — every legacy token name kept alive by
     pointing at a core token, so existing rules keep rendering and
     now derive from the theme automatically.
     ============================================================ */
  --frame-bg: var(--surface);
  --chrome-bg: var(--surface-2);
  --ink-soft: var(--ink-2);
  --ink-faint: var(--ink-3);

  /* Radii (concentric: inner < outer). Cards nudged a touch friendlier in Wave C
     (--r 12→14, --r-lg 16→18); --r-sm stays 8 so nested controls remain concentric
     (button/input 10 < card 14 < panel 18). */
  --r-sm: 8px;
  --r: 14px;
  --r-lg: 18px;
  --r-full: 999px;
  --radius: var(--r);        /* legacy alias */

  /* Elevation — soft, low-contrast, warm-tinted shadows (two-layer on --e-1 so a
     resting sheet lifts off the canvas without a hard edge). */
  --e-1: 0 1px 2px rgba(28, 24, 20, 0.05), 0 4px 10px rgba(28, 24, 20, 0.05);
  --e-2: 0 4px 18px rgba(28, 24, 20, 0.10);
  --e-3: 0 12px 40px rgba(28, 24, 20, 0.12);
  --shadow: var(--e-3);      /* legacy alias */

  /* Persistent header height. The ONE top bar is fixed at this height on every
     page; the app shell + every full-screen overlay start below it. */
  --topbar-h: 56px;

  /* Spacing scale (base-8, +4 for fine tuning). One relationship type = one gap. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s8: 32px;
  --s12: 48px;
  --s16: 64px;

  /* Type scale. */
  --t-sm: 13px;
  --t-base: 15px;
  --t-lg: 18px;
  --t-xl: 22px;
  --t-2xl: 28px;

  /* Readable measure for the content column (§2). Grids may run wider. */
  --measure: 680px;

  /* Shell region sizes. */
  --sidebar-w: 280px;
  --comments-w: 340px;

  /* ============================================================
     MOTION (§8) — ONE motion language. Interactive state changes and
     overlay entrances run 150–200ms; ease-out on the way in. Only
     meaningful motion; no decoration. Respect prefers-reduced-motion
     (see the reduce block below). Token-driven so timing is consistent.
     ============================================================ */
  --motion-fast: 160ms;   /* interactive state change (hover/press/focus) */
  --motion-med: 200ms;    /* overlay / page entrance */
  --ease: cubic-bezier(0.2, 0, 0, 1);      /* ease-out (entrance/state) */
  --ease-in: cubic-bezier(0.4, 0, 1, 1);   /* ease-in (exit) */
  /* Canonical interactive transition — reused by every control. */
  --tr-interactive: background var(--motion-fast) var(--ease),
                    border-color var(--motion-fast) var(--ease),
                    color var(--motion-fast) var(--ease),
                    box-shadow var(--motion-fast) var(--ease),
                    transform var(--motion-fast) var(--ease),
                    opacity var(--motion-fast) var(--ease);
}

/* ============================================================
   DARK THEME — overrides ONLY the core semantic tokens; every other
   value (aliases, components, layout) derives from them, so the whole
   UI adapts. Provided two ways: system preference AND an explicit
   [data-theme="dark"] override; [data-theme="light"] forces light.
   ============================================================ */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    /* Warm-graphite dark: layered surfaces (bg darkest → surface-2 recessed →
       surface raised) with a faint warm cast; inks stay legible. */
    --bg: #14110e;
    --surface: #201d19;
    --surface-2: #1a1714;
    --ink: #ede9e3;
    --ink-2: #b6aea3;
    --ink-3: #857e73;
    --line: #34302a;
    --accent: #2f81f7;
    --accent-strong: #4d94ff;
    --on-accent: #ffffff;
    --good: #2ea043;
    --bad: #e5534b;
    --warn: #d29922;
    --focus: #4d94ff;
    --scrim: rgba(8, 6, 4, 0.7);

    --accent-soft: rgba(56, 139, 253, 0.15);
    --good-soft: rgba(46, 160, 67, 0.15);
    --bad-soft: rgba(229, 83, 75, 0.15);
    --warn-soft: rgba(210, 153, 34, 0.15);

    --row-hover: rgba(255, 250, 242, 0.06);

    --accent-glow: rgba(47, 129, 247, 0.30);
    --accent-glow-strong: rgba(47, 129, 247, 0.42);

    --e-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 10px rgba(0, 0, 0, 0.4);
    --e-2: 0 4px 18px rgba(0, 0, 0, 0.6);
    --e-3: 0 12px 40px rgba(0, 0, 0, 0.7);
  }
}

/* Explicit dark (wins over system light). */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #14110e;
  --surface: #201d19;
  --surface-2: #1a1714;
  --ink: #ede9e3;
  --ink-2: #b6aea3;
  --ink-3: #857e73;
  --line: #34302a;
  --accent: #2f81f7;
  --accent-strong: #4d94ff;
  --on-accent: #ffffff;
  --good: #2ea043;
  --bad: #e5534b;
  --warn: #d29922;
  --focus: #4d94ff;
  --scrim: rgba(8, 6, 4, 0.7);

  --accent-soft: rgba(56, 139, 253, 0.15);
  --good-soft: rgba(46, 160, 67, 0.15);
  --bad-soft: rgba(229, 83, 75, 0.15);
  --warn-soft: rgba(210, 153, 34, 0.15);

  --row-hover: rgba(255, 250, 242, 0.06);

  --accent-glow: rgba(47, 129, 247, 0.30);
  --accent-glow-strong: rgba(47, 129, 247, 0.42);

  --e-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 10px rgba(0, 0, 0, 0.4);
  --e-2: 0 4px 18px rgba(0, 0, 0, 0.6);
  --e-3: 0 12px 40px rgba(0, 0, 0, 0.7);
}

/* Explicit light (wins over system dark) — re-assert the light core tokens. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #eae7e2;
  --surface: #ffffff;
  --surface-2: #f5f3f0;
  --ink: #1f1d1a;
  --ink-2: #524e47;
  --ink-3: #756f66;
  --line: #e3dfd8;
  --accent: #1f5fd6;
  --accent-strong: #1a52ba;
  --on-accent: #ffffff;
  --good: #1f7a4d;
  --bad: #b4332a;
  --warn: #b26a00;
  --focus: #1f5fd6;
  --scrim: rgba(28, 24, 20, 0.45);

  --accent-soft: #e8f0fd;
  --good-soft: #e6f2e9;
  --bad-soft: #fbeceb;
  --warn-soft: #fdf1dd;

  --row-hover: rgba(28, 24, 20, 0.05);

  --accent-glow: rgba(31, 95, 214, 0.22);
  --accent-glow-strong: rgba(31, 95, 214, 0.30);

  --e-1: 0 1px 2px rgba(28, 24, 20, 0.05), 0 4px 10px rgba(28, 24, 20, 0.05);
  --e-2: 0 4px 18px rgba(28, 24, 20, 0.10);
  --e-3: 0 12px 40px rgba(28, 24, 20, 0.12);
}

* { box-sizing: border-box; }

/* Always-visible keyboard focus ring (§7). Only shows on keyboard focus, so
   mouse/touch appearance is unchanged. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Motion accessibility (§8): honour prefers-reduced-motion by cutting all
   non-essential transitions/animations to a near-instant, motionless change.
   Nothing depends on motion to be usable. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Tabular figures — for any run of numbers that should stay column-aligned
   (HUD stat values, counters, leaderboard, pay/points, timers). */
.tabular,
[class$="-num"],
[class$="-val"],
[class$="-value"] { font-variant-numeric: tabular-nums; }

body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px 16px;
}

.frame {
  position: relative;
  width: 480px;
  max-width: 100%;
  height: min(760px, calc(100vh - 56px));
  background: var(--frame-bg);
  border-radius: 18px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ---- Содержание: toggle button (always available, floats top-right) ---- */
.toc-toggle {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  transition: var(--tr-interactive);
}
.toc-toggle:hover { border-color: var(--accent); color: var(--accent); }
.toc-toggle:active { transform: translateY(1px); }
.toc-burger {
  position: relative;
  width: 16px;
  height: 12px;
  flex-shrink: 0;
  border-top: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
}
.toc-burger::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: translateY(-50%);
}

/* ---- Содержание: overlay panel ---- */
.toc-overlay {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: flex;
}
.toc-overlay[hidden] { display: none; }
.toc-backdrop {
  position: absolute;
  inset: 0;
  background: var(--scrim);
}
.toc-panel {
  position: relative;
  margin-left: auto;
  width: 100%;
  max-width: 100%;
  height: 100%;
  background: var(--frame-bg);
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow);
  animation: toc-in 0.18s ease;
}
@keyframes toc-in { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
.toc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.toc-title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--ink);
}
.toc-close {
  width: 40px;
  height: 40px;
  font-size: 24px;
  line-height: 1;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  transition: var(--tr-interactive);
}
.toc-close:hover { border-color: var(--ink-faint); background: var(--row-hover); }

.toc-list {
  flex: 1;
  overflow-y: auto;
  padding: 12px 14px 24px;
  -webkit-overflow-scrolling: touch;
}

/* top-level standalone items (Старт / Финал) */
.toc-item {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 12px 14px;
  margin-bottom: 4px;
  font-size: 15px;
  line-height: 1.35;
  text-align: left;
  color: var(--ink-soft);
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: var(--tr-interactive);
}
.toc-item:hover { background: var(--row-hover); color: var(--ink); }
.toc-item:active { transform: translateY(1px); }
.toc-item-top { font-weight: 600; color: var(--ink); }
.toc-item.is-current {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
}

/* knowledge exam entry */
.toc-exam {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--accent);
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  margin-top: 6px;
}
.toc-exam:hover { background: var(--accent-soft); color: var(--accent); }
.toc-exam-glyph { display: inline-flex; align-items: center; line-height: 0; }
.toc-exam-glyph svg { display: block; }

/* day group */
.toc-day {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 10px;
  overflow: hidden;
}
.toc-day-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 48px;
  padding: 12px 16px;
  background: var(--surface-2);
  border: none;
  cursor: pointer;
  transition: var(--tr-interactive);
}
.toc-day-head:hover { background: color-mix(in srgb, var(--surface-2) 90%, var(--ink)); }
.toc-day.is-locked .toc-day-head { cursor: not-allowed; }
.toc-day.is-locked .toc-day-head:hover { background: var(--surface-2); }
.toc-day-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}
.toc-caret {
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--ink-faint);
  border-bottom: 2px solid var(--ink-faint);
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}
.toc-day.is-open .toc-caret { transform: rotate(-135deg); }
.toc-day-body { display: none; padding: 8px 8px 12px; }
.toc-day.is-open .toc-day-body { display: block; }

.toc-lesson-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--ink-faint);
  padding: 12px 8px 4px;
}
.toc-day-body .toc-item { font-size: 14px; }

/* (scroll-lock while the contents drawer is open is scoped to the narrow
   fallback in the app-shell section below; on desktop the sidebar is persistent) */

/* ---- Top bar ---- */
.topbar {
  padding: 14px 24px 14px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.topbar.hidden { display: none; }
.topbar-row {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
}
/* Top bar is chrome: keep the progress-fill as the single accent; the day/lesson
   labels are muted so the bar recedes (squint test). */
.day-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.lesson-label {
  font-size: 13px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
/* One orientation anchor read as a single line: «День N из 8 · Урок Y из Z».
   The middot appears only when a step label is present (lesson / overview /
   check / registration step); it never dangles after a bare phase label. */
.topbar-row .lesson-label:not(:empty)::before {
  content: "·";
  margin-right: var(--s2);
  color: var(--ink-faint);
}
/* Header progress: a thin --line track with an --accent fill (the header's one
   accent), fully rounded ends, and a smooth width transition on both themes. */
.progress-track {
  height: 4px;
  background: var(--line);
  border-radius: var(--r-full);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  width: 0;
  min-width: 0;
  background: var(--accent);
  border-radius: var(--r-full);
  transition: width var(--motion-med) var(--ease);
}
.counter {
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink-faint);
}

/* ---- Stage ---- */
.stage {
  flex: 1;
  overflow-y: auto;
  padding: 28px 24px;
  /* Column so a SHORT single-child screen can center in the available height
     (kill-the-void, §3/§7): margin-block:auto centers it only when there is free
     space; when the content is taller than the stage it collapses to 0, so the
     screen top-anchors and scrolls normally. Long lessons/quizzes therefore stay
     top-anchored; only short unlock/intro screens center. */
  display: flex;
  flex-direction: column;
}
/* Type-scale roles for the reading column (§2). Heading sits tight to its own
   body (--s2); paragraph rhythm is --s4; a new subsection heading opens a
   section break (--s8 top). One vertical rhythm across every content screen. */
.stage h1 {
  font-size: 26px;
  line-height: 1.2;
  font-weight: 690;
  margin: 0 0 var(--s2);
  letter-spacing: -0.02em;
}
.stage h2 {
  font-size: 20px;
  line-height: 1.3;
  font-weight: 650;
  margin: 0 0 var(--s2);
}
.stage * + h2 { margin-top: var(--s8); }
.stage p {
  font-size: 16px;          /* study reading is comfier a touch larger than UI 15 */
  line-height: 1.7;         /* §6/§10 — unhurried body reading rhythm (Inter metrics) */
  color: var(--ink);        /* body in PRIMARY ink — grey long-form is tiring to read */
  margin: 0 0 var(--s5);    /* more air between paragraphs so the wall breaks up */
}
.stage p strong { color: var(--ink); font-weight: 680; } /* key terms pop against dark body */
/* Lede: the first paragraph of a lesson — a slightly larger entry point that
   breaks the monolith and eases the reader in (§5). */
.stage .lede {
  font-size: 18px;
  line-height: 1.6;
  color: var(--ink);
  margin: 0 0 var(--s5);
}
.stage ul {
  margin: 0 0 var(--s5);
  padding-left: var(--s5);
}
.stage li {
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  margin-bottom: var(--s3);
}
.stage li::marker { color: var(--ink-faint); }
.stage li strong { color: var(--ink); font-weight: 680; }
/* Reading column: cap the measure by CHARACTER count (~66ch) so lines stay in the
   comfortable 60–70 range regardless of font size — the main cure for the wall. */
.stage > .reading { max-width: 66ch; }
.eyebrow {
  font-size: 12px;
  font-weight: 550;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 var(--s2);
}
/* ---- Callouts: important notes are clearly SET APART from body (3 kinds) ---- */
.callout {
  display: flex; gap: var(--s3); align-items: flex-start;
  margin: var(--s6) 0; border-radius: var(--r-sm);
}
.callout-icon { flex: none; display: inline-flex; margin-top: 2px; }
.callout-icon svg { width: 18px; height: 18px; }
.callout-text { margin: 0; font-size: 15px; line-height: 1.6; }
.callout-text strong { font-weight: 680; }
/* note — key idea / definition: soft accent tint + accent bar + bulb. */
.callout-note {
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  padding: var(--s3) var(--s4);
}
.callout-note .callout-icon { color: var(--accent); }
.callout-note .callout-text { color: var(--ink); }
/* example — a spoken line / script: recessed surface, quiet, italic. */
.callout-example {
  background: var(--surface-2);
  border-left: 3px solid var(--line);
  padding: var(--s3) var(--s4);
}
.callout-example .callout-icon { color: var(--ink-faint); }
.callout-example .callout-text { color: var(--ink-soft); font-style: italic; }
/* next — a bridge to the following topic: no fill, muted, an arrow. */
.callout-next { margin: var(--s5) 0; padding: 0; }
.callout-next .callout-icon { color: var(--ink-faint); margin-top: 1px; }
.callout-next .callout-icon svg { width: 16px; height: 16px; }
.callout-next .callout-text { color: var(--ink-faint); font-size: 14px; }

/* ---- Cover ---- */
.cover {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: left;
}
.cover .brand {
  font-size: 12px;
  font-weight: 550;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s4);
}
.cover h1 { font-size: 26px; line-height: 1.2; font-weight: 690; letter-spacing: -0.02em; margin-bottom: var(--s4); }
.cover p { font-size: 15px; line-height: 1.55; color: var(--ink-soft); margin-bottom: var(--s4); }
.cover p:last-child { margin-bottom: 0; }

/* Превью реальных индикаторов из шапки (попытки + оплата) на обложке. */
.cover-indicators {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 4px 0 22px;
}
.cover-chip {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  padding: 7px 14px;
}
.cover-chip-pay { color: var(--good); }

/* ---- ONE unlock-screen template (Layer 1) ----
   Shared by the day-0 cover, the mid-course Серия unlock, and the points/shop reveal,
   so every "a mechanic goes live" moment reads the same. One left-anchored reading
   column; sections grouped by whitespace (§4), a single accent on the eyebrow. */
.mech-unlock { max-width: var(--measure); margin: 0 auto; }
.mech-unlock .mech-brand {
  font-size: 12px; font-weight: 550; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 var(--s4);
}
.mech-unlock .mech-lead { margin-bottom: var(--s6); }
/* «что даёт» / «как связано» blocks: a caption label over its text; between-block
   space (--s6) exceeds within-block space so the grouping reads. */
.mech-unlock .mech-section { margin-bottom: var(--s6); }
.mech-unlock .mech-section:last-child { margin-bottom: 0; }
.mech-section-label {
  display: flex; align-items: center; gap: var(--s2);
  font-size: 12px; font-weight: 650; letter-spacing: 0.02em;
  color: var(--ink-faint); margin: 0 0 var(--s2);
}
.mech-section-text { font-size: 15px; line-height: 1.6; color: var(--ink-soft); margin: 0; }
/* Deferent aside: the shop is optional / reachable from the menu. Muted + small so it
   reads as a quiet note, not an instruction. Token-driven → light + dark. */
.mech-note { margin: var(--s6) 0 0; font-size: 13px; line-height: 1.55; color: var(--ink-3); }
/* Cover: two mechanics side by side, each an identical card so they carry equal
   weight. --surface card + hairline (§5 minimal container for a distinct object). */
.mech-unlock-cover .mech-item {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: var(--s4) var(--s4) calc(var(--s4) - 2px);
  margin-bottom: var(--s3);
}
.mech-item-title { font-size: 17px; font-weight: 700; color: var(--ink); margin: 0 0 var(--s2); }
.mech-item-lead { font-size: 14px; line-height: 1.55; color: var(--ink-soft); margin: 0 0 var(--s3); }
.mech-part { font-size: 14px; line-height: 1.55; color: var(--ink-soft); margin: 0; }
.mech-part-label {
  display: inline-flex; align-items: center; gap: 5px; vertical-align: baseline;
  font-size: 12px; font-weight: 650; letter-spacing: 0.02em;
  color: var(--ink-faint); text-transform: uppercase; margin-right: 6px;
}
.mech-unlock-cover .mech-section { margin-top: var(--s6); }

/* ---- Inline chip preview on an unlock screen ----
   A captioned mini-strip that mirrors the real HUD corner, so the explanation points
   at a concrete copy of the chip(s) it introduces rather than an empty header. The
   chips are presentational twins (.stat.stat-static, non-interactive); the strip sits
   on --surface-2 with a hairline so it reads as "the top bar", tokenized, light+dark. */
.mech-preview { margin-bottom: var(--s6); }
.mech-preview-caption {
  font-size: 12px; font-weight: 650; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 var(--s2);
}
.mech-preview-strip {
  display: inline-flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); padding: var(--s2) var(--s3);
}
/* Non-interactive twin: keep the chip's look, drop the button affordances. Force the
   label visible even under the < 760px rule that hides HUD labels — here it's teaching. */
.stat-static { cursor: default; }
.stat-static:hover { background: transparent; border-color: transparent; }
.mech-preview-strip .stat-label { display: inline; }

/* ---- Game cards ---- */
.game-intro {
  font-size: 14px;
  color: var(--ink-soft);
  margin-bottom: 18px;
  line-height: 1.55;
}
/* Game "client quote" object — the .card primitive with a muted quote tint. */
.quote-card {
  background: var(--surface-2);
  padding: var(--s6);
  margin-bottom: var(--s6);
}
.quote-card .quote {
  font-size: var(--t-lg);
  line-height: 1.45;
  color: var(--ink);
  font-weight: 500;
}
.choice-row {
  display: flex;
  gap: var(--s2);
  margin-bottom: var(--s4);
}
.choice-col {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  margin-bottom: var(--s4);
}
/* Quiz/game choices use the .option primitive; the horizontal row centers them. */
.choice-row .option { flex: 1; justify-content: center; text-align: center; font-weight: 600; }
/* Stacked quiz questions: between-group gap (--s8) clearly larger than the within-group
   gaps (question↔options --s3, option↔option --s2), so groups read as distinct. */
.quiz-group { margin: 0 0 var(--s8); }
.quiz-group:last-child { margin-bottom: 0; }
/* Promoted quiz question: heavier text on the plain column (no recessed grey card). */
.quiz-q {
  font-size: var(--t-lg); font-weight: 700; line-height: 1.4;
  color: var(--ink); margin: 0 0 var(--s3);
}

/* Feedback — de-boxed: a hairline accent bar carries the verdict color; the body
   reads as plain secondary text. No filled panel. Clean in light + dark. */
.feedback {
  margin-top: var(--s3);
  padding: var(--s1) 0 var(--s1) var(--s4);
  border-left: 3px solid var(--line);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-soft);
}
.feedback.good { border-left-color: var(--good); }
.feedback.bad { border-left-color: var(--bad); }
.feedback .verdict { font-weight: 700; display: block; margin-bottom: var(--s1); }
.feedback.good .verdict { color: var(--good); }
.feedback.bad .verdict { color: var(--bad); }
.feedback.hidden { display: none; }

.game-progress {
  font-size: 12px;
  color: var(--ink-faint);
  margin-bottom: 14px;
}

/* ---- timedQuiz: timed single-choice recall run ----
   Serious, token-driven, light+dark via the shared vars. The countdown reads big and
   tabular; a thin bar mirrors it; both shift to --warn under 5 s. No arcade styling. */
.timed { margin-top: var(--s2); }
.timed-start { text-align: left; }
.timed-start-line {
  font-size: 14px; line-height: 1.55; color: var(--ink-soft); margin: 0 0 var(--s4);
}
.timed-start-btn { width: 100%; }
.timed-meter {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); margin-bottom: var(--s2);
}
.timed-time { display: flex; align-items: baseline; gap: var(--s2); }
.timed-time-label {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-faint);
}
.timed-time-val {
  font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em; color: var(--ink); line-height: 1;
}
.timed-meter.is-low .timed-time-val { color: var(--warn); }
.timed-progress { font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.timed-bar {
  height: 4px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; margin-bottom: var(--s5);
}
.timed-bar-fill {
  height: 100%; width: 100%; border-radius: 999px; background: var(--accent);
  transition: width 100ms linear;
}
.timed-bar.is-low .timed-bar-fill { background: var(--warn); }
.timed-q {
  font-size: var(--t-lg); font-weight: 700; line-height: 1.4;
  color: var(--ink); margin: 0 0 var(--s3);
}
.timed-result { text-align: center; }
.timed-result-title {
  font-size: var(--t-lg); font-weight: 700; color: var(--ink); margin-bottom: var(--s2);
}
.timed-result-line { font-size: 14px; color: var(--ink-soft); margin: 0 0 var(--s4); }
.timed-again { width: 100%; }

/* ---- orderSteps («Упорядочивание») + matchPairs («Сопоставление / пары») ----
   Serious, token-driven, light+dark from the shared vars. Ordering reuses the exam's
   chevron rows (.exam-order-*); only the prompt/sub/check-button chrome is role-specific
   and shared with matching. */
.order-prompt {
  font-size: var(--t-lg); font-weight: 700; line-height: 1.4;
  color: var(--ink); margin: var(--s2) 0 var(--s2);
}
.order-sub { font-size: 14px; color: var(--ink-soft); line-height: 1.5; margin: 0 0 var(--s4); }
.order-steps { margin-bottom: var(--s4); }
.order-check { width: 100%; margin-top: var(--s2); }

/* Matching — two columns of tappable items; select-left-then-right. A shared number
   badge shows each candidate-made link (never correctness). */
.match-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3);
  margin-bottom: var(--s3);
}
.match-col { display: flex; flex-direction: column; gap: var(--s2); }
.match-item {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 56px;
  text-align: left; padding: var(--s3); font: inherit; font-size: 14px;
  font-weight: 500; line-height: 1.35; color: var(--ink); background: var(--surface);
  border: 1.5px solid var(--line); border-radius: 10px; cursor: pointer;
  transition: var(--tr-interactive);
}
.match-item:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.match-item:active:not(:disabled) { transform: translateY(1px); }
.match-item:disabled { cursor: default; }
.match-item.is-selected { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 2px var(--accent-soft); }
.match-item.is-paired { border-color: var(--accent); }
.match-item-text { flex: 1; }
.match-badge {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.match-status { font-size: 13px; color: var(--ink-faint); font-variant-numeric: tabular-nums; margin: 0 0 var(--s3); }

/* ---- callCritique / branchDialogue / qualifyLead (judgment / scenario formats) ----
   Serious, token-driven, light+dark from the shared vars. Reuse the .option / .choice-col /
   .feedback / .card primitives; only the transcript + persona chrome is role-specific.
   Real <button>s throughout inherit the global :focus-visible ring. */

/* A short call transcript rendered as TEXT: role label + line, agent vs client tinted. */
.critique-setup, .branch-setup {
  font-size: 14px; color: var(--ink-soft); line-height: 1.55; margin: 0 0 var(--s3);
}
.critique-snippet { padding: var(--s4); margin-bottom: var(--s4); }
.dialogue-line {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s1) var(--s3);
  align-items: baseline; padding: var(--s2) 0;
}
.dialogue-line + .dialogue-line { border-top: 1px solid var(--line); }
.dialogue-who {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-faint);
}
.dialogue-agent .dialogue-who { color: var(--accent); }
.dialogue-text { font-size: 15px; line-height: 1.5; color: var(--ink); }
.critique-q {
  font-size: var(--t-lg); font-weight: 700; line-height: 1.4;
  color: var(--ink); margin: var(--s2) 0 var(--s3);
}

/* branchDialogue — a running transcript (log) with the live turn below it. Client and the
   candidate's own picked line stack as tinted rows; a single advance button moves on. */
.branch-log { margin-bottom: var(--s4); display: flex; flex-direction: column; gap: 0; }
.branch-log .dialogue-line { border-top: none; }
.branch-log .dialogue-line + .dialogue-line { border-top: 1px solid var(--line); }
.branch-host { margin-bottom: var(--s2); }
.branch-next { width: 100%; margin-top: var(--s2); }
.branch-close { text-align: left; padding: var(--s5); }
.branch-close-title {
  font-size: var(--t-lg); font-weight: 700; color: var(--good); margin-bottom: var(--s2);
}
.branch-close-text { font-size: 14px; line-height: 1.55; color: var(--ink-soft); margin: 0; }

/* qualifyLead — persona card, наш/не наш verdict row, then a multi-select of qualifying
   questions (each a toggle .option with a check glyph), and one Проверить button. */
.qualify-persona { margin-bottom: var(--s5); }
.qualify-verdict { margin-bottom: var(--s5); }
.qualify-asks-prompt { margin-top: var(--s2); }
.qualify-asks { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s4); }
.qualify-ask { gap: var(--s3); }
.qualify-check {
  flex: none; width: 22px; height: 22px; border-radius: 6px;
  border: 1.5px solid var(--line); background: var(--surface-2);
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
}
.qualify-ask.is-selected .qualify-check { background: var(--accent); border-color: var(--accent); }
.qualify-ask-text { flex: 1; }

/* ---- Recording tasks ---- */
/* Recording task uses the .card primitive; only the group gap is role-specific. */
.task-item { margin-bottom: var(--s4); }
.task-item .task-no {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}
.task-item .task-desc {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin-bottom: 12px;
}
.task-item .task-desc strong { color: var(--ink); }
.sample {
  background: var(--surface-2);
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
  font-style: italic;
  margin-bottom: 12px;
}
.sample .sample-label {
  display: block;
  font-style: normal;
  font-weight: 600;
  color: var(--ink-faint);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.rec-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 18px;
  font-size: 14px;
  font-weight: 600;
  border: 1.5px solid var(--accent);
  background: var(--surface);
  color: var(--accent);
  border-radius: 999px;
  cursor: pointer;
  transition: var(--tr-interactive);
}
.rec-btn:hover:not(:disabled):not(.recording):not(.done) { background: var(--accent-soft); }
.rec-btn:active:not(:disabled) { transform: translateY(1px); }
.rec-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
}
.rec-btn.recording {
  border-color: var(--bad);
  color: var(--bad);
  background: var(--bad-soft);
}
.rec-btn.recording .rec-dot { background: var(--bad); animation: pulse 1s infinite; }
.rec-btn.done {
  border-color: var(--good);
  color: var(--good);
  background: var(--good-soft);
}
.rec-btn.done .rec-dot { background: var(--good); animation: none; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }

/* ---- Short free-text answer (shortText) — labelled field + submit ---- */
.shorttext { padding: var(--s6); }
.shorttext-q {
  font-size: var(--t-lg);
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink);
  margin: 0 0 var(--s3);
}
.shorttext-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  font: inherit;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 10px;
  resize: vertical;
  transition: var(--tr-interactive);
}
.shorttext-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.shorttext-input:disabled { opacity: 0.7; cursor: not-allowed; }
.shorttext-submit { margin-top: var(--s3); }

/* ---- Live call dialogue (callDialog) ---- */
.call-thread {
  display: flex;
  flex-direction: column;
}
.call-bubble {
  max-width: 88%;
  margin: 0 auto 14px 0;          /* incoming → left-aligned */
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 4px 14px 14px 14px;
  padding: 14px 16px;
}
.call-who {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 6px;
}
.call-line {
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink);
  font-weight: 500;
}
.call-note {
  margin: 0 0 14px;
  padding: 10px 14px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-soft);
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0;
}
.call-rec {
  margin: 0 0 18px;
}
.call-outcome {
  margin-top: 8px;
  padding: 14px 16px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--good-soft);
  border-radius: 10px;
}
.call-outcome.hidden { display: none; }
.call-outcome-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--good);
  margin-bottom: 6px;
}

/* ---- Dial-tone screen (callRinging) ---- */
.ring-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 32px 20px;
  margin: 8px 0 20px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 14px;
  text-align: center;
}
.ring-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent);
  animation: ring-pulse 1.1s infinite;
}
@keyframes ring-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); opacity: 1; }
  70%  { box-shadow: 0 0 0 16px transparent; opacity: 0.6; }
  100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
}
.ring-status {
  font-size: 15px;
  color: var(--ink-soft);
}
.ring-timer {
  font-size: 34px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  letter-spacing: 0.02em;
}
.ring-box.ended .ring-dot { animation: none; background: var(--ink-faint); box-shadow: none; }
.ring-box.ended .ring-timer { color: var(--ink-faint); }
/* Hang-up = .btn .btn-block; only the destructive red is role-specific. */
.hangup-btn { color: var(--on-accent); background: var(--bad); border-color: var(--bad); }
.hangup-btn:hover:not(:disabled) { opacity: 0.9; }

/* ---- "Повторить теорию" shortcut on practice screens ---- */
.review-theory-btn {
  display: inline-flex;
  align-items: center;
  margin-top: 22px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: var(--tr-interactive);
}
.review-theory-btn:hover { border-color: var(--accent); color: var(--accent); }
.review-theory-btn:active { transform: translateY(1px); }

/* ---- Final screen ---- */
.final {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.final h1 { font-size: 26px; line-height: 1.2; font-weight: 690; letter-spacing: -0.02em; margin-bottom: 12px; }
.final-btns {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}
/* Final actions use the .btn primitive (primary/secondary); only layout is local. */
.final-btns button { flex: 1; }

/* ---- Nav bar ---- */
.navbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 16px 24px;
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}
/* (legacy .nav-btn/.nav-primary removed — the navbar uses the .btn primitive) */

/* Stake note (§1): a one-line consequence sits ABOVE the day-finish primary so the
   candidate reads what the click costs BEFORE pressing it. Only rendered for
   stakeful steps (counting knowledge check); harmless page turns keep it hidden. */
.navbar-stake {
  order: -1;
  flex-basis: 100%;
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-2);
}
.navbar-stake[hidden] { display: none; }
.navbar-stake svg { flex-shrink: 0; margin-top: 1px; color: var(--warn); }

/* ============================================================
   APP-SHELL (service layer) + BASE COMPONENTS
   Course view = clean top bar (chrome: day/lesson + progress on the
   left, game stats on the right) + a single centered content column +
   footer nav. No sidebar, no comments column — every tester tool lives
   in the floating dev panel (see the DEV PANEL section below).
   Chrome (top bar) is muted and lighter than the white content column,
   so the content reads first (squint test).
   ============================================================ */

body {
  display: block;
  align-items: stretch;
  justify-content: flex-start;
  padding: 0;
  min-height: 100vh;
  overflow: hidden;
}

/* ----- Base components: defined once, reused across the shell ----- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: var(--s3) var(--s6);
  font-family: inherit; font-size: var(--t-base); font-weight: 600; line-height: 1.2;
  color: var(--ink-soft); background: var(--frame-bg);
  border: 1.5px solid var(--line); border-radius: 10px; cursor: pointer;
  transition: var(--tr-interactive);
}
.btn:hover:not(:disabled) { border-color: var(--ink-faint); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
/* Primary — the ONE accent per screen, given tactile depth (§7): a hairline shadow
   plus a faint accent-tinted glow at rest → stronger glow + lift on hover → the press
   collapses the glow and drops it 1px, so the button reads as physically pushable. */
.btn-primary {
  color: var(--on-accent); background: var(--accent); border-color: var(--accent);
  box-shadow: var(--e-1), 0 2px 8px var(--accent-glow);
}
.btn-primary:hover:not(:disabled) {
  background: var(--accent-strong); border-color: var(--accent-strong);
  box-shadow: var(--e-2), 0 4px 14px var(--accent-glow-strong);
}
.btn-primary:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: var(--e-1);
}
/* Secondary/ghost — deferent: --surface fill + --line border, a NEUTRAL hover (no
   second accent) that fills to --surface-2 and darkens the border, then presses. */
.btn-secondary { color: var(--ink-soft); background: var(--surface); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); border-color: var(--ink-3); color: var(--ink); }
.btn-sm { padding: var(--s2) var(--s4); font-size: var(--t-sm); }
.btn-block { width: 100%; }

/* Option — the selectable answer/choice primitive (a choice, NOT a CTA).
   Full-width, left-aligned; states: is-selected / is-correct / is-wrong / is-dim. */
.option {
  display: flex; align-items: center; width: 100%; text-align: left;
  min-height: 52px;
  padding: var(--s3) var(--s4);
  font: inherit; font-size: var(--t-base); font-weight: 500; line-height: 1.4;
  color: var(--ink); background: var(--surface);
  border: 1.5px solid var(--line); border-radius: 10px; cursor: pointer;
  transition: var(--tr-interactive);
}
/* Pre-answer hover: an accent-soft tint + accent-ish border + a tiny lift, so an
   unanswered option feels pressable; the press settles it back down. */
.option:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); transform: translateY(-1px); }
.option:active:not(:disabled) { transform: translateY(1px); }
.option:disabled { cursor: not-allowed; }
.option.is-selected { border-color: var(--accent); background: var(--accent-soft); }
.option.is-correct { border-color: var(--good); background: var(--good-soft); }
.option.is-wrong { border-color: var(--bad); background: var(--bad-soft); }
.option.is-dim { opacity: 0.55; }

/* ---- Live answer feedback (§8) ----
   On answer the chosen option animates its verdict in instead of an instant repaint:
   a brief affirming pop for correct, a restrained shake for wrong. The class is added
   by the answer handler in app.js (addAnswerAnim) alongside is-correct/is-wrong, so the
   answer LOGIC is untouched. The colour itself settles via --tr-interactive (background/
   border transition). Collapsed to no motion under prefers-reduced-motion (below). */
.option.answer-pop { animation: answer-pop var(--motion-med) var(--ease); }
.option.answer-shake { animation: answer-shake 240ms var(--ease); }
@keyframes answer-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.025); }
  100% { transform: scale(1); }
}
@keyframes answer-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}
/* The verdict callout fades/slides in when it appears (added by the same handler). */
.feedback.is-revealed { animation: feedback-in var(--motion-fast) var(--ease); }
@keyframes feedback-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

/* ---- Field: the ONE reusable input primitive (design-language §6) ----
   Consistent 44px control height, comfortable inner padding, --r-sm radius, a
   recessed --surface-2 fill with a --line border that DARKENS on hover, and a
   crafted focus state (accent border + soft accent ring, no browser outline).
   type=text / type=tel / type=date all render identically; the date control is
   normalized so it matches the text inputs and its glyph follows the theme. */
.field {
  width: 100%; font: inherit; font-size: var(--t-base); line-height: 1.4; color: var(--ink);
  min-height: 44px;
  padding: 10px var(--s3);
  background: var(--surface-2);
  border: 1.5px solid var(--line); border-radius: var(--r-sm); outline: none;
  transition: border-color var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease),
              background var(--motion-fast) var(--ease);
}
.field::placeholder { color: var(--ink-3); }
/* Hover: the border darkens so the control feels tactile (only when usable). */
.field:hover:not(:disabled):not(:focus) { border-color: var(--ink-3); }
/* Focus: accent border + a soft accent-soft ring; the browser outline is
   replaced by this crafted ring (works for both mouse and keyboard focus). */
.field:focus,
.field:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  outline: none;
}
.field:disabled { opacity: .5; cursor: not-allowed; background: var(--surface-2); }

/* Normalize the native date control so it sits at the same height/padding and
   left-aligns like a text input; color-scheme (set per theme) themes its glyph. */
input[type="date"].field { -webkit-appearance: none; appearance: none; }
input[type="date"].field::-webkit-date-and-time-value { text-align: left; margin: 0; }
input[type="date"].field::-webkit-calendar-picker-indicator { opacity: .55; cursor: pointer; }
input[type="date"].field:hover::-webkit-calendar-picker-indicator { opacity: .85; }

/* Optional helper / error line under a field (§6): muted helper, --bad for errors. */
.field-help { font-size: var(--t-sm); line-height: 1.4; color: var(--ink-3); margin: 0; }
.field-help.is-error { color: var(--bad); }

.list-row {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: var(--s3); text-align: left;
  font: inherit; font-size: var(--t-base); line-height: 1.35;
  color: var(--ink-soft); background: transparent;
  border: none; border-radius: 8px; cursor: pointer;
  transition: var(--tr-interactive);
}
.list-row:hover { background: var(--row-hover); color: var(--ink); }
.list-row:active { transform: translateY(1px); }
.list-row:disabled { opacity: .45; cursor: not-allowed; }
.list-row:disabled:hover { background: transparent; color: var(--ink-soft); }
.list-row .list-row-accessory { margin-left: auto; }

.card {
  background: var(--frame-bg); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s6);
}
/* card-raised — only for true overlays/objects (modals, floating panels): shadow, no border. */
.card-raised {
  background: var(--frame-bg); border: none;
  border-radius: var(--radius); box-shadow: var(--shadow);
}

/* Badge — the circular verdict badge (pass check / fail cross). Color via badge-good/badge-bad. */
.badge {
  width: 56px; height: 56px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--t-2xl); font-weight: 700; margin: 0 auto var(--s4);
}
.badge-good { background: var(--good-soft); color: var(--good); }
.badge-bad { background: var(--bad-soft); color: var(--bad); }
/* Verdict glyph is an inline-SVG check/cross (§9), sized to the badge, currentColor. */
.badge svg { width: 26px; height: 26px; display: block; }

/* Overlay-dismiss — the quiet skip/close control in the corner of a full-screen overlay. */
.overlay-dismiss {
  position: absolute; top: var(--s4); right: var(--s6); z-index: 2;
  padding: var(--s2) var(--s4); font-family: inherit; font-size: var(--t-sm); font-weight: 600;
  color: var(--ink-faint); background: var(--frame-bg);
  border: 1.5px solid var(--line); border-radius: 999px;
  cursor: pointer; opacity: 0.7;
  transition: border-color .15s, color .15s, opacity .15s;
}
.overlay-dismiss:hover { opacity: 1; border-color: var(--accent); color: var(--accent); }
.overlay-dismiss:active { transform: translateY(1px); }
/* Keyboard focus keeps the global visible ring (§7) — no outline:none here. */
.overlay-dismiss:focus-visible { opacity: 1; border-color: var(--accent); color: var(--accent); }

.section-head {
  font-size: var(--t-sm); font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* Leading-icon anchor (§9) for text-dense screens (unlock sections, day-intro goal/
   teaser headings, result delta rows). Deferent by design: forced to --ink-3 so it
   never competes with the ONE accent, sized to the text, currentColor SVG. One per
   line/section, consistent baseline. */
.icon-lead {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-3);
}
.icon-lead svg { display: block; }

/* ----------------------- shell layout ----------------------- */
/* Course view = header (full width) + single centered content column + footer nav.
   A simple flex column: no sidebar/comments columns. */
.app {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100vh;
  /* The ONE header is fixed (out of flow); reserve its height so shell content
     (frame → stage/navbar) starts below it, never under it. */
  padding-top: var(--topbar-h);
}

/* ----------------------- top bar (chrome: context + progress + HUD + actions) -----------------------
   The SINGLE persistent header: fixed to the viewport top, full width, present on
   EVERY page and above every full-screen overlay (z 150; below the dev FAB at 300).
   A real flex bar: LEFT zone (context + progress) grows, RIGHT zone (HUD + actions)
   hugs; space-between guarantees the zones can never overlap. Its content adapts by
   context (setHeaderMode in app.js); a thin border is the only boundary. */
.topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 150;
  height: var(--topbar-h);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s6);
  padding: var(--s3) var(--s4);
  background: var(--chrome-bg);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--e-1);   /* chrome floats a hair above the content sheet (figure-ground) */
  flex-shrink: 0;
}
.topbar.hidden { display: none; }

/* LEFT zone wrapper: the BRAND lockup + (nav | phase label). Grows to fill the row so
   the RIGHT cluster stays pinned; min-width:0 lets the nav truncate/scroll inside it. */
.topbar-left { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: var(--s4); }

/* ---- BRAND lockup (chrome): Hyperion mark + wordmark, a quiet home button ----
   Deferent: muted ink, transparent chrome; hover/focus give a light affordance only.
   It is the platform identity Hyperion (never the client company). Never the accent. */
.brand {
  flex: none; display: inline-flex; align-items: center; gap: var(--s2);
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-sm);
  margin: 0; padding: 4px 8px 4px 6px; cursor: pointer;
  color: var(--ink); text-decoration: none;
  transition: var(--tr-interactive);
}
.brand:hover { background: var(--surface-2); border-color: var(--line); }
.brand:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.brand-mark { flex: none; display: inline-flex; color: var(--ink-soft); }
.brand:hover .brand-mark { color: var(--accent); }
.brand-word {
  font-size: var(--t-base); font-weight: 600; letter-spacing: 0.01em; color: var(--ink);
  white-space: nowrap;
}

/* LEFT zone (service): the persistent section NAVIGATION — gated destination tabs.
   Deferent chrome: quiet tabs, a single accent for the active one. Never wraps; on
   narrow widths it scrolls horizontally inside its own track so it can't push the HUD. */
.topnav { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: var(--s1);
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.topnav::-webkit-scrollbar { display: none; }
.topnav[hidden] { display: none; }
.topnav-tab {
  flex: none; white-space: nowrap;
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-sm);
  margin: 0; padding: 6px 12px; cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 600; line-height: 1.1;
  color: var(--ink-faint);
  transition: var(--tr-interactive);
}
.topnav-tab:hover { background: var(--surface-2); border-color: var(--line); color: var(--ink-soft); }
.topnav-tab:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* Active section: the one accent in the nav — accent-soft fill + accent ink. */
.topnav-tab.is-active { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
.topnav-tab.is-active:hover { background: var(--accent-soft); color: var(--accent); }

/* LEFT zone (onboarding): the phase label replaces the nav (reuses .topbar-row +
   .day-label/.lesson-label styling from the moved context strip). */
.topbar-phase { flex: 1 1 auto; min-width: 0; }
.topbar-phase[hidden] { display: none; }

/* Unified progress: «Экран X из Y» beside a thin bar — one unit, not two loose elements. */
.progress-unit { display: flex; align-items: center; gap: var(--s3); }

/* RIGHT zone: game-stats HUD + quiet actions. Larger gap isolates it from the context. */
.topbar-right { flex: none; display: flex; align-items: center; gap: var(--s4); min-width: 0; }
.topbar .status-strip { flex: none; }
.topbar .status-strip[hidden] { display: none; }

/* ---- TRAINING context strip: orientation anchor + progress, at the top of the frame ----
   Moved out of the fixed header so the header stays a single constant-height nav row.
   Chrome, like the header: a thin bottom border, muted labels, the progress-fill the
   single accent. A horizontal row: day/lesson anchor on the left, progress on the right.
   Shown ONLY in the training/reading view (setHeaderMode("service")); hidden elsewhere. */
.training-context {
  flex: none;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s6);
  padding: var(--s3) var(--s8);
  border-bottom: 1px solid var(--line);
  background: var(--frame-bg);
}
.training-context[hidden] { display: none; }
.training-context .topbar-row { flex: 0 1 auto; min-width: 0; }
.training-context .progress-unit { flex: none; }
.training-context .progress-unit[hidden] { display: none; }
.training-context .counter { margin-top: 0; white-space: nowrap; }
.training-context .progress-track { flex: none; width: 200px; }
/* Long lesson label truncates rather than pushing the progress unit off the row. */
.training-context .lesson-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* ----------------------- main content (primary focus) ----------------------- */
.frame {
  flex: 1 1 auto;
  width: auto; max-width: none; height: auto;
  border-radius: 0; box-shadow: none; border-right: none;
  background: var(--frame-bg);
  display: flex; flex-direction: column;
  min-width: 0; min-height: 0; overflow: hidden;
}
/* readable, left-aligned reading column — the primary focus */
.stage { padding: var(--s12) var(--s8) var(--s16); }
.stage > div { max-width: var(--measure); margin: 0 auto; width: 100%; }
/* Center a short single-child screen vertically; a call screen (content + review
   button = two children) or any overflowing lesson keeps its top anchor. */
.stage > div:only-child { margin-block: auto; }
.cover, .final { max-width: var(--measure); margin: 0 auto; }
.navbar { padding: var(--s4) var(--s8); gap: var(--s3); }
.navbar .btn-primary { margin-left: auto; }

/* ----------------------- figure-ground: content reads as an elevated sheet -----------------------
   On desktop the course reading surface lifts off the canvas: the fixed chrome bar
   stays full-width, but the white --surface frame gets a small --bg gutter, a
   concentric --r-lg radius and a soft --e-1, so focus lands on the content sheet
   (§2 контент>хром). Whitespace still does the grouping — this is a subtle lift,
   not a hard box. Below the narrow breakpoint the page just scrolls, so we keep it
   full-bleed there (no gutter) to preserve the reading width. */
@media (min-width: 901px) {
  .app { padding: calc(var(--topbar-h) + var(--s3)) var(--s4) var(--s4); }
  .frame {
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--e-1);
  }
}

/* ============================================================
   PAGE TEMPLATE — the reusable lesson-page shape, reused by flows.
   One component (§9): a flow screen is built from the SAME anatomy as a
   lesson page — a light context strip (.page-head, mirrors .topbar) + a
   left-aligned reading column (.page-body, the SAME rules as .stage's inner
   column) + a footer action bar (.page-foot, mirrors .navbar). Drop a .page
   into any full-surface container and it renders identically to the course
   view. Progress in the head is optional per screen.
   ============================================================ */
.page {
  display: flex; flex-direction: column;
  flex: 1 1 auto; height: 100%; min-height: 0;
  background: var(--frame-bg);
  overflow: hidden;
}
/* Head = chrome, like .topbar: muted context on the left, one unified
   progress unit on the right, thin bottom border, the progress fill the only
   accent so the bar recedes (squint test). */
.page-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s6);
  min-height: 56px;
  padding: var(--s3) var(--s4);
  background: var(--chrome-bg);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--e-1);   /* same chrome-over-sheet lift as the top bar */
  flex-shrink: 0;
}
.page-head-context {
  font-size: 13px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-soft);
}
/* progress unit reuses .progress-unit / .counter / .progress-track (topbar). */
.page-head .progress-unit { flex: none; }
.page-head .counter { margin-top: 0; white-space: nowrap; }
.page-head .progress-track { width: 160px; }

/* Body = the reading column: identical to .stage's inner column (padding from
   the scale, 720px column centered in the surface, text left-aligned). */
.page-body {
  flex: 1 1 auto; overflow-y: auto;
  padding: var(--s12) var(--s8) var(--s16);
  /* Column + auto-margin child = the kill-the-void rule (§3/§7): a SHORT flow
     screen (registration landing, exam gate, screening/shop intro) centers in the
     space between the header and the foot instead of top-anchoring above a big
     void; a TALL screen overflows, the auto margin collapses to 0, and it
     top-anchors and scrolls normally. Self-distinguishing by content height. */
  display: flex; flex-direction: column;
}
.page-body > div { max-width: 720px; margin: auto; width: 100%; }
/* CARD-GRID view-type (marketplace, shop store): the same template, but the
   content column is allowed past the reading measure so the grid runs 2–3 wide
   (§2: grids may be wider than --measure). Header block inside stays readable. */
.page-body > div.wide { max-width: 960px; }
/* typography mirrors .stage h1/h2/p/ul so prose reads the same as a lesson (§2). */
.page-body h1 { font-size: 26px; line-height: 1.2; font-weight: 690; margin: 0 0 var(--s2); letter-spacing: -0.02em; }
.page-body h2 { font-size: 20px; line-height: 1.3; font-weight: 650; margin: 0 0 var(--s2); }
.page-body * + h2 { margin-top: var(--s8); }
.page-body p { font-size: 15px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 var(--s4); }
.page-body p strong { color: var(--ink); font-weight: 600; }
.page-body ul { margin: 0 0 var(--s4); padding-left: var(--s6); }
.page-body li { font-size: 15px; line-height: 1.55; color: var(--ink-soft); margin-bottom: var(--s2); }
.page-body li strong { color: var(--ink); font-weight: 600; }

/* Foot = footer action bar, like .navbar: secondary «Назад» on the left, the
   primary action pushed to the right. */
.page-foot {
  display: flex; gap: var(--s3);
  padding: var(--s4) var(--s8);
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}
.page-foot .btn-primary { margin-left: auto; }
/* When a step needs two right-side actions (e.g. face capture: Retake + Done),
   group them so the pair right-anchors regardless of which one is primary. */
.foot-group { margin-left: auto; display: inline-flex; gap: var(--s3); }
.page-foot .foot-group .btn { margin-left: 0; }

/* ----------------------- comments (on-demand right drawer, closed by default) -----------------------
   Not a permanent column: an off-canvas drawer that slides in over the content when
   the «Комментарий» toggle is pressed. Reuses the sidebar-drawer pattern. All comment
   functionality (ref, textarea, save/export, note) is unchanged — only placement. */
.comments {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  z-index: 65;   /* above .top-actions (60) so the drawer header/close aren't covered */
  width: min(var(--comments-w), 88vw);
  height: 100%;
  background: var(--chrome-bg);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.2s ease;
}
body.comments-open .comments { transform: none; }

/* backdrop behind the comments drawer */
.comments-backdrop {
  position: fixed; inset: 0; z-index: 62;   /* above .top-actions (60), below the drawer (65) */
  background: var(--scrim);
  display: none;
}
.comments-backdrop[hidden] { display: none; }
body.comments-open .comments-backdrop { display: block; }

/* close control in the comments drawer head */
.comments-close {
  width: 34px; height: 34px; flex: none;
  font-size: 22px; line-height: 1;
  color: var(--ink-soft); background: var(--surface);
  border: 1.5px solid var(--line); border-radius: 8px; cursor: pointer;
  transition: var(--tr-interactive);
}
.comments-close:hover { border-color: var(--ink-faint); background: var(--row-hover); }
.comments-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.comments-title { font-size: 14px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--ink-soft); }
.comments-head-actions { display: inline-flex; align-items: center; gap: 10px; }
.comments-count {
  min-width: 22px; height: 22px; padding: 0 7px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: var(--on-accent); background: var(--accent);
  border-radius: 999px;
}
.comments-count.is-zero { background: var(--ink-faint); }
.comments-export {
  font-size: 12px; font-weight: 600; color: var(--ink-soft);
  background: var(--surface); border: 1.5px solid var(--line); border-radius: 8px;
  padding: 5px 10px; cursor: pointer;
  transition: var(--tr-interactive);
}
.comments-export:hover { border-color: var(--accent); color: var(--accent); }
.comments-export:active { transform: translateY(1px); }

.comments-current {
  padding: 16px 18px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.comments-ref {
  font-size: 12px; line-height: 1.45; color: var(--ink-faint);
  margin-bottom: 8px; font-weight: 600;
}
.comments-ref strong { color: var(--ink); }
/* Comment box uses the .field primitive; only the textarea sizing is role-specific. */
.comments-input { resize: vertical; min-height: 76px; font-size: var(--t-sm); }
.comments-current-actions { display: flex; gap: var(--s2); margin-top: var(--s2); }
/* Save = .btn .btn-secondary .btn-sm (a quiet action, not a second solid primary). */
.comments-save { flex: 1; }
.comments-delete {
  font-size: 13px; font-weight: 600; color: var(--bad);
  background: var(--bad-soft); border: none; border-radius: 8px;
  padding: 9px 12px; cursor: pointer;
}
.comments-delete[hidden] { display: none; }
.comments-saved-hint {
  margin-top: 8px; font-size: 12px; font-weight: 700; color: var(--good);
  display: inline-flex; align-items: center; gap: 5px;
}
.comments-saved-hint svg, .comments-saved-hint .inline-icon { display: block; flex: none; }

.comments-list-head {
  padding: 14px 18px 6px; font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint);
  flex-shrink: 0;
}
.comments-list { flex: 1; overflow-y: auto; padding: 0 18px 18px; }
.comments-empty { font-size: 13px; color: var(--ink-faint); padding: 8px 0; }
.comment-card {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; cursor: pointer;
  transition: var(--tr-interactive);
}
.comment-card:hover { border-color: var(--accent); box-shadow: 0 2px 10px color-mix(in srgb, var(--accent) 10%, transparent); }
.comment-card:active { transform: translateY(1px); }
.comment-card.is-current { border-left-color: var(--good); background: var(--good-soft); }
.comment-card-ref { font-size: 11px; font-weight: 700; color: var(--ink-soft); margin-bottom: 4px; }
.comment-card-text { font-size: 13px; line-height: 1.45; color: var(--ink); white-space: pre-wrap; }

/* ---------------- lesson-test slot screen ---------------- */
.lesson-test { text-align: left; }
.lesson-test .lt-badge {
  display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--accent); background: var(--accent-soft);
  padding: 5px 12px; border-radius: 999px; margin-bottom: 16px;
}
/* De-boxed empty state: a hairline section break + left-aligned teaching text,
   no dashed panel (§7 empty state). */
.lesson-test-box {
  margin-top: var(--s6); padding-top: var(--s6);
  border-top: 1px solid var(--line); text-align: left;
}
.lesson-test-box p { color: var(--ink-soft); }
/* Take-test = .btn .btn-primary; keep the local top gap + the "preparing" disabled look. */
.lt-start { margin-top: var(--s3); }
.lt-start:disabled { background: var(--ink-faint); border-color: var(--ink-faint); opacity: 1; cursor: default; }

/* backdrop for the narrow contents drawer; invisible on desktop */
.toc-backdrop {
  position: fixed; inset: 0; z-index: 45;
  background: var(--scrim);
  display: none;
}
.toc-backdrop[hidden] { display: none; }

/* ---------------- responsive fallback (narrow, < 900px) ----------------
   The shell is a flex column at every width; below the breakpoint we simply let
   the page scroll vertically and give the content column a sensible min-height.
   The dev panel is fixed and already width-capped to the viewport. */
@media (max-width: 900px) {
  /* Let the page scroll vertically, but NEVER horizontally. */
  body { overflow-x: hidden; overflow-y: auto; }
  .app { height: auto; min-height: 100vh; }
  .frame { min-height: 60vh; }
}

/* write-only comments: explanatory note under the input — plain text, no box */
.comments-note {
  margin: 16px 18px;
  font-size: 12px; line-height: 1.5; color: var(--ink-faint);
}

/* ---------------- top-bar actions: language toggle + logout ----------------
   Quiet secondary group at the far right of the header, split from the HUD by a
   thin divider. A normal flex child (no absolute positioning → no overlap). */
/* ---- Account menu (chrome): avatar + name trigger, opening a deferent dropdown ----
   Sits at the far right, after the HUD stat cluster, with a divider before it (the HUD
   reads as its own group). The dropdown is a small popover: identity header + Язык /
   Тема / Выйти. Token-driven; light + dark from the same variables. */
.account {
  position: relative; flex: none;
  padding-left: var(--s4); border-left: 1px solid var(--line);
}
.account[hidden] { display: none; }
.account-trigger {
  display: inline-flex; align-items: center; gap: var(--s2);
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-full);
  margin: 0; padding: 3px 8px 3px 3px; cursor: pointer;
  font: inherit; color: var(--ink-soft);
  transition: var(--tr-interactive);
}
.account-trigger:hover { background: var(--surface-2); border-color: var(--line); }
.account-trigger:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.account-trigger[aria-expanded="true"] { background: var(--surface-2); border-color: var(--line); }
/* Avatar: a small round token carrying the candidate's initials. */
.avatar {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--r-full);
  background: var(--accent-soft); color: var(--accent);
  font-size: 12px; font-weight: 700; letter-spacing: 0.01em; line-height: 1;
  text-transform: uppercase;
}
.avatar-lg { width: 38px; height: 38px; font-size: 15px; }
.account-name {
  max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--t-sm); font-weight: 600; color: var(--ink);
}
.account-caret { flex: none; color: var(--ink-faint); }

/* Dropdown popover — elevated sheet under the trigger, right-aligned. */
.account-menu {
  position: absolute; top: calc(100% + var(--s2)); right: 0; z-index: 200;
  min-width: 300px; max-width: 340px;
  background: var(--frame-bg); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--e-3);
  padding: var(--s3);
}
.account-id { display: flex; align-items: center; gap: var(--s3); padding: var(--s1) var(--s2) var(--s2); }
.account-id-text { min-width: 0; }
.account-id-name {
  font-size: var(--t-base); font-weight: 700; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.account-id-sub {
  margin-top: 2px; font-size: 12px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.account-sep { height: 1px; background: var(--line); margin: var(--s2) 0; }
.account-group { padding: 0 var(--s2); }
.account-group-label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 var(--s2);
}
/* Segmented option row (Язык, Тема): equal-width option buttons; one accent-soft active. */
.account-seg { display: flex; gap: var(--s1); }
.account-seg-btn {
  flex: 1 1 0; min-width: 0;
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-sm);
  margin: 0; padding: 6px 6px; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 600; line-height: 1.1; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: var(--tr-interactive);
}
.account-seg-btn:hover { background: var(--surface-2); color: var(--ink); }
.account-seg-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.account-seg-btn.is-active { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
.account-seg-btn.is-active:hover { background: var(--accent-soft); color: var(--accent); }
/* Full-width menu item (Выйти). */
.account-item {
  display: block; width: 100%; text-align: left;
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-sm);
  margin: 0; padding: 8px var(--s2); cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 600; color: var(--ink-soft);
  transition: var(--tr-interactive);
}
.account-item:hover { background: var(--surface-2); color: var(--ink); }
.account-item:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.account-logout { color: var(--bad); }
.account-logout:hover { background: var(--bad-soft); color: var(--bad); }

.lang-toggle {
  min-height: 30px;
  min-width: 36px;
  padding: var(--s1) var(--s3);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: var(--tr-interactive);
}
.lang-toggle:hover { border-color: var(--accent); color: var(--accent); }
.lang-toggle:active { transform: translateY(1px); }
.lang-toggle[hidden] { display: none; }

/* ================= M1 вход + M2 статус/гейтинг/результат ================= */

/* строка счётчика + статус (жизни, оплата) */
.counter-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* ---- HUD: the game-stats cluster (attempts · pay · streak · points) ----
   One tight cluster with a small internal gap; the chips recede as chrome (muted),
   so the progress-fill stays the single accent in the header. */
.hud, .status-strip { display: inline-flex; align-items: baseline; gap: var(--s3); }
.status-strip[hidden] { display: none; }

/* ---- One .stat chip anatomy, reused for all four stats (label over value) ----
   Same size/shape; the class (lives/pay/streak/points) is both the coach-mark anchor
   and the MECHANIC_INFO key. Each chip is a BUTTON: activating it re-shows the
   mechanic's explanation in a popover. Deferent — reset to look like chrome, gain a
   quiet hover/focus affordance only. */
.stat {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: 1px; line-height: 1.1; white-space: nowrap;
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 1px solid transparent;
  border-radius: var(--r-sm); margin: 0; padding: 3px 6px; cursor: pointer;
  font: inherit; text-align: left;
  transition: var(--tr-interactive);
}
.stat:hover { background: var(--surface-2); border-color: var(--line); }
.stat:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.stat[aria-expanded="true"] { background: var(--surface-2); border-color: var(--line); }
.stat-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.02em; color: var(--ink-faint);
}
.stat-value { font-size: var(--t-sm); font-weight: 700; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

/* ---- Purposeful, sparing semantic tints (still deferent chrome) ----
   The header progress-fill stays the one full accent; these are light value tints
   that let each stat read at a glance:
   · Оплата (pay)  → --good  : money reads as positive.
   · Серия (streak) → --accent : the ×multiplier reward stands out.
   · Попытки (lives) → neutral, but at the LAST attempt (lives == 1, .is-crit set in
     updateHeader) the value + chip go --bad so the risk is visible.
   · Баллы / Ранг → neutral (default ink-soft), tabular-nums. */
.stat.pay .stat-value { color: var(--good); }
.stat.streak .stat-value { color: var(--accent); }
.stat.lives.is-crit .stat-value { color: var(--bad); }
.stat.lives.is-crit,
.stat.lives.is-crit:hover,
.stat.lives.is-crit[aria-expanded="true"] {
  background: var(--bad-soft);
  border-color: color-mix(in srgb, var(--bad) 32%, transparent);
}

/* ---- Re-readable HUD chip popover (Layer 2), anchored under a stat chip ----
   Popover elevation (--e-2); a small caret tracks the chip centre. Meaning is never
   hidden: forgot what «Серия» is → tap the chip → read it again. */
.stat-popover {
  position: fixed; z-index: 113; max-width: 300px;
  background: var(--frame-bg); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--e-2);
  padding: 12px 14px;
}
.stat-popover-title { font-size: 13px; font-weight: 700; color: var(--ink); margin: 0 0 6px; }
.stat-popover-text { font-size: 13px; line-height: 1.5; color: var(--ink-soft); margin: 0; }
.stat-popover-arrow {
  position: absolute; top: -7px; width: 13px; height: 13px;
  background: var(--frame-bg);
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transform: rotate(45deg); transform-origin: center;
}

/* ---- Leaderboard (Ранг): a clean ranked list — leading rank · name · trailing points.
   One accent only: the current user's row (--accent-soft fill + accent text). Tabular
   numerals keep ranks and points aligned; light + dark from variables. ---- */
.leaderboard {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; background: var(--surface);
}
.lb-row {
  display: flex; align-items: center; gap: var(--s3);
  padding: 10px 14px;
  border-top: 1px solid var(--line);
}
.lb-row:first-child { border-top: none; }
.lb-rank {
  flex: 0 0 auto; min-width: 34px;
  font-size: var(--t-sm); font-weight: 700; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.lb-name {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--t-sm); font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-points {
  flex: 0 0 auto;
  font-size: var(--t-sm); font-weight: 700; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.lb-row.is-user { background: var(--accent-soft); }
.lb-row.is-user .lb-rank,
.lb-row.is-user .lb-name,
.lb-row.is-user .lb-points { color: var(--accent); }

/* The leaderboard is now a full-screen SECTION (.leaderboard-screen), not a reopen
   modal — the board (.leaderboard / .lb-row) renders inside a .page via buildPage. */

/* ---- Responsive collapse (< 760px): drop the stat labels, keep the values;
   tighten gaps and shrink the progress bar. Never overlap, never scroll sideways. */
@media (max-width: 760px) {
  /* Header collapses: drop stat labels, tighten gaps, shrink the bar — the zones
     stay space-between so they can never overlap, and the bar never wraps. */
  .topbar { gap: var(--s2); padding: var(--s2) var(--s3); }
  .hud, .status-strip { gap: var(--s3); }
  .stat-label { display: none; }
  .topbar-right { gap: var(--s3); }
  .topbar-left { gap: var(--s2); }
  /* Brand condenses to just the mark; the account trigger to just the avatar. */
  .brand { padding: 4px 6px; }
  .brand-word { display: none; }
  .account { padding-left: var(--s3); }
  .account-name { display: none; }
  .account-caret { display: none; }
  .account-trigger { padding: 3px; }
  /* Nav condenses: tighter tabs + gap; it scrolls inside its own track (set on .topnav)
     so it can never push the HUD off-screen or force a horizontal body scroll. */
  .topnav { gap: 2px; }
  .topnav-tab { padding: 5px 9px; font-size: 12px; }
  /* Training strip: tighter padding + shorter bar; day/lesson label truncates. */
  .training-context { padding: var(--s2) var(--s4); gap: var(--s3); }
  .training-context .progress-track { width: 120px; }
  /* Long lesson label must truncate, not push the progress unit off the row. */
  .lesson-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

  /* Comfortable page padding at narrow width (from the scale, not the desktop
     s8/s16). Applies to the reading column of every view (stage + page). */
  .stage { padding: var(--s6) var(--s4) var(--s12); }
  .page-body { padding: var(--s6) var(--s4) var(--s12); }
  .navbar, .page-foot { padding: var(--s4); }
  .page-head { padding: var(--s3) var(--s4); }

  /* Card grids reflow to a single column so nothing is cramped. */
  .company-grid, .shop-grid { grid-template-columns: 1fr; }

  /* Modals get breathing room from the viewport edge. */
  .modal-overlay, .pres-overlay { padding: var(--s4); }
}

/* заблокированные дни/пункты в оглавлении */
.toc-day.is-locked .toc-day-head { opacity: .5; }
.toc-item.is-locked { opacity: .45; cursor: not-allowed; }
.toc-item.is-locked:hover { background: transparent; color: var(--ink-soft); }
.toc-lock { margin-left: 6px; font-size: 11px; color: var(--ink-faint); }

/* оверлей входа — full-surface region below the persistent header that hosts a
   .page (same template as the exam): the inner #onbCard is just a flex column so
   the .page fills it. No bespoke centered card. */
.onboarding { position: fixed; top: var(--topbar-h); left: 0; right: 0; bottom: 0; z-index: 100; background: var(--frame-bg); display: flex; flex-direction: column; }
.onb-inner { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.onb-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin: 0 0 10px; }
.onb-title { font-size: 25px; font-weight: 700; color: var(--ink); margin: 0 0 12px; line-height: 1.25; }
.onb-text { font-size: 15px; color: var(--ink-soft); line-height: 1.6; margin: 0 0 var(--s6); }
.onb-actions { display: flex; gap: var(--s3); margin-top: var(--s1); }

/* STAKE note (§1) — one legible consequence line before a stakeful primary, on the
   reading column of the screening / exam page flows. Warn-tinted alert + plain text. */
.stake-note {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 0 0 var(--s6); padding: 10px 12px;
  background: var(--warn-soft); border-radius: var(--radius);
  font-size: 14px; line-height: 1.5; color: var(--ink);
}
.stake-note svg { flex-shrink: 0; margin-top: 2px; color: var(--warn); }
/* NEXT-STEP line (§4) — the one named «что дальше» on result screens. */
.next-step {
  display: flex; align-items: flex-start; gap: 8px;
  margin: var(--s5) 0 var(--s6);
  font-size: 15px; line-height: 1.5; font-weight: 600; color: var(--ink);
}
.next-step svg { flex-shrink: 0; margin-top: 2px; color: var(--accent); }
/* onboarding buttons/inputs now use the .btn / .field primitives */
.onb-code-note { font-size: 13px; color: var(--ink-soft); background: var(--accent-soft); border-radius: var(--radius); padding: 10px 12px; margin: 0 0 12px; }
.onb-code-note b { color: var(--accent); font-size: 17px; letter-spacing: 3px; }
.onb-driver { background: var(--surface-2); border-radius: var(--radius); padding: 14px 16px; margin: 0 0 16px; }
.onb-driver .who { font-size: 12px; font-weight: 700; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 4px; }
.onb-driver .line { font-size: 16px; color: var(--ink); }
.onb-error { font-size: 13px; color: var(--bad); margin: 0 0 10px; min-height: 16px; }
.onb-steps { font-size: 12px; color: var(--ink-faint); margin: 18px 0 0; }

/* ---- Регистрация: мастер (индикатор шагов, форма, камера) ---- */
/* (full-width register button now uses .btn-block) */

/* индикатор шагов — a clean caption-level indicator at the top of the column
   (small dots + caption labels), not a bespoke filled-pill row. */
.onb-steps-ind { display: flex; align-items: center; gap: var(--s1); margin: 0 0 var(--s6); }
.onb-step { display: inline-flex; align-items: center; gap: 6px; }
/* Three legible states in the new palette: upcoming = hollow ink-3 dot on the
   recessed fill; active = filled accent with a soft accent ring; done = filled
   good with a check. Labels follow: upcoming ink-3, active ink (bold), done ink-2. */
.onb-step-dot {
  width: 22px; height: 22px; flex: 0 0 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; border: 1.5px solid var(--line);
  background: var(--surface-2); color: var(--ink-3);
  transition: background var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease), box-shadow var(--motion-fast) var(--ease);
}
.onb-step-dot svg { display: block; }
.onb-step-label { font-size: var(--t-sm); font-weight: 600; color: var(--ink-3); white-space: nowrap; }
.onb-step-active .onb-step-dot { border-color: var(--accent); background: var(--accent); color: var(--on-accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.onb-step-active .onb-step-label { color: var(--ink); font-weight: 700; }
.onb-step-done .onb-step-dot { border-color: var(--good); background: var(--good); color: var(--on-accent); box-shadow: none; }
.onb-step-done .onb-step-label { color: var(--ink-2); }
.onb-step-conn { width: 16px; height: 2px; flex: 0 0 16px; background: var(--line); border-radius: 2px; margin: 0 4px; }
.onb-step-conn.is-done { background: var(--good); }

/* форма данных */
.onb-form { display: flex; flex-direction: column; gap: var(--s4); margin: 0 0 var(--s6); }
.onb-field { display: flex; flex-direction: column; gap: var(--s2); }
.onb-label { font-size: var(--t-sm); font-weight: 600; color: var(--ink-soft); }

/* камера */
.onb-cam {
  position: relative; width: 100%; aspect-ratio: 4 / 3; margin: 0 0 14px;
  border: 1.5px solid var(--line); border-radius: var(--radius); overflow: hidden;
  background: var(--well); display: flex; align-items: center; justify-content: center;
}
.onb-cam.is-fallback { background: var(--surface-2); border-style: dashed; border-color: var(--ink-faint); }
.onb-cam-media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.onb-cam-ph { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 20px; text-align: center; color: var(--ink-faint); }
.onb-cam-ph span { font-size: 13px; line-height: 1.5; max-width: 260px; }
.onb-cam-status {
  font-size: 14px; font-weight: 600; color: var(--ink-faint); margin: 0 0 12px; min-height: 18px;
  display: inline-flex; align-items: center; gap: 6px;
}
.onb-cam-status svg { display: block; flex: none; }
.onb-cam-status.is-ok { color: var(--good); }
.onb-cam-status.is-err { color: var(--bad); }

/* ---------- English-скрининг (полноэкранный оверлей, после записи, до Дня 1) ----------
   Хостит .page (тот же шаблон, что экзамен/магазин): оверлей — просто flex-колонка,
   в которую .page разворачивается на всю высоту (внутренний скролл — у .page-body). */
.eng-screen {
  position: fixed; top: var(--topbar-h); left: 0; right: 0; bottom: 0; z-index: 105;
  background: var(--frame-bg);
  display: flex; flex-direction: column;
}
.eng-screen[hidden] { display: none !important; }
.eng-inner { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }

/* Демо-кнопка «Пропустить» скрининг живёт в дев-панели (engSkip); отдельного
   контрола в оверлее нет. */
.eng-note {
  font-size: 13px; color: var(--ink-soft); line-height: 1.55; margin: 0 0 22px;
  padding: 10px 14px; background: var(--accent-soft);
  border-left: 3px solid var(--accent); border-radius: 8px;
}
/* Result column — mirrors .exam-result: prose left-anchored; only the badge, the
   one-line verdict title and the level pill are centered (short hero). */
.eng-result { text-align: left; }
.eng-result .badge { display: flex; }               /* block-level flex → margin:0 auto centers it */
.eng-result .onb-title { text-align: center; }
.eng-result .eng-level { display: block; width: -moz-fit-content; width: fit-content; margin-left: auto; margin-right: auto; }

/* ---- English screening: emulated AI phone call ---- */
/* Shared caller avatar (bot/phone glyph) for ringing + in-call header. */
.eng-call-avatar {
  flex: none;
  width: 48px; height: 48px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
  border: 1.5px solid var(--accent);
}
.eng-call-avatar-lg { width: 84px; height: 84px; }
.eng-call-avatar-lg svg { width: 52px; height: 52px; }

/* Ringing screen — caller-identity block (short hero) centered in the column. */
.eng-ring-box {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 30px 20px 24px; margin: 8px 0 0;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 16px;
}
.eng-call-avatar.is-ringing { animation: eng-ring-pulse 1.2s infinite; }
@keyframes eng-ring-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  70%  { box-shadow: 0 0 0 18px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.eng-ring-name { font-size: 20px; font-weight: 700; color: var(--ink); }
.eng-ring-status { font-size: 15px; color: var(--ink-soft); }
.eng-ring-waves { display: flex; gap: 6px; height: 20px; align-items: flex-end; }
.eng-ring-waves span {
  width: 4px; border-radius: 2px; background: var(--accent);
  animation: eng-ring-wave 1s infinite ease-in-out;
}
.eng-ring-waves span:nth-child(1) { animation-delay: 0s; }
.eng-ring-waves span:nth-child(2) { animation-delay: .18s; }
.eng-ring-waves span:nth-child(3) { animation-delay: .36s; }
@keyframes eng-ring-wave {
  0%,100% { height: 6px; opacity: .5; }
  50%     { height: 20px; opacity: 1; }
}

/* ---- Voice conversation: caption progress + speaking avatar + level meter + mic ---- */
/* Progress caption at the top of the column (same anatomy as a caption label). */
.eng-voice-progress {
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-faint);
  text-align: center; margin: 0 0 8px;
}
/* Clean centered component stack (avatar + state + meter + mic + repeat) — no
   bespoke bubble container; the state classes drive the avatar/meter feedback. */
.eng-voice-stage {
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  padding: 8px 0 4px;
}
/* Big caller avatar with pulsing rings */
.eng-voice-avatar {
  position: relative;
  width: 104px; height: 104px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
  border: 2px solid var(--accent); transition: background .2s, color .2s, border-color .2s;
}
.eng-voice-avatar svg { width: 60px; height: 60px; position: relative; z-index: 1; }
.eng-voice-rings { position: absolute; inset: 0; pointer-events: none; }
.eng-voice-rings span {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--accent); opacity: 0;
}
/* Speaking → expanding rings + soft glow on the avatar */
.eng-voice-stage.is-speaking .eng-voice-avatar {
  animation: eng-voice-glow 1.6s ease-in-out infinite;
}
.eng-voice-stage.is-speaking .eng-voice-rings span { animation: eng-voice-ring 1.8s ease-out infinite; }
.eng-voice-stage.is-speaking .eng-voice-rings span:nth-child(2) { animation-delay: .6s; }
.eng-voice-stage.is-speaking .eng-voice-rings span:nth-child(3) { animation-delay: 1.2s; }
@keyframes eng-voice-ring {
  0%   { opacity: .55; transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.8); }
}
@keyframes eng-voice-glow {
  0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 35%, transparent); }
  50%     { box-shadow: 0 0 0 12px transparent; }
}
/* Listening / recording → green "your turn" avatar */
.eng-voice-stage.is-listening .eng-voice-avatar,
.eng-voice-stage.is-recording .eng-voice-avatar {
  background: var(--good-soft); color: var(--good); border-color: var(--good);
}
.eng-voice-stage.is-recording .eng-voice-avatar { animation: eng-voice-glow-good 1s ease-in-out infinite; }
@keyframes eng-voice-glow-good {
  0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 40%, transparent); }
  50%     { box-shadow: 0 0 0 12px transparent; }
}
.eng-voice-state {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font-size: 14px; font-weight: 600; color: var(--ink-soft); line-height: 1.4;
  min-height: 20px; max-width: 340px;
}
.eng-voice-state svg { flex: none; }
/* Live input-level meter (bars) — renamed from .eng-level to avoid colliding with
   the pass-result level BADGE (.eng-level) further down. */
.eng-meter { display: flex; align-items: center; gap: var(--s1); height: 34px; }
.eng-meter span {
  width: 5px; height: 4px; border-radius: 3px; background: var(--ink-faint);
  transition: height .08s linear;
}
.eng-voice-stage.is-recording .eng-meter span { background: var(--good); }

/* Big mic control — the primary interaction of the call turn (inline-SVG icon). */
.eng-mic-btn {
  appearance: none; cursor: pointer; border: none; margin-top: 4px;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  width: 108px; height: 108px; border-radius: 50%;
  background: var(--good); color: var(--on-accent);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--good) 28%, transparent);
  transition: background .15s, transform .1s, box-shadow .15s;
}
.eng-mic-btn:hover:not(:disabled) { transform: translateY(-1px); }
.eng-mic-btn:disabled { background: var(--ink-faint); box-shadow: none; opacity: .6; cursor: default; }
.eng-mic-btn.is-rec { background: var(--bad); box-shadow: 0 6px 18px color-mix(in srgb, var(--bad) 30%, transparent); animation: eng-mic-pulse 1s infinite; }
@keyframes eng-mic-pulse {
  0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--bad) 45%, transparent); }
  50%     { box-shadow: 0 0 0 14px transparent; }
}
.eng-mic-icon { display: inline-flex; line-height: 0; }
.eng-mic-lbl { font-size: 14px; font-weight: 700; }
/* Small icon+label control «повторить вопрос» (audio replay). */
.eng-repeat-btn {
  appearance: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: var(--s2);
  border: 1.5px solid var(--line); background: var(--surface); color: var(--ink-soft);
  font-size: 13px; font-weight: 600; padding: 8px 14px; border-radius: 999px;
  transition: border-color .15s, color .15s;
}
.eng-repeat-btn svg { flex: none; }
.eng-repeat-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.eng-repeat-btn:disabled { opacity: .4; cursor: default; }

/* Analysing state (spinner) — short centered loading hero in the column. */
.eng-analysing { text-align: center; }
.eng-analysing .eng-note { max-width: 420px; margin-left: auto; margin-right: auto; text-align: left; }
.eng-spinner {
  width: 44px; height: 44px; margin: 4px auto 18px;
  border: 4px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%; animation: eng-spin .8s linear infinite;
}
@keyframes eng-spin { to { transform: rotate(360deg); } }

/* модалка результата дня — a TRUE modal: overlays fully, above the persistent
   header (z 150), below the dev FAB (z 300). */
.modal-overlay { position: fixed; inset: 0; z-index: 160; background: var(--scrim); display: flex; align-items: center; justify-content: center; padding: 24px; }
/* Left-anchored card; only the badge + the one-line verdict title are centered. */
.modal { width: 100%; max-width: 420px; padding: var(--s8); text-align: left; }  /* surface = .card-raised; verdict circle = .badge */
.modal .m-title { font-size: 22px; font-weight: 700; color: var(--ink); margin: 0 0 var(--s6); text-align: center; }
/* Pay is the ONE dominant value — carried by SIZE, not a filled box (de-boxed). */
.modal .m-pay {
  font-size: 26px; font-weight: 800; color: var(--good);
  font-variant-numeric: tabular-nums; line-height: 1.1; margin: 0 0 var(--s3);
}
.modal .m-text { font-size: 15px; color: var(--ink-soft); line-height: 1.55; margin: 0 0 var(--s2); }
/* Retention nudges (streak / exam progress) — plain quiet left-aligned lines, no box. */
.modal .m-note {
  font-size: 14px; line-height: 1.5; color: var(--ink-soft); margin: 0 0 var(--s2);
}
.modal .m-note:last-of-type { margin-bottom: var(--s6); }
/* «Что изменилось» — a compact factual list (label ↔ value), deferent to the verdict.
   Related rows sit close; the block is separated from the verdict by whitespace. */
.modal .m-delta { display: flex; flex-direction: column; gap: var(--s2); margin: 0 0 var(--s5); }
.modal .m-delta-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); font-size: 14px; line-height: 1.4; }
/* Left group = a leading icon anchor (§9) + the row label, kept together against the
   right-aligned value. */
.modal .m-delta-left { display: inline-flex; align-items: center; gap: var(--s2); min-width: 0; }
.modal .m-delta-label { color: var(--ink-soft); }
.modal .m-delta-val { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.modal .m-delta-val.is-good { color: var(--good); }
.modal .m-delta-val.is-bad { color: var(--bad); }
/* «Что дальше» — one named next step, set apart with a top hairline. */
.modal .m-next { display: flex; align-items: flex-start; gap: var(--s2); padding-top: var(--s4); margin: 0 0 var(--s6); border-top: 1px solid var(--line); font-size: 14px; line-height: 1.45; color: var(--ink); font-weight: 600; }
.modal .m-next-icon { display: inline-flex; flex-shrink: 0; margin-top: 1px; color: var(--accent); }
/* Footer action row: secondary left, primary pushed right. */
.modal .m-actions { display: flex; gap: var(--s3); align-items: center; }
.modal .m-actions .btn-primary { margin-left: auto; }

/* тост */
.flash { position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 120; background: var(--ink); color: var(--surface); font-size: 14px; font-weight: 500; padding: 11px 18px; border-radius: 999px; box-shadow: var(--shadow); }

/* Атрибут hidden должен реально скрывать оверлеи: их собственные правила задают
   display:flex, что перебивало бы [hidden]{display:none} из-за равной специфичности.
   Показ управляется снятием hidden (app.js), тогда display:flex снова работает. */
.onboarding[hidden], .modal-overlay[hidden], .flash[hidden] { display: none !important; }

/* ================= FLOATING DEV PANEL (all tester tools) =================
   A single collapsible dev tool. The wrench FAB is fixed bottom-right and always
   visible (testers need it everywhere); the panel is a raised card above it,
   hidden by default, scrollable, max-height ~80vh. Inside: page jumps, the course
   TOC («Оглавление»), demo actions, per-screen comments and the reset action. */
/* The wrap hugs the FAB; it is DRAGGABLE (app.js switches right/bottom → left/top and
   persists the spot). The panel is positioned out of flow (absolute) so it never shifts
   the FAB, and its open side flips to stay on-screen wherever the FAB is dragged. */
.dev-fab-wrap {
  position: fixed;
  right: var(--s4);
  /* Sit ABOVE the bottom action bar (.navbar / .page-foot): its primary button
     lives bottom-right, and the FAB must never cover it. The JS drag-clamp
     reserves the same bottom strip so it can't be dropped onto the bar either. */
  bottom: calc(var(--s4) + 72px);
  z-index: 300;
  width: max-content;
}
.dev-fab {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 8px 14px;
  font-family: inherit; font-size: 14px; font-weight: 700;
  color: var(--surface); background: var(--ink);
  border: none; border-radius: 999px;
  box-shadow: var(--shadow); cursor: grab;
  touch-action: none;   /* pointer drag shouldn't scroll the page on touch */
  transition: var(--tr-interactive);
}
.dev-fab:hover { background: var(--accent); color: var(--on-accent); }
.dev-fab:active { cursor: grabbing; transform: translateY(1px); }
.dev-fab-wrap.is-dragging .dev-fab { cursor: grabbing; }
.dev-fab[aria-expanded="true"] { background: var(--accent); }
.dev-fab-text { font-size: 13px; letter-spacing: 0.02em; }
.dev-fab-icon { display: block; flex: none; }

.dev-panel {
  position: absolute;
  right: 0; bottom: calc(100% + var(--s2));   /* default: above the FAB, right-aligned */
  width: min(360px, calc(100vw - 2 * var(--s4)));
  max-height: 80vh;
  display: flex; flex-direction: column;
  overflow: hidden;   /* header fixed; body scrolls */
}
.dev-panel[hidden] { display: none; }
/* Flip the panel's open side so it stays fully on-screen wherever the FAB sits
   (classes toggled by app.js from the FAB's viewport position). */
.dev-fab-wrap.dp-below .dev-panel { bottom: auto; top: calc(100% + var(--s2)); }
.dev-fab-wrap.dp-alignleft .dev-panel { right: auto; left: 0; }
.dev-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.dev-panel-title {
  font-size: var(--t-sm); font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-soft);
}
.dev-panel-close {
  width: 30px; height: 30px; flex: none;
  font-size: 20px; line-height: 1;
  color: var(--ink-soft); background: var(--surface);
  border: 1.5px solid var(--line); border-radius: 8px; cursor: pointer;
  transition: var(--tr-interactive);
}
.dev-panel-close:hover { border-color: var(--ink-faint); background: var(--row-hover); }
.dev-panel-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: var(--s3) var(--s4) var(--s4);
  -webkit-overflow-scrolling: touch;
}
.dev-section { margin-bottom: var(--s4); }
.dev-section:last-child { margin-bottom: 0; }
.dev-section-title {
  margin: 0 0 var(--s2);
  font-size: var(--t-sm); font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-faint);
}
/* Page/demo buttons: a compact wrap of quiet secondary buttons. */
.dev-btn-grid { display: flex; flex-wrap: wrap; gap: var(--s2); }
.dev-btn { flex: 0 0 auto; }
/* Active selection (e.g. current theme): accent outline + tint, no new primitive. */
.dev-btn.is-active {
  color: var(--accent); border-color: var(--accent); background: var(--accent-soft);
}
/* The course TOC inside the panel reuses the base .toc-* styles; keep it bounded. */
.dev-panel .toc-list {
  max-height: 40vh; overflow-y: auto;
  padding: 0; margin: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.dev-panel .toc-list .toc-day:last-child { margin-bottom: 0; }
/* Comments UI inside the panel: strip the drawer padding, keep the field/ref/note. */
.dev-panel .comments-current { padding: 0; border-bottom: none; }
.dev-panel .comments-note { margin: var(--s3) 0 0; }
.dev-panel .comments-current-actions { gap: var(--s2); }
.dev-panel .comments-current-actions .btn { flex: 1 1 auto; }

/* ================= COMPANY SELECTION (маркетплейс) ================= */
/* Полноэкранный оверлей между регистрацией и Днём 1. Перекрывает всё
   приложение, как онбординг; z-index ниже кнопки сброса (200). */
/* MARKETPLACE — full-surface region hosting a .page (card-grid view-type).
   #companyView is a flex column so the .page fills it and scrolls internally. */
.company-select {
  position: fixed; top: var(--topbar-h); left: 0; right: 0; bottom: 0; z-index: 100;
  background: var(--frame-bg);
  display: flex; flex-direction: column;
}
.company-select[hidden] { display: none !important; }
.company-inner { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }

/* header block now uses the shared onb-eyebrow/onb-title/onb-text, left-anchored
   in the column (like the exam) — no bespoke centered head. */
.company-head { margin: 0 0 var(--s8); }

.company-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  gap: 20px;
}
/* company-card = the .card primitive acting as a button; object behaviour (hover lift)
   is local but speaks the SAME press/hover language as every other actionable card:
   rest --e-1 → hover --e-2 + lift + border, active press. */
.company-card {
  position: relative;
  box-shadow: var(--e-1);
  display: flex; flex-direction: column;
  transition: var(--tr-interactive);
}
.company-card:hover { box-shadow: var(--e-2); border-color: var(--ink-3); transform: translateY(-2px); }
.company-card:active { transform: translateY(0); box-shadow: var(--e-1); }
.company-card.is-soon { opacity: .92; }

.company-badge {
  position: absolute; top: 16px; right: 16px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-faint); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 10px;
}

.company-emblem {
  width: 52px; height: 52px; border-radius: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 700; color: var(--on-accent);
  margin: 0 0 16px; flex: 0 0 auto;
}
.company-name { font-size: 20px; font-weight: 700; color: var(--ink); margin: 0 0 4px; }
.company-sector {
  font-size: 12px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 12px;
}
.company-tagline { font-size: 14px; line-height: 1.5; color: var(--ink-soft); margin: 0 0 14px; }

/* Feature 1 — key-facts chips on the card */
.fact-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.fact-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 600; color: var(--ink-soft);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 9px; line-height: 1.2;
}
/* Fact-chip icon: inline-SVG (§9), muted to sit as chrome beside the label. */
.fact-chip-icon { display: inline-flex; align-items: center; color: var(--ink-faint); }
.fact-chip-icon svg { display: block; }

/* Feature 8 (card part) — requirements one-liner. NO flex:1 here: the single
   spacer is the button's margin-top:auto, so every card's action bottom-aligns
   regardless of how much data (facts/tagline) sits above it. */
.company-reqline {
  font-size: 12px; line-height: 1.5; color: var(--ink-faint);
  margin: 0 0 18px;
}

/* view button = .btn .btn-secondary .btn-block; the ONE spacer bottom-anchors it. */
.company-view-btn { margin-top: auto; }

/* ---- Презентация компании (модалка) ---- */
/* TRUE modal: overlays fully, above the persistent header (z 150). */
.pres-overlay {
  position: fixed; inset: 0; z-index: 160;
  background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
  padding: 24px; overflow-y: auto;
}
.pres-overlay[hidden] { display: none !important; }
.pres-modal {
  width: 100%; max-width: 580px;
  padding: var(--s6) var(--s8) 0; margin: auto;
  max-height: 85vh; overflow-y: auto;
}  /* surface = .card-raised */
.pres-head { display: flex; align-items: center; gap: 14px; margin: 0 0 20px; }
.pres-emblem { width: 46px; height: 46px; border-radius: 12px; font-size: 20px; margin: 0; }
.pres-name { font-size: 20px; font-weight: 700; color: var(--ink); line-height: 1.2; }
.pres-sector {
  font-size: 12px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
  color: var(--ink-faint); margin-top: 3px;
}

.pres-video {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: var(--well); border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; margin: 0 0 20px;
}
.pres-play {
  width: 62px; height: 62px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--accent);
  background: var(--on-well); border: none;
  cursor: pointer; padding-left: 3px;
  box-shadow: var(--e-2);
  transition: var(--tr-interactive);
}
.pres-play svg { display: block; }
.pres-play:hover { transform: scale(1.06); }
.pres-play:active { transform: scale(0.98); }
.pres-video-cap {
  font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: color-mix(in srgb, var(--on-well) 70%, transparent);
}
.pres-video-note { font-size: 12px; color: color-mix(in srgb, var(--on-well) 55%, transparent); min-height: 14px; }

.pres-body { margin: 0 0 22px; }
.pres-body p { font-size: 15px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 14px; }
.pres-body p:last-child { margin-bottom: 0; }

/* ---- Presentation sections (framing / product / program / requirements) ---- */
.pres-section { margin: 0 0 22px; padding-top: 20px; border-top: 1px solid var(--line); }
.pres-section-title {
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 12px;
}
.pres-para { font-size: 14px; line-height: 1.6; color: var(--ink-soft); margin: 0 0 10px; }
.pres-para:last-child { margin-bottom: 0; }

.pres-bullets { list-style: none; margin: 0; padding: 0; }
.pres-bullets li {
  position: relative; font-size: 14px; line-height: 1.55; color: var(--ink-soft);
  padding: 0 0 0 18px; margin: 0 0 9px;
}
.pres-bullets li:last-child { margin-bottom: 0; }
.pres-bullets li::before {
  content: ""; position: absolute; left: 2px; top: 8px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}

.pres-program { display: flex; flex-direction: column; gap: var(--s2); }
/* Plain rows separated by whitespace (no card-per-item); keep the number chip. */
.pres-day {
  display: flex; align-items: flex-start; gap: 12px;
}
.pres-day-num {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: var(--accent);
  background: var(--accent-soft);
}
.pres-day-text { flex: 1; min-width: 0; }
.pres-day-title { font-size: 14px; font-weight: 700; color: var(--ink); line-height: 1.3; margin: 2px 0 2px; }
.pres-day-desc { font-size: 13px; line-height: 1.5; color: var(--ink-soft); }

.pres-checklist { list-style: none; margin: 0; padding: 0; }
.pres-checklist li {
  position: relative; font-size: 14px; line-height: 1.55; color: var(--ink-soft);
  padding: 0 0 0 26px; margin: 0 0 10px;
}
.pres-checklist li:last-child { margin-bottom: 0; }
.pres-checklist li::before {
  content: ""; position: absolute; left: 0; top: 3px;
  width: 16px; height: 16px; background-color: var(--good);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* Actions mirror the page-foot pattern: secondary «Закрыть» left, primary
   «Записаться» right — sticky so it's always reachable in the scrolling modal. */
.pres-actions {
  display: flex; gap: var(--s3); align-items: center;
  position: sticky; bottom: 0;
  padding: var(--s4) 0 var(--s6); margin-top: var(--s1);
  background: var(--frame-bg);
  border-top: 1px solid var(--line);
}
/* join = .btn .btn-primary (right); close = .btn .btn-secondary (left). */
.pres-join { margin-left: auto; }
.pres-join.is-disabled, .pres-join:disabled {
  background: var(--ink-faint); border-color: var(--ink-faint); color: var(--on-accent); opacity: .7;
}

@media (max-width: 560px) {
  .pres-actions { flex-wrap: wrap; }
}

/* ---------- English screening result: level badge + emulated metric bars ---------- */
.eng-level {
  display: inline-block; margin: 0 auto 18px;
  padding: 8px 18px; border-radius: 999px;
  background: var(--good-soft); color: var(--good);
  font-size: 15px; font-weight: 700; letter-spacing: .01em;
}
.eng-metrics { text-align: left; margin: 4px 0 20px; display: grid; gap: 12px; }
.eng-metric { display: block; }
.eng-metric-head { display: flex; justify-content: space-between; align-items: baseline; margin: 0 0 6px; }
.eng-metric-label { font-size: 14px; font-weight: 600; color: var(--ink); }
.eng-metric-val { font-size: 13px; font-weight: 700; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.eng-metric-track { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
.eng-metric-fill { height: 100%; border-radius: 999px; background: var(--accent); transition: width .5s ease; }
.eng-metric-fill.is-good { background: var(--good); }
.eng-metric-fill.is-bad { background: var(--bad); }

/* ---------- Intro / guide (страница ознакомления, мок) ---------- */
.intro-guide {
  position: fixed; inset: 0; z-index: 105;
  background: var(--bg);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 56px 24px 72px; overflow-y: auto;
}
.intro-guide[hidden] { display: none !important; }
.intro-inner { width: 100%; max-width: 560px; margin: auto; }
.guide-card {
  width: 100%; background: var(--frame-bg); border: 1px solid var(--line);
  border-radius: 18px; box-shadow: var(--shadow); padding: 34px 34px 30px;
}
.guide-lead { margin: 4px 0 26px; }
.guide-para {
  margin: 0 0 16px; font-size: 16px; line-height: 1.65; color: var(--ink-soft);
}
.guide-para:last-child { margin-bottom: 0; }

@media (max-width: 560px) {
  .intro-guide { padding: 40px 16px 56px; }
  .guide-card { padding: 26px 22px 24px; }
}

/* ---------- PROGRESSIVE DISCLOSURE ---------- */

/* Feature 1 — per-day intro is now a REAL screen rendered INLINE in #stage
   (a clean "cover"-style screen that opens each day 2–8). Styles are scoped under
   .dayintro-screen and use two classes so they win over the generic .stage h1/p. */
.dayintro-screen {
  min-height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 12px 0 24px;
}
/* Left-anchored content column (no card wrapper): the day title is the single
   focus, sections separated by whitespace. */
.day-intro-card {
  width: 100%; max-width: 520px; margin: auto;
  padding: var(--s8) 0;
  text-align: left;
}
.dayintro-screen .day-intro-eyebrow {
  font-size: 12px; font-weight: 550; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 var(--s3);
}
.dayintro-screen .day-intro-title {
  font-size: 26px; font-weight: 700; color: var(--ink); margin: 0 0 var(--s2); line-height: 1.2;
}
.dayintro-screen .day-intro-text {
  font-size: 15px; line-height: 1.55; color: var(--ink-soft); margin: 0 0 var(--s6);
}
/* Unlock — de-boxed: a good-accent bar + good text, not a filled panel. */
.dayintro-screen .day-intro-unlock {
  display: flex; align-items: flex-start; gap: var(--s3); text-align: left;
  padding: var(--s1) 0 var(--s1) var(--s4); margin: 0 0 var(--s6);
  border-left: 3px solid var(--good);
}
.dayintro-screen .day-intro-unlock-key {
  flex: none; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--good); background: var(--good-soft); padding: 4px 9px; border-radius: 999px; margin-top: 1px;
}
.dayintro-screen .day-intro-unlock-text {
  font-size: 14px; line-height: 1.55; font-weight: 600; color: var(--good);
}
.dayintro-screen .dayintro-hint {
  font-size: 13px; line-height: 1.5; color: var(--ink-mute, var(--ink-soft));
  margin: 0; opacity: .8;
}

/* Retention layer (Days 3–4): the GOAL — rendered as accent TEXT + a small countdown
   chip (no filled panel / left border), so it never out-weighs the day title. */
.dayintro-screen .dayintro-goal {
  text-align: left; margin: 0 0 var(--s6);
}
/* Small countdown chip — soft accent (chip, not a heavy filled pill). */
.dayintro-screen .dayintro-countdown {
  display: inline-block; font-size: 12px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); background: var(--accent-soft);
  padding: 5px 12px; border-radius: 999px; margin: 0 0 var(--s3);
}
/* Goal = accent TEXT (does not out-weigh the day title). The leading icon stays --ink-3
   (via .icon-lead) so it doesn't add a second accent inside the accent heading. */
.dayintro-screen .dayintro-goal-heading {
  display: flex; align-items: center; gap: var(--s2);
  font-size: 17px; font-weight: 700; color: var(--accent); margin: 0 0 var(--s2); line-height: 1.3;
}
.dayintro-screen .dayintro-goal-text {
  font-size: 14px; line-height: 1.55; color: var(--ink-soft); margin: 0;
}

/* Retention layer (Days 3–4): the TEASER — a light heading over plain "locked" text
   lines (no dashed box, no per-item boxes); a reward you're working toward. */
.dayintro-screen .dayintro-teaser {
  text-align: left; margin: 0 0 var(--s6);
}
.dayintro-screen .dayintro-teaser-heading {
  display: flex; align-items: center; gap: var(--s2);
  font-size: 12px; font-weight: 550; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 var(--s3);
}
.dayintro-screen .teaser-list { display: flex; flex-direction: column; gap: var(--s2); margin: 0 0 var(--s3); }
/* Plain locked rows: an inline-SVG lock (§9) + text, no per-item box. */
.dayintro-screen .teaser-item {
  display: flex; align-items: center; gap: var(--s2);
  font-size: 14px; font-weight: 500; line-height: 1.4; color: var(--ink-faint);
}
.dayintro-screen .teaser-lock { flex: none; display: inline-flex; color: var(--ink-3); }
.dayintro-screen .teaser-lock svg { width: 14px; height: 14px; display: block; }
.dayintro-screen .dayintro-teaser-text {
  font-size: 13px; line-height: 1.55; color: var(--ink-faint); margin: 0; font-style: italic;
}

@media (max-width: 560px) {
  .dayintro-screen { padding: 8px 0 24px; }
  .day-intro-card { padding: 32px 24px 28px; }
  .dayintro-screen .day-intro-title { font-size: 24px; }
}

/* Feature 2 — one-time coach marks (compact, non-blocking callout with arrow) */
.coach-mark {
  position: fixed; z-index: 112; max-width: 260px;
  background: var(--frame-bg); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: var(--shadow);
  padding: 12px 14px 12px;
}
.coach-text { font-size: 13.5px; line-height: 1.45; font-weight: 600; color: var(--ink); margin: 0 0 var(--s2); }
/* coach confirm = .btn .btn-primary .btn-sm */
.coach-arrow {
  position: absolute; top: -7px; width: 13px; height: 13px;
  background: var(--frame-bg);
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transform: rotate(45deg); transform-origin: center;
}

/* ================= KNOWLEDGE EXAM (гейт после Дня 4) =================
   Полноэкранный оверлей, визуально согласован со скринингом и результатом дня. */
/* Full-surface overlay that hosts a .page — its inner structure is the
   lesson-page template (.page-head / .page-body / .page-foot), so every exam
   screen renders identically to a lesson page. The overlay itself is just a
   flex column that lets the .page fill the viewport. */
.exam-screen {
  position: fixed; top: var(--topbar-h); left: 0; right: 0; bottom: 0; z-index: 106;
  background: var(--frame-bg);
  display: flex; flex-direction: column;
}
.exam-screen[hidden] { display: none !important; }
.exam-inner { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }

.exam-q { font-size: 17px; font-weight: 600; line-height: 1.45; color: var(--ink); margin: 0 0 16px; }
.exam-sub { font-size: 14px; color: var(--ink-soft); line-height: 1.5; margin: 0 0 14px; }

/* MCQ — варианты в столбик, выбор подсвечивается (без right/wrong во время экзамена) */
/* MCQ options use the .option primitive (selection via .option.is-selected). */
.exam-choices { display: flex; flex-direction: column; gap: var(--s2); }
.exam-choice { flex: none; }

/* Critique — расшифровка как в звонках курса + чек-лист действий */
.exam-thread { margin: 0 0 18px; }
.exam-bubble.is-agent {
  margin: 0 0 12px auto;               /* реплики агента — справа */
  background: var(--accent-soft);
  border-radius: 14px 4px 14px 14px;
}
.exam-check-label {
  font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 10px;
}
.exam-checklist { display: flex; flex-direction: column; gap: var(--s2); }
/* critique rows = .option with a checkbox + text flex layout; ticked state is local. */
.exam-check { display: flex; align-items: flex-start; gap: var(--s3); }
.exam-check.is-ticked { border-color: var(--accent); background: var(--accent-soft); }
.exam-check-box {
  flex: none; width: 22px; height: 22px; border-radius: 6px;
  border: 1.5px solid var(--line); background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--on-accent);
  transition: var(--tr-interactive);
}
.exam-check-box svg { display: block; }
.exam-check.is-ticked .exam-check-box { background: var(--accent); border-color: var(--accent); }
.exam-check-text { font-size: 15px; line-height: 1.45; color: var(--ink); }

/* Ordering — строки с номером и стрелками вверх/вниз */
.exam-order { display: flex; flex-direction: column; gap: 10px; }
.exam-order-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; background: var(--surface);
  border: 1.5px solid var(--line); border-radius: 10px;
}
.exam-order-num {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700;
}
.exam-order-text { flex: 1; font-size: 15px; line-height: 1.4; color: var(--ink); }
.exam-order-ctrls { flex: none; display: flex; flex-direction: column; gap: 4px; }
.exam-order-btn {
  appearance: none; width: 30px; height: 22px; line-height: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); background: var(--surface); color: var(--ink-soft);
  border-radius: 7px; cursor: pointer;
  transition: var(--tr-interactive);
}
.exam-order-btn svg { display: block; }
.exam-order-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.exam-order-btn:active:not(:disabled) { transform: translateY(1px); }
.exam-order-btn:disabled { opacity: 0.3; cursor: not-allowed; }

/* Result — PASS зелёный, FAIL красный (как результат дня/скрининга).
   Left-anchored prose; only the badge + one-line verdict title are centered. */
.exam-result { text-align: left; }  /* verdict circle now uses the .badge primitive */
.exam-result .badge { display: flex; }               /* block-level flex → margin:0 auto centers it */
.exam-result .onb-title { text-align: center; }      /* short verdict hero centered; prose stays left */
.exam-score { font-size: 16px; font-weight: 700; color: var(--ink); margin: 0 0 14px; }
.exam-result.is-pass .exam-score { color: var(--good); }
.exam-result.is-fail .exam-score { color: var(--bad); }
.exam-teaser {
  font-size: 13px; color: var(--ink-soft); line-height: 1.55; margin: 0 0 6px;
  padding: 10px 14px; background: var(--accent-soft);
  border-left: 3px solid var(--accent); border-radius: 8px; text-align: left;
}
.exam-weak {
  font-size: 14px; color: var(--bad); line-height: 1.5; margin: 0 0 12px;
  padding: 10px 14px; background: var(--bad-soft); border-radius: 8px; text-align: left;
}

@media (max-width: 560px) {
  .exam-bubble.is-agent { margin-left: 0; }
}

/* ======================= SHOP (Phase-2, валюта — баллы) ======================= */
/* SHOP — full-surface region hosting a .page (reveal/store/locked each render as
   a .page, same template as the exam). #shopView is a flex column so the .page
   fills it; the corner «Закрыть» (.overlay-dismiss) floats over it. */
.shop-screen {
  position: fixed; top: var(--topbar-h); left: 0; right: 0; bottom: 0; z-index: 107;
  background: var(--frame-bg);
  display: flex; flex-direction: column;
}
.shop-screen[hidden] { display: none !important; }
.shop-inner { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.shop-loading { color: var(--ink-faint); font-size: 14px; padding: 40px 0; }

/* ======================= LEADERBOARD (Phase-2, переоткрываемый раздел) =======================
   Full-surface region hosting a .page (same template as the shop/exam): the board renders
   via buildPage/pageHeader; the corner «Закрыть» (.overlay-dismiss) floats over it. */
.leaderboard-screen {
  position: fixed; top: var(--topbar-h); left: 0; right: 0; bottom: 0; z-index: 108;
  background: var(--frame-bg);
  display: flex; flex-direction: column;
}
.leaderboard-screen[hidden] { display: none !important; }
.leaderboard-inner { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }

/* Reveal — the accumulated points are the hero; accent belongs to this reward
   number + its primary CTA. Left-anchored like every other page. */
.shop-reveal-balance {
  display: inline-flex; align-items: baseline; gap: 8px;
  margin: var(--s1) 0 var(--s4); padding: 14px 26px;
  background: var(--accent-soft); border-radius: var(--r-lg);
}
.shop-reveal-num { font-size: 44px; font-weight: 800; color: var(--accent); line-height: 1; font-variant-numeric: tabular-nums; }
.shop-reveal-unit { font-size: 16px; font-weight: 600; color: var(--accent); }

/* Store header block: title «Магазин» + the balance as a prominent NEUTRAL stat
   (--ink, big & tabular) — so the ONE accent on the store screen is the Buy CTA. */
.shop-head { margin: 0 0 var(--s6); }
.shop-balance {
  display: inline-flex; align-items: baseline; gap: 10px;
  margin-top: var(--s3);
  padding: 10px 18px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r);
}
.shop-balance-label { font-size: 14px; font-weight: 600; color: var(--ink-soft); }
.shop-balance-num { font-size: 28px; font-weight: 800; color: var(--ink); line-height: 1; font-variant-numeric: tabular-nums; }
.shop-head-note { font-size: 13px; color: var(--ink-faint); line-height: 1.5; margin: 12px 0 0; }

/* Сетка карточек товаров */
.shop-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.shop-item {
  display: flex; flex-direction: column;
  background: var(--frame-bg); border: 1px solid var(--line);
  border-radius: var(--r); padding: 18px 18px 16px;
  box-shadow: var(--e-1);
  transition: var(--tr-interactive);
}
/* Neutral hover lift (the ONE accent on this screen stays the Buy button): --e-1→--e-2
   + a darker hairline, no accent border. Matches the company-card language. */
.shop-item:hover { border-color: var(--ink-3); box-shadow: var(--e-2); }
.shop-item.is-disabled { opacity: 0.7; }
.shop-item.is-disabled:hover { border-color: var(--line); box-shadow: var(--e-1); }
.shop-item-status { background: linear-gradient(180deg, var(--frame-bg), var(--surface-2)); }
.shop-item-name { font-size: 16px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.shop-item-desc { font-size: 13px; color: var(--ink-soft); line-height: 1.5; margin: 0 0 14px; flex: 1; }
.shop-item-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: auto;
}
/* Price in ink (not accent) so the filled Buy button is the sole accent per card. */
.shop-item-price { font-size: 16px; font-weight: 700; color: var(--ink); flex: none; }

/* buy = .btn .btn-primary .btn-sm; only the muted/disabled tint is local. */
.shop-buy.is-muted, .shop-buy:disabled {
  background: var(--line); border-color: var(--line); color: var(--ink-faint); opacity: 1;
}

/* Сводка внизу (заморозки + купленные статусы) — мелким шрифтом */
.shop-summary {
  display: flex; flex-wrap: wrap; gap: 8px 20px;
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
}
.shop-summary-item { font-size: 13px; color: var(--ink-faint); }

@media (max-width: 560px) {
  .shop-grid { grid-template-columns: 1fr; }
}
