/* PrepKoi web stylesheet: styles every screen of web/app.html (markup from
   screens.js, prova.js, kit.js and the other web/ui modules). Loaded after
   tokens.css, which supplies the var(--…) values. The ?v= stamp on its <link>
   is this file's md5 (tools/stamp_assets.py), so any edit needs a re-stamp.

   Material is design v3: light glass on cards, dark glass on the one main
   thing, glass inside glass only as a flat tile (a second blur layer drops
   text contrast below 4.5:1). The older canvas sections come first; the
   DESIGN v3 block further down overrides them and must stay after them.

   tools/check_web_ui.js reads this file raw, comments included, and fails on
   a hex colour, a font size under 11px, or physical left/right spacing
   (logical properties keep RTL mirroring free). */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* No word left alone on a paragraph's last line, as the phones break lines (`.display`
     balances its lines instead). Browsers without it wrap as before. */
  text-wrap: pretty;
  /* The page runs under the notch and the home indicator (viewport-fit=cover in
     app.html): side insets keep text clear of the notch in landscape and are
     zero in portrait. */
  padding-inline: env(safe-area-inset-left) env(safe-area-inset-right);
}

/* ---- page grid ----------------------------------------------------------- */

/* Body column, centred at --web-max. The v3 web-header section resets its
   padding. */
.wrap { max-width: var(--web-max); margin: 0 auto; padding: 26px 26px 0; }

/* Two-column screens. Each screen sets its ratio with `data-cols` (e.g. 1.1:1
   for an explanation, 1:1.1 for listening, where the question is wider than
   the player). Without the attribute, or with a value that has no rule here,
   the ratio is 1.35:1. */
.cols {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 26px;
  align-items: start;
}
.cols[data-cols="1.1:1"]  { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 24px; }
.cols[data-cols="1:1.05"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 24px; }
.cols[data-cols="1.25:1"] { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.cols[data-cols="1.15:1"] { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
.cols[data-cols="1:1.1"]  { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
.cols[data-cols="1:1.15"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.cols[data-cols="1:1"]    { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }

/* One column below 900px: under that the second column shrinks until
   unreadable. Repeated at the end of the file, after the v3 ratios. */
@media (max-width: 900px) { .cols, .cols[data-cols] { grid-template-columns: minmax(0, 1fr); } }

/* Narrow screen (≤560px). The header wraps: brand and the right-hand group on
   the first line, links on a second line that scrolls sideways rather than
   widening the page. Later v3 rules override the header part at the same
   width: nav hidden (the tab bar takes over), no wrapping. */
@media (max-width: 560px) {
  .header { flex-wrap: wrap; row-gap: 8px; }
  .header .brand { order: 1; }
  .header .row { order: 2; margin-inline-start: auto; }
  .nav {
    order: 3; width: 100%;
    overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { padding: 10px 11px; flex: 0 0 auto; }
  /* Buttons go full width: long labels do not fit side by side. */
  .btn { width: 100%; justify-content: center; }
  /* Except language-pick buttons: fourteen full-width buttons would make a
     list two screens long, so they size to content and the row wraps. */
  .btn.lang-pick { width: auto; }
  .stat { min-width: 0; flex: 1; }
}

/* Small button (header sign-in and level check, in-card actions): keeps the
   .btn 44px min-height, narrower padding. */
.btn-small { padding-block: 10px; padding-inline: 14px; font-size: 14px; }

/* Two-line language button (.lang-pick): the native name in its own script,
   the English name (.lang-name) below it at 11px, the floor check_web_ui.js
   enforces. */
.lang-pick { flex-direction: column; gap: 2px; line-height: 1.3; }
.lang-name { font-size: 11px; color: var(--ink-secondary); letter-spacing: .02em; }
.lang-pick.on .lang-name { color: inherit; opacity: .85; }

/* Footer: set off by a rule and smaller type, so it is there without
   competing with the task of the day. app.js renders .footer.foot3, restyled
   in the “Block W” section. */
.footer {
  margin-block-start: var(--sp-gap-lg);
  padding-block: 20px 28px;
  border-block-start: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 8px;
}
/* Mascot in empty states: shows the page is alive and waiting, not broken. */
.koi-sm { width: 120px; height: 120px; object-fit: contain; align-self: center; }

.foot-links { display: flex; flex-wrap: wrap; gap: 14px; }
.foot-links a {
  color: var(--accent-ink); text-decoration: none;
  font-size: var(--fs-secondary-sm); font-weight: 700;
  /* Tap height from block padding rather than a 44px min-height: in a row
     of links that would make the footer taller than a card. */
  padding-block: 10px;
}
.foot-links a:hover, .foot-links a:focus-visible { text-decoration: underline; }

/* Legal pages (main.legal): long text that must be read, not scanned. One
   reading-width column, v3 glass, list items with a teal dot, subheadings
   in the display font. */
.prose { gap: 10px; }
main.legal { max-width: 720px; margin-inline: auto; }
.legal-doc { padding: 22px 24px; font-size: 15px; line-height: 1.65; color: var(--ink); }
.legal-doc p { margin: 0 0 12px; }
.legal-doc p:last-child { margin-bottom: 0; }
.legal-doc b { font-family: var(--font-display); font-weight: 800; }
.legal-h {
  font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-secondary); margin: 22px 0 10px;
}
.legal-h3 { font-family: var(--font-display); font-weight: 800; font-size: 16px; margin: 18px 0 8px; }
.legal-doc > .legal-h3:first-child { margin-top: 4px; }
.legal-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.legal-list li { position: relative; padding-inline-start: 18px; }
.legal-list li::before {
  content: ""; position: absolute; inset-inline-start: 2px; top: .62em; width: 6px; height: 6px;
  border-radius: var(--r-pill); background: var(--pass);
}
@media (max-width: 560px) { .legal-doc { padding: 18px; } }

.stack { display: flex; flex-direction: column; gap: var(--sp-gap); }
.stack-lg { display: flex; flex-direction: column; gap: var(--sp-gap-lg); }
.row { display: flex; align-items: center; gap: var(--sp-gap-sm); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-gap-sm); }

/* ---- header -------------------------------------------------------------- */

/* Header band (.topbar) and its inner row, in the same margins as the body,
   so the logo and the first card share one vertical. The v3 web-header
   section restyles both as a floating glass bar. */
.topbar {
  background: var(--paper-bar);
  border-block-end: 1.5px solid var(--line);
}
.header {
  display: flex; align-items: center;
  gap: 12px; padding: 9px 26px;
  max-width: var(--web-max); margin: 0 auto;
}
/* The logo is a link: colour and no underline are set explicitly, or the
   browser paints it blue and underlined around the orange “Koi” span. No link
   in this interface keeps the default look. */
.brand {
  display: flex; align-items: center; gap: 8px;
  color: var(--ink); text-decoration: none;
}
.brand-disc { width: 27px; height: 27px; border-radius: var(--r-pill); display: block; }
.brand-name {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-logo);
  letter-spacing: -.01em;
}
.brand-name span { color: var(--accent-deep); }

/* Navigation links are words, not buttons; the tap floor comes from
   invisible padding. The v3 web-header section underlines the current link. */
.nav { display: flex; align-items: center; gap: 0; flex: 1; }
.nav a {
  font-family: var(--font-display); font-weight: 800; font-size: 14.5px;
  color: var(--ink-secondary); text-decoration: none;
  padding: 0 10px; min-height: var(--a11y-tap-target-min);
  display: inline-flex; align-items: center;
}
.nav a:hover { color: var(--ink); }
.nav a[aria-current="page"] { color: var(--accent-ink); }

/* Streak chip and avatar: the visible pill and circle are smaller than the
   44px tap target; the difference is invisible padding in the link, so the
   header does not grow. */
.run-chip {
  display: inline-flex; align-items: center; min-height: var(--a11y-tap-target-min);
  color: var(--ink); text-decoration: none;
}
.run-chip > span {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--paper-card); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-pill); padding: 6px 12px;
  box-shadow: 0 2px 0 var(--lip);
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px; white-space: nowrap;
}
.avatar {
  color: var(--ink-secondary); text-decoration: none;
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min);
  display: inline-flex; align-items: center; justify-content: center;
}
.avatar > span {
  width: 34px; height: 34px; border-radius: var(--r-pill);
  background: var(--track);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 800; font-size: 14px;
}

/* ---- right-to-left scripts -----------------------------------------------
   Selected by :lang as well as [dir="rtl"]: explanation paragraphs carry
   lang and dir="auto" (prova.js, screens.js), never dir="rtl", so each line
   turns by its own language and only :lang reaches it. RTL text gets its own
   faces and a line-height floor from tokens.css; at the Latin face and 1.55
   line height, Arabic marks above and below collide.

   The interface itself is not mirrored while its strings are English (handoff
   R01–R04): a mirrored layout with English text is broken English, not an
   Arabic interface. UI string translation comes last (rule 3); every inset
   here is logical, so mirroring then is one `dir` on <html>. */
:lang(ar), :lang(ur), :lang(fa), :lang(he), [dir="rtl"] {
  font-family: var(--font-rtl-body);
  line-height: var(--a11y-rtl-line-height-min);
}
:lang(ar) h1, :lang(ar) h2, :lang(ar) h3, :lang(ar) .kicker, :lang(ar) .btn,
:lang(ur) h1, :lang(ur) h2, :lang(ur) h3, :lang(ur) .kicker, :lang(ur) .btn,
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] .kicker, [dir="rtl"] .btn {
  font-family: var(--font-rtl-display);
}

/* ---- cards --------------------------------------------------------------- */

.card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card); padding: var(--sp-card-web);
  box-shadow: var(--shadow-card);
}
.card-inset {
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-input); padding: 13px 15px;
}
.panel {
  background: linear-gradient(170deg, var(--panel-from), var(--panel-to));
  color: var(--paper); border-radius: var(--r-panel);
  padding: var(--sp-card-web); box-shadow: var(--shadow-panel);
}
.panel .muted { color: rgba(255, 246, 236, .72); }

/* Caps kicker above a heading: grey by default; .kicker-accent only for what
   needs attention (“The trap · one word”), so a label never outshouts its
   title. */
.kicker {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-kicker);
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-secondary);
}
.kicker-quiet { color: var(--ink-secondary); }
.kicker-accent { color: var(--accent-ink); }

/* Web page title: the screen's main heading, full column width. The
   hand-drawn .squiggle under it is hidden by the v3 headings section. */
.display {
  font-family: var(--font-display); font-weight: 800;
  font-size: var(--fs-display-web); letter-spacing: -.025em; line-height: 1.05;
  margin: 8px 0 0;
}
.display-sm { font-size: var(--fs-display-web-sm); }
.squiggle { display: block; margin-top: 4px; width: 210px; height: 9px; }
.squiggle path { fill: none; stroke: var(--accent); stroke-width: 3.2; stroke-linecap: round; }
.squiggle.pass path { stroke: var(--pass); }
h1, h2, h3 { font-family: var(--font-display); font-weight: 800; margin: 0; line-height: 1.25; }
h1 { font-size: var(--fs-headline); letter-spacing: -.01em; }
h2 { font-size: var(--fs-card-title); }
h3 { font-size: var(--fs-header); }
p { margin: 0; }
.muted { color: var(--ink-secondary); }
.small { font-size: var(--fs-secondary); }
.tiny { font-size: var(--fs-secondary-sm); }

/* ---- buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--a11y-tap-target-min); padding: 12px 18px;
  border: 0; border-radius: var(--r-input);
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-body-sm);
  cursor: pointer; text-decoration: none;
}
.btn-primary {
  background: linear-gradient(180deg, var(--accent-from), var(--accent-to));
  color: var(--paper-card); box-shadow: var(--shadow-button);
}
.btn-primary:active { transform: translateY(2px); box-shadow: 0 2px 0 var(--accent-lip); }
.btn-quiet {
  background: var(--paper-card); color: var(--ink);
  border: 1.5px solid var(--line-strong); box-shadow: var(--shadow-card-sm);
}

/* A locked button must look locked: the disabled attribute alone is
   invisible, and a press that does nothing reads as a product bug. The v3
   buttons section overrides this with a beige fill at full opacity. */
.btn:disabled {
  opacity: .55; cursor: default; box-shadow: none;
}
.btn-primary:disabled:active { transform: none; }

/* A row allowed to wrap: fourteen languages do not fit on one line at any width. */
.row.wrap { flex-wrap: wrap; }
.gap-sm { gap: var(--sp-gap-sm); }

/* The selected item in a button group. Not by colour alone: colour alone cannot
   be read by colour-blind people, and the language choice is something a person
   checks by eye. */
.btn.on {
  border-color: var(--accent-ink); color: var(--accent-ink);
  box-shadow: inset 0 0 0 1.5px var(--accent-ink);
}
.lang-pick { padding: 10px 14px; }

/* Week calendar: seven day cells with a per-day state, not a bar (a person
   with a deadline cares about “when”, not “how much”). A freeze saved the
   streak but no lesson happened, so it is drawn unlike a study day. */
.week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.day {
  display: flex; align-items: center; justify-content: center;
  min-height: 38px; border-radius: var(--r-input);
  border: 1.5px solid var(--line-strong); background: var(--paper-warm);
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary-sm);
  color: var(--ink-tertiary);
}
.day-done { background: var(--accent); border-color: var(--accent-ink); color: var(--paper-card); }
.day-freeze { background: var(--paper-card); border-style: dashed; color: var(--ink-secondary); }
.day-today { border-color: var(--ink); color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--ink); }
.day-miss { background: transparent; }

/* Input field: 44px min-height, the same tap floor as buttons. */
.field {
  min-height: var(--a11y-tap-target-min);
  padding: 10px 14px; border-radius: var(--r-input);
  border: 1.5px solid var(--line-strong); background: var(--paper-card);
  color: var(--ink); font-family: var(--font-body); font-weight: 600;
  font-size: var(--fs-body-sm); width: 100%;
}
.field:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* Safari on iPhone zooms in when a field under 16px takes focus and does not
   zoom back, so fields are exactly 16px on narrow screens. */
@media (max-width: 560px) { #app .field { font-size: 16px; } }

/* Listening player (.player): full width, tap-height floor. The dark panel
   comes from the canvas task section and the v3 dark glass below. */
.player { width: 100%; min-height: var(--a11y-tap-target-min); }

/* ---- gates --------------------------------------------------------------- */

/* Gate row: the label in a fixed cell, the bar in a flex:1 cell, the width
   limit on the inner element, so labels of different length do not stretch
   the bars and the four gates compare by eye. */
.gate { display: flex; align-items: center; gap: 10px; }
.gate-name { flex: 0 0 74px; font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary); }
.gate-track { flex: 1; position: relative; height: 12px; background: var(--paper-warm);
  border: 1.5px solid var(--line-strong); border-radius: var(--r-pill); overflow: hidden; }
.gate-score { flex: 0 0 56px; text-align: end; font-family: var(--font-display);
  font-weight: 800; font-size: var(--fs-secondary); font-variant-numeric: tabular-nums; }
.gate-score.over { color: var(--pass-text); }
.gate-score.under { color: var(--fail-ink); }

/* Pass mark: one dashed line across all bars, its position computed from the passport. */
.gate-threshold {
  position: absolute; top: -4px; bottom: -4px; width: 0;
  border-inline-start: 2.5px dashed var(--ink);
}

/* Colour is never the only signal: next to the bar there is a glyph and a number. */
.glyph { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary-sm); }
.glyph.over { color: var(--pass-text); }
.glyph.under { color: var(--fail-ink); }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: var(--r-pill); padding: 5px 11px;
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary-sm);
}
.chip.over { background: var(--pass-bg); border: 1.5px solid var(--pass-border); color: var(--pass-text); }
.chip.under { background: var(--fail-bg); border: 1.5px solid var(--fail-border); color: var(--fail-ink); }
/* Current part of the run in the row of part chips: the “you are here” mark. */
.chip.on {
  border: 2px solid var(--accent); color: var(--accent-ink);
  background: var(--paper-warm); font-weight: 800;
}

/* ---- money and dates ----------------------------------------------------- */

.timeline { display: flex; flex-direction: column; gap: var(--sp-gap-sm); }
.timeline-row { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; align-items: start; }
.timeline-when {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary-sm);
  color: var(--accent-ink); padding-top: 2px;
}
.price-big { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-headline); }

.feature { display: flex; gap: 9px; align-items: flex-start; font-size: var(--fs-body-sm); }
.feature::before { content: "✓"; color: var(--pass-text); font-weight: 800; }

/* ---- small bits ---------------------------------------------------------- */

.trap { background: var(--trap); border-radius: var(--r-input-sm); padding: 0 3px; }
.it { font-style: normal; }          /* an Italian word is not italicised: it is a term, not a quotation */
.divider { height: 1.5px; background: var(--line); border: 0; margin: 4px 0; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* A Latin word or number inside a right-to-left line stays left-to-right:
   otherwise the full stop and the quote mark land on the wrong side. */
[dir="rtl"] .ltr { direction: ltr; unicode-bidi: isolate; }

/* ── state screens: win, result, payment, waiting, settings ───────────────── */

/* Mascot image: its size lives here, not in the markup. */
.koi { width: 190px; height: auto; display: block; }

/* Status chip: above the line (.chip-good) or below it (.chip-bad). */
.chip-good {
  color: var(--pass-text); background: var(--pass-bg);
  border: 1.5px solid var(--pass-border);
}
.chip-bad {
  color: var(--fail-ink); background: var(--fail-bg);
  border: 1.5px solid var(--fail-border);
}

/* Three numbers in a row: how many above the line, how many below, what streak. */
.stat {
  display: flex; flex-direction: column; align-items: center;
  min-width: 78px; padding: 10px 12px;
  background: var(--paper-warm); border: 1px solid var(--line-strong);
  border-radius: var(--r-card-sm);
}
.stat b { font-family: var(--font-display); font-size: var(--fs-card-title); }

/* ── keyboard focus ────────────────────────────────────────────────────────── */
/*
   Visible keyboard focus on every interactive element: keyboard and
   screen-reader users must see where they are (handoff accessibility floor),
   and the browser's faint default outline is lost on the warm background.
   :focus-visible, not :focus, so a mouse click draws no ring.
*/
:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid var(--accent-ink);
  outline-offset: 2px;
  border-radius: var(--r-input);
}
/* Dark panel: an orange outline on near-black reads worse than a paper-coloured one. */
.panel :where(a, button):focus-visible { outline-color: var(--paper); }

/* The avatar links to /settings: it must look pressable. */
a.avatar { text-decoration: none; }
a.avatar:hover { border-color: var(--accent); }

/* “Label: value” rows (settings): the value carries the weight and the label
   is muted, the reverse of the event timeline (.timeline), whose accent sits
   on the left. */
.kv { display: flex; flex-direction: column; gap: var(--sp-gap-sm); }
.kv-row { display: grid; grid-template-columns: 136px minmax(0, 1fr); gap: 12px; align-items: baseline; }
.kv-key {
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-secondary);
  color: var(--ink-secondary);
}
.kv-val { font-weight: 700; }

/* The value in a settings row is a link: it leads to where the value is changed.
   Its look is set explicitly, otherwise the browser paints it blue and underlined,
   and on warm paper that looks like a foreign insert. */
.row-link { color: var(--accent-ink); text-decoration: none; }
.row-link:hover { text-decoration: underline; }

/* Small link (a.tiny), such as “pass mark N” leading to the pass rule. */
a.tiny { color: var(--accent-ink); text-decoration: none; }
a.tiny:hover { text-decoration: underline; }

/* 44px tap height for links that stand alone: the logo, a.tiny, settings
   value links. A link inside a sentence keeps its line height (WCAG exempts
   inline targets). */
a.brand, a.tiny, a.row-link {
  min-height: var(--a11y-tap-target-min);
  display: inline-flex; align-items: center;
}
/* A settings row whose value is a link centres instead of baseline-aligning:
   the 44px link would pull the key down. */
.kv-row:has(a.row-link) { align-items: center; }
/* A row link inside a sentence (the pricing answers) stays inline, so its line
   is as tall as the others; the tap height comes from block padding, which
   does not grow the line. */
:is(p, span, li) > a.row-link { display: inline; min-height: 0; padding-block: 13px; }

/* ── run mode: the person inside a task ─────────────────────────────────────── */
/*
   Run-mode header (.prova-head, prova.js): no menu and no streak, only the
   way out, the title, the question position and the clock, as in the exam
   room. The canvas and v3 task sections below restyle it.
*/
.prova-head {
  display: flex; align-items: center; gap: var(--sp-gap);
  padding: 14px 0; border-bottom: 1.5px solid var(--line);
  margin-bottom: var(--sp-gap-lg);
}
.prova-close {
  /* Exit from the run: a missed tap here goes unnoticed at first, so it gets
     the 44px floor like the answer-sheet bubbles. */
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min);
  border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--paper-card); border: 1.5px solid var(--line-strong);
  color: var(--ink); text-decoration: none;
  font-family: var(--font-display); font-weight: 800;
}
.prova-title {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-header);
}
.prova-right { margin-inline-start: auto; }
.prova-right .ok { color: var(--pass-text); }
.prova-right .over { color: var(--fail-ink); }
.prova-body { padding-bottom: 40px; }

/* Question strip: one dot per question, filled (.on) when answered; the
   current one (.cur) gets an ink outline, so it does not rely on colour and
   the row stays even. Dots, not vertical ticks, and an outline, not extra
   height: both of those read as a “0” before the dots on a narrow screen. */
.prova-marks { display: inline-flex; gap: 4px; align-items: flex-end; }
.prova-marks i {
  width: 9px; height: 9px; border-radius: var(--r-pill);
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
}
.prova-marks i.on { background: var(--accent); border-color: var(--accent-ink); }
.prova-marks i.cur {
  border-color: var(--ink);
  outline: 2px solid var(--ink); outline-offset: 2px;
}

/* Countdown ring. Time remaining, not time elapsed: a playback bar looks like
   something you can drag, and in the exam there is nothing to drag. */
.ring { position: relative; width: 220px; height: 220px; }
/* Only the ring's own svg turns (so the arc starts at the top); a descendant
   rule would also turn the play icon in the centre. */
.ring > svg { transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: rgba(255, 246, 236, .18); stroke-width: 12; }
.ring-arc {
  fill: none; stroke: var(--accent); stroke-width: 12; stroke-linecap: round;
}
.ring-mid {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
}
.ring-num {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-headline);
  color: var(--paper); font-variant-numeric: tabular-nums;
}

/* The question is the card heading (h2.q-stem in prova.js), not a
   paragraph: that is how both the eye and a screen reader read it. */
.q-stem { font-size: var(--fs-card-title); }
/* Answer option: the key on the left is a letter, as on the answer sheet;
   the tick on the right is a second cue for the selection besides colour. */
.opt {
  display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; gap: 10px;
  align-items: center; width: 100%; text-align: start;
  padding: 12px 14px; min-height: var(--a11y-tap-target-min);
  background: var(--paper-card); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-input); color: var(--ink);
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-body-sm);
  cursor: pointer;
}
/* An answer option locked after the recording ends dims only to .85: the
   person still reads their choice against the explanation. */
.opt:disabled { cursor: default; opacity: .85; }
.opt-key {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--r-pill);
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary-sm);
}
.opt-tick { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary-sm); }
.opt.on { border-color: var(--accent); }
.opt.on .opt-key { background: var(--accent); border-color: var(--accent-ink); color: var(--paper-card); }
.opt.right { border-color: var(--pass); }
.opt.right .opt-key { background: var(--pass); border-color: var(--pass-text); color: var(--paper-card); }
.opt.right .opt-tick { color: var(--pass-text); }
.opt.wrong { border-color: var(--fail); }
.opt.wrong .opt-key { background: var(--fail); border-color: var(--fail-ink); color: var(--paper-card); }
.opt.wrong .opt-tick { color: var(--fail-ink); font-family: var(--font-body); font-weight: 700; }
.opt-letter { grid-template-columns: 26px auto; justify-content: start; width: auto; }

/* The very word that flipped the sentence. One per screen: a handoff rule. */
mark.trap { background: var(--trap); color: var(--ink); padding: 0 3px; border-radius: var(--r-input-sm); }

/* Writing: the field and the rubric axes. */
.letter {
  width: 100%; min-height: 220px; resize: vertical;
  padding: 14px; border-radius: var(--r-input);
  border: 1.5px solid var(--line-strong); background: var(--paper-card);
  color: var(--ink); font-family: var(--font-body); font-weight: 600;
  font-size: var(--fs-body); line-height: 1.6;
}
.axis { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: baseline; }
.axis-name { display: flex; flex-direction: column; }
.axis-name > span:first-child {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary);
}
.axis-score {
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary);
  font-variant-numeric: tabular-nums; color: var(--ink-secondary);
}
.axis-score.over { color: var(--pass-text); }
.axis-score.under { color: var(--fail-ink); }

/* Transfer answer sheet: eighteen bubbles. Filled always means “done”: this is a
   handoff rule, and no opposite reading is allowed. */
.sheet { display: flex; flex-wrap: wrap; gap: 9px; }
.bubble {
  /* 44px at every width: the tap floor does not depend on window width, and
     a missed bubble costs a point. At 375px eighteen fit five per row
     (5 × 44 + 4 × 9 = 256 of about 310 inside the card). */
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min);
  border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 800; font-size: var(--fs-secondary);
  cursor: pointer;
  background: transparent; border: 1.5px solid var(--ink-secondary); color: var(--ink-tertiary);
}
.bubble.cur { background: var(--paper-warm); border: 2px solid var(--accent); color: var(--ink); }
.bubble.done { background: var(--paper); border: 1.5px solid var(--ink); color: var(--ink); }

@media (max-width: 560px) {
  .prova-head { flex-wrap: wrap; row-gap: 8px; }
  .prova-marks { order: 3; width: 100%; }
  .ring { width: 170px; height: 170px; }
  .ring svg { width: 170px; height: 170px; }
}

/* ── small utility classes instead of inline styles ────────────────────────── */
/*
   Utility classes in place of inline styles. Inline style="…" remains only
   for values computed from data (bar widths, pass-mark and plot positions,
   flask levels such as --lvl), which no class can express. Those keep
   'unsafe-inline' in style-src (deploy/prepkoi-app-csp.conf; reason in
   deploy/INFRA.md).
*/
.screen { padding-bottom: 40px; }        /* whitespace under the last card */
.gap-sm { gap: 8px; }
.gap-9 { gap: 9px; }
.gap-md { gap: 10px; }
.gap-base { gap: 12px; align-items: baseline; }
.on-panel { color: var(--paper-warm); }  /* text on a dark panel */
.lead { margin-top: 6px; }
.prose { margin-top: 8px; max-width: 62ch; }  /* reading-width line */
.centered { align-items: center; text-align: center; }
.chosen { border-color: var(--accent); }
.num-lg { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-headline); }
.num-md { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-card-title); }

/* Reading passage below 900px: a 270–330-word text and its items run to
   about five phone screens, so the text scrolls in its own box and the
   questions stay next to it. Wider screens show the columns side by side.
   ⚠️ A bottom fade via a sticky ::after covers the last line. */
@media (max-width: 900px) {
  .passage {
    max-height: min(46vh, 520px);
    overflow-y: auto;
    padding-inline-end: 6px;
    border-inline-start: 3px solid var(--line);
    padding-inline-start: 12px;
  }
}
/* Writing task's list of communicative goals; the live checklist variant
   is .goals.live in the flask section. */
.goals { margin: 0; padding-inline-start: 20px; }
.goals li { margin-bottom: 4px; }

/* ─── Motion ──────────────────────────────────────────────────────────────────

   1. Durations are --motion-* tokens and deliberately short: this is a
      trainer with an exam clock, so animation explains a transition and
      takes no time away. Past about 200 ms a person starts to WAIT.

   2. Screen entrance runs only on a route or step change: markRise() in
      app.js sets data-rise and --i on the top-level blocks (styles in
      “Motion v3”). Inside a run the markup redraws on every clock tick, and
      animating each redraw would flicker.

   3. `prefers-reduced-motion` turns everything down to zero: motion causes
      nausea and dizziness for some people, and extra frames lag on cheap
      phones. */

/* Response to a finger is always there, even with motion turned off: it is not
   decoration but feedback; the person must see that the press registered. So
   colour and shadow transitions live outside the media query, while translation
   and scale live inside it. */
.btn, a, button, input, textarea, select, .chip, .day {
  transition: background-color var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease),
              color var(--motion-fast) var(--motion-ease),
              box-shadow var(--motion-fast) var(--motion-ease),
              opacity var(--motion-fast) var(--motion-ease);
}

@media (prefers-reduced-motion: no-preference) {
  .btn, button { transition: background-color var(--motion-fast) var(--motion-ease),
                             border-color var(--motion-fast) var(--motion-ease),
                             color var(--motion-fast) var(--motion-ease),
                             box-shadow var(--motion-fast) var(--motion-ease),
                             transform var(--motion-fast) var(--motion-ease); }
  /* Press and hover for v3 are in the “Motion v3” section. */
  .card { transition: box-shadow var(--motion-base) var(--motion-ease),
                      transform var(--motion-base) var(--motion-ease); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* A hidden tab keeps no animation running: app.js sets .pk-hidden on <html>
   while document.hidden, and every loop goes on from where it stopped when
   the tab comes back. */
.pk-hidden *, .pk-hidden *::before, .pk-hidden *::after { animation-play-state: paused !important; }

/* ─── Landing (M01) ────────────────────────────────────────────────────────── */

/* The fish on a marketing surface, per the handoff rule: the full fish only on
   wins and in marketing; inside the app only the disc in the header remains. */
.koi-hero { display: block; margin-inline: auto; margin-block-end: var(--sp-sm, 8px); }

/* Landing proofs: exactly three equal columns, a large number over a small
   caption, so the figures compare at a glance and none looks primary.
   Stacked under 680px. */
.proofs {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
}
@media (max-width: 680px) {
  .proofs { grid-template-columns: 1fr; }
}
.proof { text-align: center; }
.proof .num-lg { font-size: var(--fs-display, 40px); line-height: 1; color: var(--accent-ink); }


/* ══ Canvas components ══════════════════════════════════════════════════════
   Taken by the numbers from the previous canvas
   (archive/design-2026-09/handoff-2026-09-17). The DESIGN v3 block below
   overrides their material. */

/* Task-of-the-day card: title on the left, big button on the right, on one line. */
.hero-card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-card);
  padding: 22px; margin-top: 20px;
}
.hero-row { display: flex; align-items: center; gap: 20px; }
.hero-text { flex: 1; min-width: 0; }
.hero-title {
  font-family: var(--font-display); font-weight: 800; font-size: 28px;
  line-height: 1.2; margin: 6px 0 0;
}
.hero-body { font-size: 15px; color: var(--ink-secondary); line-height: 1.5; margin-top: 6px; max-width: 400px; }

/* The big action button: eighteen pixels and radius twenty. An ordinary interface
   button is smaller; this one is one per screen, and the canvas makes it the main one. */
.btn-hero {
  flex: 0 0 auto; font-size: 18px; padding: 17px 28px; border-radius: var(--r-card-md);
}

/* Small secondary cards: two per row under the task. */
.mini-row { display: flex; gap: 12px; margin-top: 16px; }
.mini-row > * { flex: 1; min-width: 0; }
.mini-card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-md); box-shadow: var(--shadow-card-sm); padding: 15px;
}
.mini-text { font-size: 15.5px; line-height: 1.5; margin-top: 7px; }
.mini-note { font-size: 13.5px; color: var(--ink-secondary); margin-top: 6px; line-height: 1.45; }

/* The trap word: a yellow patch reaching three points past the line on every
   side; not a text selection but a mark on paper. */
mark.trap, .trap {
  background: var(--trap); box-shadow: 0 0 0 3px var(--trap);
  border-radius: var(--r-input-sm); font-weight: 800; color: inherit; padding: 0;
}

/* A large number with its scale: “9 / 12”. */
.score-lg { font-family: var(--font-display); font-weight: 800; font-size: 24px; margin-top: 5px; }
.score-lg small { font-size: 14px; color: var(--ink-secondary); }

/* Gates as a column (home): name and score on one line, a thick bar under them,
   the pass mark a solid tick at seven twelfths. The dividers between gates use
   the track colour, not the card rule: these are rows of one list, not separate blocks. */
.gates-head { display: flex; align-items: center; justify-content: space-between; margin: 0 2px 10px; }
.gates-card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card);
  padding: 6px 16px 10px;
}
.gate-block { padding: 12px 0; }
.gate-block + .gate-block { border-top: 1.5px solid var(--track); }
.gate-top { display: flex; align-items: center; gap: 10px; }
.gate-label { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.gate-val { font-family: var(--font-display); font-weight: 800; font-size: 16px; font-variant-numeric: tabular-nums; }
.gate-val.over { color: var(--pass-text); }
.gate-val.under { color: var(--fail-ink); }
.bar {
  position: relative; height: 9px; border-radius: var(--r-pill);
  background: var(--track); margin-top: 8px; overflow: hidden;
}
.bar > .bar-line { display: block; position: absolute; top: -2px; bottom: -2px; width: 2.5px; background: var(--ink); }

/* Money on a warm patch: a large “€0” and a line next to it. Bold in the line is
   the date and the amount, exactly what the person must remember. */
.money-card {
  display: flex; align-items: center; gap: 13px;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-md); padding: 15px; margin-top: 14px;
}
.money-big { flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 26px; color: var(--accent-deep); }
.money-text { flex: 1; font-size: 13.5px; line-height: 1.45; color: var(--ink-warm); }
.money-text b { font-weight: 800; color: var(--ink); }

/* Date tile: the day large, the month below. A sitting is a date, and the canvas
   shows it as a date on a calendar, not as a line of text. */
.date-row { display: flex; align-items: center; gap: 12px; margin-top: 9px; }
.date-tile {
  width: 44px; height: 44px; flex: 0 0 auto; border-radius: var(--r-tile);
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.date-tile b { font-family: var(--font-display); font-weight: 800; font-size: 15px; line-height: 1; }
.date-tile small { font-size: 11px; color: var(--ink-secondary); line-height: 1.2; text-transform: uppercase; }
.date-text { flex: 1; font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; }
.mt-12 { margin-top: 12px; }

/* State card on home: a failed sitting, writing under review, a streak at risk.
   The canvas draws these states as separate screens; on home they only call the
   person there, so the card is small and sits between the title and the task. */
.state-card { margin-top: 16px; display: flex; flex-direction: column; gap: 6px; }
.state-card .btn { align-self: flex-start; margin-top: 6px; }

/* Gates as rows (progress, W05): glyph, name, short bar, score. The glyph is a
   circle with a tick or a dash, so colour is not the only signal. */
.gates-rows {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card);
  padding: 16px 20px 18px;
}
.gates-rows .head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.meta { font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--ink-secondary); text-decoration: none; }
/* Tap-target floor via invisible padding with a negative margin: the finger
   hits forty-four points, while the row keeps its drawn height. */
a.meta { display: inline-flex; align-items: center; padding-block: 14px; margin-block: -14px; }
.grow { display: flex; align-items: center; gap: 12px; padding: 11px 0; }
.grow + .grow { border-top: 1.5px solid var(--track); }
.gmark {
  width: 19px; height: 19px; flex: 0 0 auto; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center;
}
.gmark.over { background: var(--pass); }
.gmark.under { background: var(--fail-bg); box-shadow: inset 0 0 0 2px var(--fail); }
.gmark svg { width: 11px; height: 11px; fill: none; stroke: var(--paper-card); stroke-width: 4; stroke-linecap: round; }
.gmark.under i { width: 6px; height: 2.5px; border-radius: var(--r-pill); background: var(--fail); }
.gname { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.bar-sm {
  position: relative; width: 120px; height: 8px; flex: 0 0 auto;
  border-radius: var(--r-pill); background: var(--track); overflow: hidden;
}
.bar-sm > .bar-line { display: block; position: absolute; top: -2px; bottom: -2px; width: 2.5px; background: var(--ink); }
.gnum {
  width: 56px; text-align: end; font-family: var(--font-display); font-weight: 800;
  font-size: 17px; font-variant-numeric: tabular-nums;
}
.gnum.under { color: var(--fail-ink); }
.gnum small { font-size: 12.5px; color: var(--ink-secondary); }

/* Two numbers under the gates: prove passed and traps. The large figure is what
   can be seen at arm's length; everything else is smaller. */
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 16px; }
.duo > * { min-width: 0; }
.card-22 {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card); padding: 16px;
}
.big-num { display: flex; align-items: baseline; gap: 8px; margin-top: 6px; }
.big-num b { font-family: var(--font-display); font-weight: 800; font-size: 30px; }
.big-num span { font-size: 14px; color: var(--ink-secondary); }

/* The week as circles: a completed day is green with a tick, a freeze is a dash
   in a pale ring, today is an orange ring, a missed day is empty. A circle, not a
   tile: a day is a mark on a calendar, not a button. */
.week7 { display: flex; justify-content: space-between; margin-top: 14px; }
.week7 .d { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.week7 .c {
  width: 38px; height: 38px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--paper-warm);
}
.week7 .c.done { background: var(--pass); }
.week7 .c.done svg { width: 13px; height: 13px; fill: none; stroke: var(--paper-card); stroke-width: 4.5; stroke-linecap: round; }
.week7 .c.freeze { background: var(--fail-bg); box-shadow: inset 0 0 0 2px var(--line-strong); }
.week7 .c.freeze i { width: 8px; height: 2.5px; border-radius: var(--r-pill); background: var(--ink-tertiary); }
.week7 .c.today { box-shadow: inset 0 0 0 2.5px var(--accent); }
.week7 .c.miss { box-shadow: inset 0 0 0 1.5px var(--line-strong); }
.week7 .l { font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--ink-secondary); }
.note-warm { font-size: 13.5px; color: var(--ink-warm); line-height: 1.5; margin-top: 14px; }

/* Below the line: a tile with the score and a sentence where the bold part is the part name. */
.num-tile {
  width: 48px; height: 48px; flex: 0 0 auto; border-radius: var(--r-input-sm);
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 800; font-size: 18px; color: var(--fail-ink);
}
.tile-row { display: flex; align-items: center; gap: 13px; margin-top: 10px; }
.tile-row .t { flex: 1; font-size: 14px; line-height: 1.45; color: var(--ink-warm); }
.tile-row .t b { font-weight: 800; color: var(--ink); }
.btn-wide { width: 100%; font-size: 17px; padding: 15px; border-radius: var(--r-input); margin-top: 14px; }

/* The sitting as a line on a warm patch, with no label: on progress it is a
   reference, not a section. The date tile is white here: a warm tile would vanish
   on the warm background. */
.warm-row {
  display: flex; align-items: center; gap: 13px;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-md); padding: 15px; margin-top: 14px;
}
.warm-row .date-tile { background: var(--paper-card); }
.warm-row .t { flex: 1; font-size: 13.5px; line-height: 1.45; color: var(--ink-warm); }
.warm-row .t b { font-weight: 800; color: var(--ink); }
.mt-14 { margin-top: 14px; }
.mt-20 { margin-top: 20px; }
.display.s38 { font-size: 38px; }
.display.s36 { font-size: 36px; }
.p18 { padding: 18px; }

/* Practice (W07) header: the title column and a side note; stacked under 700px. */
.practice-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; }
.practice-top .lead-col { flex: 0 0 340px; }
.practice-top .side-note { font-size: 14.5px; color: var(--ink-secondary); line-height: 1.5; max-width: 420px; text-align: end; }
@media (max-width: 700px) {
  .practice-top { flex-direction: column; align-items: flex-start; }
  .practice-top .lead-col { flex: 1 1 auto; }
  .practice-top .side-note { text-align: start; }
}

/* Mode switch: the base in the track colour, the selected option a white patch
   with a shadow. This is not two buttons but one choice of two, hence one base for both. */
.seg {
  display: flex; gap: 6px; background: var(--track); border-radius: var(--r-input-sm);
  padding: 4px; margin-top: 12px; max-width: 340px;
}
.seg a, .seg span {
  flex: 1; text-align: center; font-family: var(--font-display); font-weight: 800;
  font-size: 14.5px; padding: 10px 0; white-space: nowrap; border-radius: 12px;
  color: var(--ink-warm); text-decoration: none; min-height: var(--a11y-tap-target-min);
  display: inline-flex; align-items: center; justify-content: center;
}
.seg [aria-current="page"] { background: var(--paper-card); color: var(--ink); box-shadow: 0 2px 0 var(--line-strong); }

.grid4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-top: 20px; }
@media (max-width: 900px) { .grid4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .grid4 { grid-template-columns: minmax(0, 1fr); } }
.pcard {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card); padding: 18px;
  display: flex; flex-direction: column;
}
/* A gate below the line: red border and shadow, seen before the number is
   read. The v3 glass section resets the shadow; the border stays. */
.pcard.under { border-color: var(--fail-border); box-shadow: 0 4px 0 var(--fail-lip); }
.pcard .top { display: flex; align-items: center; gap: 10px; }
.pcard .nm { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 20px; }
.pcard .sc { font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.pcard.under .sc { color: var(--fail-ink); }
.pcard .sc small { font-size: 13px; color: var(--ink-secondary); }
.pcard .bar { height: 8px; margin-top: 10px; }
.pcard .nt { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; margin-top: 11px; flex: 1; }

/* Buttons inside a card: sixteen pixels, radius eighteen. The primary one is
   orange on a short shadow in the link colour; the secondary one is a warm patch
   on a paper shadow. The canvas tells them apart by material, not size. */
.btn-card {
  width: 100%; font-size: 16px; padding: 13px; border-radius: var(--r-input); margin-top: 13px;
}
.btn-card.btn-primary { box-shadow: 0 3px 0 var(--accent-ink); }
.btn-warm {
  background: var(--paper-warm); color: var(--ink);
  border: 1.5px solid var(--line-strong); box-shadow: 0 3px 0 var(--lip);
}
.duo-16 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; margin-top: 16px; }
@media (max-width: 560px) { .duo-16 { grid-template-columns: minmax(0, 1fr); } }
.trap-line { font-size: 16px; line-height: 1.55; margin-top: 9px; }
.big-num.lg b { font-size: 30px; }
.big-num.lg span { line-height: 1.45; }

/* Win (W04): the full-height mascot on the left, a title with a green line, three
   numbers, and a warm “next, already unlocked” band. The screen a person studies
   for: the only one where the mascot moves. */
.win-card {
  position: relative; overflow: hidden;
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow-card); padding: 26px;
}
.win-grid { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 26px; align-items: center; }
@media (max-width: 700px) { .win-grid { grid-template-columns: minmax(0, 1fr); justify-items: center; } }
.win-koi { position: relative; display: flex; justify-content: center; }
.win-koi img { width: 190px; height: 190px; object-fit: contain;
  animation: pk-bob var(--motion-idle) ease-in-out infinite alternate; }
.win-koi .sp1, .win-koi .sp2 { position: absolute;
  animation: pk-spark var(--motion-idle) ease-in-out infinite alternate; }
.win-koi .sp1 { left: 8px; top: 6px; width: 11px; height: 11px; border-radius: var(--r-pill);
  background: var(--spark); transform: rotate(18deg); }
.win-koi .sp2 { right: 2px; top: 34px; width: 8px; height: 8px; border-radius: var(--r-pill);
  background: var(--accent); }
@keyframes pk-bob { from { transform: translateY(0); } to { transform: translateY(-7px); } }
@keyframes pk-spark { from { transform: scale(.7); opacity: .35; } to { transform: scale(1.15); opacity: .9; } }
@media (prefers-reduced-motion: reduce) {
  .win-koi img, .win-koi .sp1, .win-koi .sp2 { animation: none; }
}
.chip-win {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--pass-text); background: var(--pass-bg); border: 1.5px solid var(--pass-border);
  padding: 7px 13px; border-radius: var(--r-pill);
}
.win-lede { font-size: 16px; color: var(--ink-secondary); line-height: 1.55; margin-top: 12px; max-width: 520px; }
.win-stats { display: flex; gap: 12px; margin-top: 18px; max-width: 470px; }
.win-stats > div {
  flex: 1; background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-md); box-shadow: var(--shadow-card-sm); padding: 13px 18px; text-align: center;
}
.win-stats b { display: block; font-family: var(--font-display); font-weight: 800; font-size: 26px; }
.win-stats b.over { color: var(--pass); }
.win-stats b.under { color: var(--fail-ink); }
.win-stats span { display: block; font-size: 12.5px; color: var(--ink-secondary); margin-top: 1px; }
.next-bar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 20px; align-items: center;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-sm); padding: 18px; margin-top: 22px;
}
@media (max-width: 700px) { .next-bar { grid-template-columns: minmax(0, 1fr); } }
.next-bar .l { display: flex; align-items: center; gap: 14px; }
.next-bar .num-tile { background: var(--paper-card); }
.next-bar .ttl { display: block; font-family: var(--font-display); font-weight: 800; font-size: 20px; margin-top: 3px; }
.next-bar .sub { display: block; font-size: 13.5px; color: var(--ink-secondary); margin-top: 2px; }
.next-bar .r { display: flex; align-items: center; gap: 12px; }
/* Quiet link under the primary button (v3 `cta(…, sub)`): 12.5 px in the text
   face, muted; the touch target stays at 44 px. */
.link-quiet {
  font-family: var(--font-body); font-weight: 600; font-size: 12.5px; color: var(--ink-secondary);
  text-decoration: none; min-height: var(--a11y-tap-target-min); display: inline-flex; align-items: center;
  /* min-width keeps a short word (“Today”, “Cancel”) a 44px-wide target. */
  min-width: var(--a11y-tap-target-min); justify-content: center;
}
/* Narrow screen: the primary button is full width and the quiet link under
   it is centred, as on the phone (price, pack, waiting for payment). */
@media (max-width: 560px) {
  .solo > .link-quiet, .btn + .link-quiet { display: flex; width: fit-content; margin-inline: auto; }
}
/* The keyboard hint is for those who have keys: on a phone “click a letter,
   or press the number keys” sounds like instructions for someone else's device. */
@media (hover: none) and (pointer: coarse) { .kbd-only { display: none; } }
/* A quiet link as a button: no browser border or fill. */
button.link-quiet { border: 0; background: none; padding: 0 10px; cursor: pointer; justify-content: center; }
button.link-quiet:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: var(--r-pill); }
.btn-hero-sm { font-size: 18px; padding: 16px 26px; border-radius: var(--r-card-md); }

/* Price (W08). The date timeline is dots on a vertical thread: today green, the
   charge day orange, the exam dark. Three events, not a table: a person reads
   them as a calendar, top to bottom. */
.tl {
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-sm); padding: 20px; margin-top: 20px; max-width: 520px;
}
.tl-row { display: flex; gap: 14px; }
.tl-rail { display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; }
.tl-dot { width: 16px; height: 16px; border-radius: var(--r-pill); box-shadow: 0 0 0 3px var(--paper-warm); }
.tl-dot.now { background: var(--pass); }
.tl-dot.pay { background: var(--accent); }
.tl-dot.exam { background: var(--ink); }
.tl-line { width: 2.5px; flex: 1; min-height: 32px; background: var(--line-strong); }
.tl-body { flex: 1; padding-bottom: 14px; }
.tl-row:last-child .tl-body { padding-bottom: 0; }
.tl-when { display: block; font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.tl-note { display: block; font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; margin-top: 2px; }
.lede { font-size: 16px; color: var(--ink-secondary); line-height: 1.55; margin-top: 14px; max-width: 460px; }

.plan-card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card); padding: 20px;
}
.plan-top { display: flex; align-items: baseline; justify-content: space-between; }
.plan-top .nm { font-family: var(--font-display); font-weight: 800; font-size: 22px; }
.plan-top .pr { font-family: var(--font-display); font-weight: 800; font-size: 34px; }
.plan-top .pr small { font-size: 15px; color: var(--ink-secondary); }
.checks { display: flex; flex-direction: column; gap: 11px; margin-top: 18px; }
.checks > div { display: flex; align-items: flex-start; gap: 10px; }
.checks .ck {
  width: 18px; height: 18px; flex: 0 0 auto; margin-top: 2px; border-radius: var(--r-pill);
  background: var(--pass); display: flex; align-items: center; justify-content: center;
}
.checks .ck svg { width: 11px; height: 11px; fill: none; stroke: var(--paper-card); stroke-width: 4; stroke-linecap: round; }
.checks .tx { flex: 1; font-size: 14.5px; line-height: 1.45; color: var(--ink-warm); }
.btn-full { width: 100%; font-size: 18px; padding: 17px; border-radius: var(--r-card-md); margin-top: 18px; }
.fee-card {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card-sm); padding: 18px; margin-top: 14px;
}
.fee-card .big { font-family: var(--font-display); font-weight: 800; font-size: 26px; flex: 0 0 auto; }
.fee-card .tx { flex: 1; font-size: 14.5px; line-height: 1.5; color: var(--ink-warm); }
.pad-top-4 { padding-top: 4px; }
.squiggle.w240 { width: 240px; }
.squiggle.w220 { width: 220px; }

/* ══ Task mode per the canvas (W02, W03) ═══════════════════════════════════ */

/* The task header is the same band as the site's, only inside: the cross, the
   title, the question ticks and a dark status patch. */
.prova-head {
  display: flex; align-items: center; gap: 16px;
  padding: 8px 26px; max-width: var(--web-max); margin: 0 auto;
  border: 0;
}
.prova-close {
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min); margin: 0 -6px;
  background: none; border: 0; display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none;
}
.prova-close > span {
  width: 32px; height: 32px; border-radius: var(--r-pill);
  background: var(--paper-card); border: 1.5px solid var(--line-strong);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; color: var(--ink-secondary);
}
.prova-title { font-family: var(--font-display); font-weight: 800; font-size: 18px; white-space: nowrap; }
.pstrip { flex: 1; display: flex; align-items: center; min-width: 0; overflow: hidden; }
/* One tick per question: done is dark, current is orange, ahead is the track. In
   the explanation, green and red replace dark: right and wrong. */
.pmarks { display: flex; align-items: center; gap: 6px; }
.pmarks i { width: 22px; height: 7px; border-radius: var(--r-pill); background: var(--track); flex: 0 0 auto; }
.pmarks i.done { background: var(--ink); }
.pmarks i.cur { background: var(--accent); }
.pmarks i.right { background: var(--pass); }
.pmarks i.wrong { background: var(--fail); }
.pmarks i.cur-review { background: var(--ink); }
.pill-dark {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  font-family: var(--font-display); font-weight: 800; font-size: 13px;
  color: var(--paper); background: var(--ink); padding: 7px 13px; border-radius: var(--r-pill);
}
.pill-dark .tiny { font-size: inherit; color: inherit; }
.pill-dark .dot { width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--accent); }
@media (max-width: 560px) { .pstrip { display: none; } .prova-head { gap: 10px; } }

/* Player: dark panel, remaining-time ring, a circle in the centre. */
.player {
  background: linear-gradient(170deg, var(--panel-from), var(--panel-to));
  box-shadow: var(--shadow-panel); border-radius: var(--r-panel);
  padding: 24px 20px 20px; text-align: center; color: var(--paper);
}
.player .pk { color: var(--panel-kicker); }
.player .ring { margin: 16px auto 0; }
.ring-bg { stroke: var(--panel-ring); }
.ring-mid { flex-direction: column; }
.play-disc {
  width: 72px; height: 72px; border-radius: var(--r-pill); background: var(--accent);
  border: 0; padding: 0; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 5px 0 var(--accent-ink); cursor: pointer;
}
.play-disc svg { width: 30px; height: 30px; fill: var(--paper-card); }
.play-disc.idle { cursor: default; }
.play-disc.sm { width: 48px; height: 48px; flex: 0 0 auto; box-shadow: var(--shadow-button); }
.play-disc.sm svg { width: 20px; height: 20px; }
.player .ring-num { font-family: var(--font-display); font-weight: 800; font-size: 28px; color: var(--paper); margin-top: 9px; }
.player-note { font-size: 14px; color: var(--ink-faint); line-height: 1.5; margin: 18px auto 0; max-width: 330px; }
.player-cta { display: block; font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--paper); margin-top: 14px; }
.player .btn { margin-top: 14px; }

/* Question and options. The selected one has a two-pixel dark border and a dark
   shadow: the canvas marks a choice with ink, not accent; the accent belongs to
   the action button. */
.q-stem { font-family: var(--font-display); font-weight: 800; font-size: 24px; line-height: 1.3; margin-top: 7px; }
.opts { display: flex; flex-direction: column; gap: 9px; margin-top: 14px; }
.opt {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: start;
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-input-sm); padding: 14px; box-shadow: 0 3px 0 var(--lip);
  font: inherit; color: var(--ink); cursor: pointer; min-height: var(--a11y-tap-target-min);
}
.opt .opt-key {
  font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary);
  width: 16px; height: auto; flex: 0 0 auto; background: none; border: 0; border-radius: 0;
}
.opt .opt-text { flex: 1; font-size: 16px; font-weight: 600; }
.opt-radio {
  width: 19px; height: 19px; flex: 0 0 auto; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1.5px var(--line-strong);
  display: flex; align-items: center; justify-content: center;
}
.opt-radio svg { width: 11px; height: 11px; fill: none; stroke: var(--paper-card); stroke-width: 4; stroke-linecap: round; }
.opt.on { border: 2px solid var(--ink); padding: 13px; box-shadow: 0 3px 0 var(--ink); }
.opt.on .opt-key { color: var(--ink); background: none; }
.opt.on .opt-text { font-weight: 700; }
.opt.on .opt-radio { background: var(--ink); box-shadow: none; }
div.opt { cursor: default; }
.opt.right { background: var(--pass-bg); border-color: var(--pass); box-shadow: none; }
.opt.right .opt-key { color: var(--pass-text); background: none; }
.opt.right .opt-radio { background: var(--pass); box-shadow: none; }
.opt.wrong { background: var(--fail-bg); border-color: var(--fail); box-shadow: none; }
.opt.wrong .opt-key { color: var(--fail-ink); background: none; }
.opt-mine { font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--fail-ink); }

/* State hint: a warm patch with an “i” icon. */
.callout {
  display: flex; align-items: center; gap: 10px;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-input); padding: 13px; margin-top: 14px;
  font-size: 13.5px; line-height: 1.45; color: var(--ink-warm);
}
.callout .ic { width: 17px; height: 17px; flex: 0 0 auto; fill: none; stroke: var(--ink-secondary); stroke-width: 2; stroke-linecap: round; }
.callout .ic .dotfill { fill: var(--ink-secondary); stroke: none; }

.act-row { display: flex; gap: 11px; margin-top: 16px; }
.btn-all {
  flex: 0 0 auto; background: var(--paper-card); color: var(--ink-secondary);
  border: 1.5px solid var(--line-strong); box-shadow: 0 3px 0 var(--lip);
  font-size: 16px; padding: 16px 20px; border-radius: var(--r-card-md);
}
.btn-go { flex: 1; font-size: 18px; padding: 16px; border-radius: var(--r-card-md); }
@media (max-width: 560px) { .act-row .btn-all { width: auto; } }
.all-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 8px; margin-top: 14px; }
.all-grid button {
  min-height: var(--a11y-tap-target-min); border-radius: var(--r-tile);
  border: 1.5px solid var(--line-strong); background: var(--paper-card); cursor: pointer;
  font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink-secondary);
}
.all-grid button.done { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.all-grid button.right { background: var(--pass-bg); border-color: var(--pass); color: var(--pass-text); }
.all-grid button.wrong { background: var(--fail-bg); border-color: var(--fail); color: var(--fail-ink); }
.all-grid button.cur { outline: 2.5px solid var(--accent); outline-offset: 1px; }

/* Explanation: the trap card and the dark replay bar inside it. */
.trap-card { padding: 20px; }
.trap-card .why { font-size: 16px; line-height: 1.55; margin-top: 10px; }
.replay {
  display: flex; align-items: center; gap: 13px; width: 100%; text-align: start;
  background: linear-gradient(170deg, var(--panel-from), var(--panel-to)); box-shadow: var(--shadow-panel);
  border: 0; border-radius: var(--r-card-md); padding: 12px 14px; margin-top: 16px;
  cursor: pointer; color: var(--paper); font: inherit;
}
.replay .rt { flex: 1; }
.replay .rt b { display: block; font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--paper); }
.replay .rt small { display: block; font-size: 13px; color: var(--ink-faint); margin-top: 2px; }
.situ { padding: 18px 20px; margin-top: 14px; }
.situ-text { font-size: 14px; line-height: 1.5; margin-top: 11px; }

/* Writing (W06): a title with a word-count patch, a warm task, a white sheet;
   on the right, the score large, the axes as rows and a warm notes card. */
.sc-title { display: flex; align-items: center; gap: 12px; }
.sc-h { font-family: var(--font-display); font-weight: 800; font-size: 22px; margin: 0; }
.pill-soft {
  font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary);
  background: var(--track); padding: 6px 11px; border-radius: var(--r-pill); white-space: nowrap;
}
.pill-soft.ok { color: var(--pass-text); background: var(--pass-bg); }
.task-box {
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-md); padding: 15px; margin-top: 14px;
}
.tb-text { font-size: 15px; line-height: 1.55; margin-top: 6px; color: var(--ink); }
.task-box .goals { margin: 6px 0 0; padding-inline-start: 20px; font-size: 15px; line-height: 1.55; }
.seg-themes { max-width: none; margin-top: 12px; background: var(--track); }
.seg-themes button {
  flex: 1; border: 0; background: none; cursor: pointer; font-family: var(--font-display); font-weight: 800;
  font-size: 14px; color: var(--ink-warm); padding: 10px 8px; border-radius: 12px; min-height: var(--a11y-tap-target-min);
}
.seg-themes button[aria-current="page"] { background: var(--paper-card); color: var(--ink); box-shadow: 0 2px 0 var(--line-strong); }
.letter-card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card);
  padding: 20px; margin-top: 14px; min-height: 260px;
}
.letter-card .letter {
  width: 100%; min-height: 220px; border: 0; outline: none; resize: vertical; background: none;
  font-family: var(--font-body); font-weight: 600; font-size: 16px; line-height: 1.7; color: var(--ink);
}
/* The field itself draws no outline (the card is the field), so the card shows
   where the keyboard is, like the search pill. */
.letter-card:focus-within { outline: 3px solid var(--accent); outline-offset: 2px; }
.score-card { text-align: center; }
.score-xl { font-family: var(--font-display); font-weight: 800; font-size: 44px; line-height: 1; margin-top: 6px; }
.score-xl small { font-size: 18px; color: var(--ink-secondary); }
.sc-note { font-size: 14px; color: var(--ink-secondary); line-height: 1.5; margin-top: 6px; }
.axes-card {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card); padding: 6px 18px 8px;
}
.axes-card .ax-head { margin-top: 12px; }
.axes-card .ax-lead { margin-bottom: 6px; }
.ax { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.ax + .ax { border-top: 1.5px solid var(--track); }
.ax-l { flex: 1; display: flex; align-items: baseline; gap: 8px; min-width: 0; flex-wrap: wrap; }
.ax-n { font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.ax-g { font-size: 12.5px; color: var(--ink-secondary); }
.ax-v { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink-secondary); white-space: nowrap; }
.ax-v.over { color: var(--pass-text); }
.ax-v.under { color: var(--fail-ink); }
.drop-card {
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-sm); padding: 18px; margin-top: 14px;
}
.dc-note { font-size: 14px; line-height: 1.5; margin-top: 9px; color: var(--ink-warm); }

/* Answer sheet (W13): a dark panel with the clock and an elapsed-time bar,
   bubbles six per row. Transferred is cream with a dark digit, current is warm
   in an orange ring, pending is empty in a thin ring. Filled always means
   “done”. */
.sheet-panel {
  background: linear-gradient(170deg, var(--panel-from), var(--panel-to)); box-shadow: var(--shadow-panel);
  border-radius: var(--r-card); padding: 22px; color: var(--paper);
}
.sp-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sheet-panel .pk { color: var(--panel-kicker); }
.sp-left { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--paper); }
.sp-left .dot { width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--fail); }
.sp-bar { height: 8px; border-radius: var(--r-pill); background: var(--panel-ring); margin-top: 12px; overflow: hidden; }
.sp-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--fail); }
.sp-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px; margin-top: 20px; }
/* Narrow phone: six bubbles per row, as on the answer sheet, but tighter. The
   answer-sheet row must not change: the person is learning exactly this layout. */
@media (max-width: 420px) { .sp-grid { gap: 6px; } .sheet-panel { padding: 18px 14px; } }
.bub {
  width: 100%; aspect-ratio: 1; min-height: var(--a11y-tap-target-min); border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0;
  font-family: var(--font-display); font-weight: 800; font-size: 18px;
}
.bub.done { background: var(--paper); border: 1.5px solid var(--paper); color: var(--ink); }
.bub.cur { background: var(--paper-warm); border: 2px solid var(--accent); color: var(--ink); }
.bub.pending { background: transparent; border: 1.5px solid var(--ink-secondary); color: var(--ink-faint); }
/* A closed sheet (full or out of time): the bubbles are a record, not controls. */
.bub.ro { cursor: default; }
.sp-note { max-width: none; margin: 16px 0 0; font-size: 13.5px; text-align: start; }
.sp-done { margin-top: 18px; padding-top: 16px; border-top: 1.5px solid var(--panel-ring); }
.sp-done .player-note { max-width: none; margin: 8px 0 0; text-align: start; }
.why-card { padding: 20px; }
.wc-text { font-size: 15px; line-height: 1.55; margin-top: 9px; }
.wc-text b { font-weight: 800; }
.cur-card { padding: 20px; }
.cc-top { display: flex; align-items: center; gap: 13px; }
.cc-n { font-family: var(--font-display); font-weight: 800; font-size: 24px; flex: 0 0 auto; width: 34px; text-align: center; }
.cc-t { flex: 1; font-size: 15px; line-height: 1.45; color: var(--ink-warm); }
.lets { display: flex; gap: 11px; margin-top: 13px; }
.let {
  flex: 1; text-align: center; cursor: pointer; font-family: var(--font-display); font-weight: 800; font-size: 18px;
  background: var(--paper-card); border: 1.5px solid var(--line); border-radius: var(--r-input-sm);
  padding: 14px; box-shadow: 0 3px 0 var(--lip); color: var(--ink); min-height: var(--a11y-tap-target-min);
}
.let:hover { background: var(--paper-warm); border-color: var(--accent); }


/* ==== Result, payment, waiting, rule, sittings, settings (W09–W12, W14, W15) ====

   Shared small bits: spacing, a note line, the card's large number. Sizes come
   from the canvas; colours and radii only via tokens. */
.mt-7 { margin-top: 7px; }
.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mt-18 { margin-top: 18px; }
.pad-20 { padding: 20px; }
.lede.sm { font-size: 15px; margin-top: 10px; max-width: 480px; }
.note-sm { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; margin-top: 10px; }
.note-sm.err { color: var(--fail-ink); }
.stat-big { font-family: var(--font-display); font-weight: 800; font-size: 28px; margin-top: 6px; line-height: 1.15; }
.card-big { font-family: var(--font-display); font-weight: 800; font-size: 24px; margin-top: 8px; line-height: 1.2; }
.meta.accent { color: var(--accent-ink); }
.body-warm { font-size: 14.5px; color: var(--ink-warm); line-height: 1.55; margin-top: 8px; }
.trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 18px; }
.trio > * { min-width: 0; }
@media (max-width: 700px) { .trio { grid-template-columns: minmax(0, 1fr); } }
.btn-row { display: flex; flex-wrap: wrap; gap: 11px; }
.btn-lg { font-size: 16px; padding: 15px 22px; border-radius: var(--r-card-md); }

/* W09: the win in three columns: mascot, words, a scoresheet on a warm patch. */
.win-grid.w3 { grid-template-columns: 200px minmax(0, 1fr) 280px; }
@media (max-width: 900px) { .win-grid.w3 { grid-template-columns: 200px minmax(0, 1fr); } .win-grid.w3 .score-panel { grid-column: 1 / -1; } }
@media (max-width: 700px) { .win-grid.w3 { grid-template-columns: minmax(0, 1fr); } }
.score-panel {
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-sm); padding: 8px 18px 10px; width: 100%;
}
.score-panel .grow + .grow { border-top-color: var(--track); }

/* W10: a “saved” mark in a green circle and the day plan as a list. */
.ok-ring {
  width: 56px; height: 56px; border-radius: var(--r-pill);
  background: var(--pass-bg); border: 1.5px solid var(--pass-border);
  display: inline-flex; align-items: center; justify-content: center;
}
.ok-ring svg { width: 24px; height: 24px; fill: none; stroke: var(--pass-text); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.money-card.wide { margin-top: 20px; max-width: 460px; }
.money-card.wide .date-tile { background: var(--paper-card); }
.plan-list { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.pl-row { display: flex; align-items: center; gap: 13px; }
.pl-when { width: 58px; flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); }
.pl-dot { width: 10px; height: 10px; flex: 0 0 auto; border-radius: var(--r-pill); background: var(--line-strong); }
.pl-dot.now { background: var(--accent); }
.pl-what { flex: 1; min-width: 0; font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.pl-note { font-size: 13px; color: var(--ink-secondary); text-align: end; }

/* W11: the waiting weeks as a bar and the sign-in details as pills. */
.wait-bar { display: flex; gap: 6px; margin-top: 14px; }
.wait-bar i { flex: 1; height: 9px; border-radius: var(--r-pill); background: var(--track); }
.wait-bar i.on { background: var(--ink); }
.pill-kv { display: flex; align-items: center; gap: 11px; margin-top: 11px; }
.pill-kv.sep { padding-top: 11px; border-top: 1.5px solid var(--track); }
.pill-kv .k { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.pill-kv .v {
  font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--ink-secondary);
  background: var(--track); padding: 7px 13px; border-radius: var(--r-pill);
}

/* W12: four columns and a dashed pass mark. Column height is the score out of
   twelve over one hundred forty points; the dashed line sits at seven twelfths. */
.rule-call {
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-sm); padding: 18px; margin-top: 20px; max-width: 470px;
}
.rule-call.fail { background: var(--fail-bg); border-color: var(--fail-border); }
.rule-call.fail .kicker { color: var(--fail-ink); }
.rule-call.ok { background: var(--pass-bg); border-color: var(--pass-border); }
.rule-call.ok .kicker { color: var(--pass-text); }
.rule-call .t { font-size: 15px; color: var(--ink-warm); line-height: 1.5; margin-top: 8px; }
.rchart {
  position: relative; height: 140px; display: flex; align-items: flex-end;
  justify-content: space-between; gap: 18px; padding: 0 6px;
}
.rb { flex: 1; max-width: 54px; border-radius: var(--r-bar-top) var(--r-bar-top) 0 0; min-height: 2px; }
.rb.over { background: var(--pass); }
.rb.under { background: var(--fail); }
.rline { position: absolute; left: 0; right: 0; border-top: 2.5px dashed var(--ink); }
.rlabels { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-top: 9px; padding: 0 6px; }
.rl { flex: 1; max-width: 54px; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.rn { font-family: var(--font-display); font-weight: 800; font-size: 13.5px; color: var(--ink-secondary); }
.rv { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.rv.under { color: var(--fail-ink); }
.rv small { font-size: 14px; color: var(--ink-secondary); }
.rlegend { display: flex; align-items: center; gap: 8px; margin-top: 13px; }
.rlegend .dash { width: 26px; border-top: 2.5px dashed var(--ink); }
.rlegend span:last-child {
  font-family: var(--font-display); font-weight: 800; font-size: 12px;
  letter-spacing: .06em; text-transform: uppercase;
}

/* W14: sittings as rows. The person's own has an ink border: it is a choice, not an option. */
.sit-list { display: flex; flex-direction: column; gap: 11px; margin-top: 18px; }
.sit-row {
  display: flex; align-items: center; gap: 14px;
  background: var(--paper-bar); border: 1.5px solid var(--line);
  border-radius: var(--r-card-md); padding: 15.5px; box-shadow: var(--shadow-card-sm);
}
.sit-row.chosen { background: var(--paper-card); border: 2px solid var(--ink); padding: 15px; box-shadow: 0 3px 0 var(--ink); }
.date-tile.lg { width: 52px; height: 52px; border-radius: var(--r-input-sm); }
.date-tile.lg b { font-size: 17px; }
.sit-body { flex: 1; min-width: 0; }
.sit-top { display: flex; align-items: baseline; flex-wrap: wrap; gap: 9px; }
.sit-name { font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.chip-yours {
  font-family: var(--font-display); font-weight: 800; font-size: 11.5px;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--pass-text); background: var(--pass-bg); border: 1.5px solid var(--pass-border);
  padding: 4px 9px; border-radius: var(--r-pill);
}
.sit-sub { display: block; font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; margin-top: 3px; }
.sit-meta { font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--ink-secondary); text-align: end; max-width: 150px; }
.sit-act {
  font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--accent-ink);
  background: none; border: 0; cursor: pointer; padding: 0 4px;
  min-height: var(--a11y-tap-target-min);
}
.day-list { display: flex; flex-direction: column; gap: 9px; margin-top: 14px; }
.day-row { display: flex; align-items: center; gap: 12px; }
.day-row + .day-row { padding-top: 9px; border-top: 1.5px solid var(--track); }
.day-row .dn { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.day-row .dm { font-size: 13px; color: var(--ink-secondary); }
.pill-row {
  display: flex; align-items: center; gap: 12px; margin-top: 13px;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-input-sm); padding: 12px 14px;
}
.pill-row .pn { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.pill-row .pv {
  font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--ink-secondary);
  background: var(--paper-card); border: 1.5px solid var(--line-strong); padding: 6px 11px; border-radius: var(--r-pill);
}

/* W15: settings as lists. A row with an arrow is a link; without an arrow it is
   just a value. Explanation language as pills: the selected one is dark. */
.set-list {
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-sm); box-shadow: var(--shadow-card); padding: 6px 20px 8px; margin-top: 8px;
}
.set-row {
  display: flex; align-items: center; gap: 12px; padding: 14px 0;
  color: inherit; text-decoration: none; min-height: var(--a11y-tap-target-min);
}
.set-row + .set-row { border-top: 1.5px solid var(--track); }
.sr-n { flex: 1; min-width: 0; font-family: var(--font-display); font-weight: 800; font-size: 16px; overflow-wrap: anywhere; }
.sr-v { font-size: 14.5px; color: var(--ink-secondary); text-align: end; }
.sr-go { font-size: 16px; color: var(--ink-tertiary); }
.set-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 20px; margin-top: 16px; }
.set-foot button { background: none; border: 0; padding: 0; cursor: pointer; }
.link-danger {
  font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--fail-ink); text-decoration: none;
  min-height: var(--a11y-tap-target-min); display: inline-flex; align-items: center;
}
.lang-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.lang-pill {
  font-family: var(--font-display); font-weight: 800; font-size: 14.5px; cursor: pointer;
  background: var(--paper-card); color: var(--ink); border: 1.5px solid var(--line-strong);
  padding: 9px 14px; border-radius: var(--r-pill); box-shadow: var(--shadow-card-sm);
  min-height: var(--a11y-tap-target-min);
}
.lang-pill.on { background: var(--ink); color: var(--paper); border-color: var(--ink); box-shadow: 0 3px 0 var(--ink); }
.note-card {
  display: flex; align-items: flex-start; gap: 12px; margin-top: 14px;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  border-radius: var(--r-card-md); padding: 16px;
}
.note-card .nk {
  flex: 0 0 auto; padding-top: 2px; font-family: var(--font-display); font-weight: 800; font-size: 12px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-secondary);
}
.note-card .nt { flex: 1; font-size: 14px; line-height: 1.5; color: var(--ink-warm); }


/* ==== Product entry per the canvas (M01–M07, M04): landing, three questions,
   score, goal, language, baseline, account. Same vocabulary as the W screens. ==== */
.land-koi { justify-content: flex-start; margin-bottom: 10px; }
.land-koi img { width: 150px; height: 150px; }
.proof-list { display: flex; flex-direction: column; gap: 11px; }
.proof-row {
  display: flex; align-items: center; gap: 16px;
  background: var(--paper-card); border: 1.5px solid var(--line);
  border-radius: var(--r-card-md); box-shadow: var(--shadow-card-sm); padding: 16px 18px;
}
.proof-num { flex: 0 0 auto; min-width: 44px; font-family: var(--font-display); font-weight: 800; font-size: 26px; color: var(--accent-ink); }
.proof-tx { flex: 1; font-size: 14.5px; line-height: 1.45; color: var(--ink-warm); }
.step-dots { display: inline-flex; gap: 6px; }
.step-dots i { width: 22px; height: 6px; border-radius: var(--r-pill); background: var(--track); }
.step-dots i.on { background: var(--ink); }
.step-dots i.now { background: var(--accent); }
.vf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
.opt.vf { justify-content: flex-start; }
.note-sm.center { text-align: center; margin-top: 12px; }
.score-hero { display: flex; align-items: baseline; gap: 6px; margin: 6px 0 4px; }
.score-hero b { font-family: var(--font-display); font-weight: 800; font-size: 56px; line-height: 1; }
.score-hero span { font-family: var(--font-display); font-weight: 800; font-size: 20px; color: var(--ink-secondary); }
.gmark.none { background: var(--paper-warm); box-shadow: inset 0 0 0 2px var(--line-strong); }
.gmark.none i { width: 6px; height: 2.5px; border-radius: var(--r-pill); background: var(--ink-tertiary); }
.gnum.none { color: var(--ink-secondary); }
.gnum.over { color: var(--pass-text); }
.pick-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 4px; }
.pick {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: start; cursor: pointer;
  background: var(--paper-card); border: 1.5px solid var(--line); color: var(--ink);
  border-radius: var(--r-card-md); box-shadow: var(--shadow-card-sm); padding: 15px 16px;
  font: inherit; min-height: var(--a11y-tap-target-min);
}
.pick.on { border: 2px solid var(--ink); padding: 14px 15px; box-shadow: 0 3px 0 var(--ink); }
.pk-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.pk-t b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.pk-t span { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.4; }
.pk-r {
  width: 24px; height: 24px; flex: 0 0 auto; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 2px var(--line-strong); display: inline-flex; align-items: center; justify-content: center;
}
.pick.on .pk-r, .lang-row.on .pk-r { background: var(--ink); box-shadow: none; }
.pk-r svg { width: 12px; height: 12px; fill: none; stroke: var(--paper-card); stroke-width: 4; stroke-linecap: round; }
.card-22.warm { background: var(--paper-warm); border-color: var(--line-strong); box-shadow: none; }
.lang-list { padding: 4px 20px 6px; margin-top: 0; }
.lang-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: start; cursor: pointer;
  background: none; border: 0; color: var(--ink); font: inherit; padding: 12px 0;
  min-height: var(--a11y-tap-target-min);
}
.lang-row + .lang-row { border-top: 1.5px solid var(--track); }
.lr-t { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.lr-t b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.lr-t span { font-size: 13px; color: var(--ink-secondary); }
.form-card { display: flex; flex-direction: column; gap: 8px; }
.f-label { font-family: var(--font-display); font-weight: 800; font-size: 13.5px; color: var(--ink-secondary); margin-top: 4px; }
ul.dots { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
ul.dots li { position: relative; padding-inline-start: 16px; font-size: 14.5px; line-height: 1.5; color: var(--ink-warm); }
ul.dots li::before {
  content: ''; position: absolute; inset-inline-start: 0; top: .6em;
  width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--accent);
}


/* ==== State screens per the canvas (M12, M14, M15, M28, M37, M39, M41–M43,
   M45–M47): same vocabulary: chip or kicker, title, lead, cards. ==== */
.land-koi { display: inline-flex; width: 170px; }
.solo { max-width: 560px; }
.solo .koi-sm { align-self: flex-start; display: block; margin-bottom: 8px; }
.chip-state {
  display: inline-flex; align-items: center;
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px;
  letter-spacing: .06em; text-transform: uppercase; padding: 7px 13px; border-radius: var(--r-pill);
  margin-bottom: 6px;
}
.chip-state.ok { color: var(--pass-text); background: var(--pass-bg); border: 1.5px solid var(--pass-border); }
.chip-state.bad { color: var(--fail-ink); background: var(--fail-bg); border: 1.5px solid var(--fail-border); }
.chip-state.soft { color: var(--ink-secondary); background: var(--track); border: 1.5px solid var(--line-strong); }
.seg-bar { display: flex; gap: 6px; }
.seg-bar i { flex: 1; height: 8px; border-radius: var(--r-pill); background: var(--track); }
.seg-bar i.ok { background: var(--pass); }
.seg-bar i.bad { background: var(--fail); }
.seg-bar i.now { background: var(--accent); }
.acc-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; margin-top: 14px; }
.acc-opt {
  font-family: var(--font-display); font-weight: 800; font-size: 26px; cursor: pointer; color: var(--ink);
  background: var(--paper-card); border: 1.5px solid var(--line-strong); border-radius: var(--r-card-md);
  box-shadow: var(--shadow-card-sm); padding: 18px 12px; min-height: var(--a11y-tap-target-min);
}
.acc-opt:disabled { cursor: default; }
.acc-opt.ok { background: var(--pass-bg); border: 2px solid var(--pass); color: var(--pass-text); }
.acc-opt.bad { background: var(--fail-bg); border: 2px solid var(--fail); color: var(--fail-ink); }
.verdict { border-radius: var(--r-card-md); padding: 16px 18px; margin-top: 14px; border: 1.5px solid; }
.verdict.ok { background: var(--pass-bg); border-color: var(--pass-border); }
.verdict.ok .kicker { color: var(--pass-text); }
.verdict.bad { background: var(--fail-bg); border-color: var(--fail-border); }
.verdict.bad .kicker { color: var(--fail-ink); }
.verdict .t { font-size: 15px; line-height: 1.5; color: var(--ink-warm); margin-top: 6px; }
.sum-row { display: flex; align-items: center; gap: 14px; padding: 4px 0 12px; }
.sum-row.sep { border-top: 1.5px solid var(--track); padding-top: 14px; }
.sum-row .sum { flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 24px; }
.sum-row .sum.lg { font-size: 30px; margin-inline-start: auto; }
.sum-row .tx { flex: 1; font-size: 14.5px; line-height: 1.5; color: var(--ink-warm); }
.sum-row .tx.strong { font-family: var(--font-display); font-weight: 800; font-size: 18px; color: var(--ink); }
.word-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.word-pills span {
  font-family: var(--font-display); font-weight: 800; font-size: 15px;
  background: var(--paper-card); border: 1.5px solid var(--line-strong); border-radius: var(--r-pill);
  padding: 9px 15px; box-shadow: var(--shadow-card-sm);
}
.kv2 { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; }
.kv2.sep { border-top: 1.5px solid var(--track); }
.kv2 .k { font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.kv2 .v { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink-secondary); text-align: end; }
.dark-card {
  background: linear-gradient(170deg, var(--panel-from), var(--panel-to));
  color: var(--paper); border-radius: var(--r-panel); padding: 26px; box-shadow: var(--shadow-panel);
  text-align: center;
}
.dc-ic {
  width: 58px; height: 58px; border-radius: var(--r-pill); background: var(--panel-ring);
  display: inline-flex; align-items: center; justify-content: center;
}
.dc-ic svg { width: 26px; height: 26px; fill: none; stroke: var(--paper); stroke-width: 2; stroke-linecap: round; }
.dc-k { font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--panel-kicker); margin-top: 14px; }
.dc-t { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 1.2; margin-top: 6px; }
.dc-l { font-size: 14.5px; line-height: 1.5; opacity: .8; margin-top: 8px; }
.pill-st {
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px; padding: 5px 11px; border-radius: var(--r-pill);
}
.pill-st.ok { color: var(--pass-text); background: var(--pass-bg); border: 1.5px solid var(--pass-border); }
.pill-st.no { color: var(--ink-secondary); background: var(--track); }
.choice {
  display: flex; flex-direction: column; gap: 5px; width: 100%; text-align: start; cursor: pointer;
  background: var(--paper-card); color: var(--ink); text-decoration: none; font: inherit;
  border: 1.5px solid var(--line); border-radius: var(--r-card-md); box-shadow: var(--shadow-card-sm);
  padding: 15px 16px; margin-top: 11px;
}
.choice.on { background: var(--paper-warm); border: 2px solid var(--ink); padding: 14px 15px; box-shadow: 0 3px 0 var(--ink); }
.choice b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.choice span { font-size: 14px; line-height: 1.45; color: var(--ink-warm); }
.ic-ring {
  width: 56px; height: 56px; border-radius: var(--r-pill); margin-bottom: 12px;
  background: var(--paper-warm); border: 1.5px solid var(--line-strong);
  display: inline-flex; align-items: center; justify-content: center;
}
.ic-ring svg { width: 24px; height: 24px; fill: none; stroke: var(--accent-ink); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ax-list { margin-top: 10px; }
.ax-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; }
.ax-row + .ax-row { border-top: 1.5px solid var(--track); }
.ax-row .an { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.ax-row .ag { flex: 1; min-width: 0; font-size: 12.5px; color: var(--ink-secondary); }
.ax-row .bar-sm { width: 70px; }
.ax-row .av { width: 44px; text-align: end; font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.card-22.dashed { border-style: dashed; border-color: var(--line-strong); box-shadow: none; background: var(--paper-bar); }
.tg-row { display: flex; align-items: center; gap: 14px; padding: 14px 0; }
.tg-row + .tg-row { border-top: 1.5px solid var(--track); }
.tg-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tg-t b { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.tg-t span { font-size: 13px; line-height: 1.4; color: var(--ink-secondary); }
.switch {
  position: relative; width: 56px; height: var(--a11y-tap-target-min); flex: 0 0 auto; cursor: pointer;
  border: 0; background: none; padding: 0;
}
.switch::before {
  content: ''; position: absolute; inset-inline: 2px; top: 6px; height: 32px;
  border-radius: var(--r-pill); background: var(--line-strong);
}
.switch i {
  position: absolute; top: 9px; inset-inline-start: 5px; width: 26px; height: 26px;
  border-radius: var(--r-pill); background: var(--paper-card); transition: inset-inline-start var(--motion-base);
}
.switch.on::before { background: var(--pass); }
.switch.on i { inset-inline-start: 25px; }
.switch:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.note-card .nk svg { width: 16px; height: 16px; fill: none; stroke: var(--ink-secondary); stroke-width: 2; stroke-linecap: round; }


/* ==== Full run (M24–M26) ==== */
.tl2 { position: relative; margin-top: 12px; display: flex; flex-direction: column; gap: 14px; }
.tl2-row { display: flex; align-items: center; gap: 12px; }
.tl2-at { width: 40px; flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); }
.tl2-dot { width: 10px; height: 10px; flex: 0 0 auto; border-radius: var(--r-pill); background: var(--ink); }
.tl2-b b { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.tl2-b span { font-size: 13px; color: var(--ink-secondary); margin-inline-start: 6px; }
.pill-st.now { color: var(--accent-ink); background: var(--paper-warm); border: 1.5px solid var(--line-strong); }
.gtag { font-size: 12.5px; color: var(--ink-secondary); margin-inline-end: 4px; }
.prova-body .solo { margin: 0 auto; }


/* ══════════════════════════════════════════════════════════════════════════
   DESIGN v3 is the only one in force (design/README.md, design/handoff-v3/).

   Everything below is the v3 material and details: warm paper with two light
   spots, light glass on cards, dark glass on the main thing, pill buttons, a
   flask in place of the gate bar. The block sits after the canvas sections on
   purpose: it overrides their rules at equal specificity, including the
   material of the older card classes. When no screen emits an older class,
   delete its rule rather than override it again.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---- background: paper and two light spots -------------------------------- */
body { background: var(--paper); min-height: 100vh; }
body::before, body::after {
  content: ''; position: fixed; z-index: -1; pointer-events: none; border-radius: 50%;
}
body::before {
  inset-inline-end: -160px; top: -80px; width: 680px; height: 680px;
  background: radial-gradient(circle, var(--tint-blob-teal), transparent 64%);
}
body::after {
  inset-inline-start: -180px; bottom: -200px; width: 620px; height: 620px;
  background: radial-gradient(circle, var(--tint-blob-warm), transparent 64%);
}
/* The browser's own rubber band past the top and bottom of the page (Max,
   2026-09-28: a fast scroll on a short page stopped dead against the edge).
   The gap it opens shows the canvas, which is the body's paper (see below);
   the glow layers are fixed and stay put. */
html, body { overscroll-behavior-y: auto; }
/* ⚠️ No background on <html>: the body's paper must propagate to the canvas.
   With a colour on <html>, the body paints its own paper box over the two
   glow layers (z-index -1) and the page turns flat. */
body.dark { background: var(--screen-dark); color: var(--paper-card); }
body.dark::before { background: radial-gradient(circle, var(--tint-blob-teal-dark), transparent 64%); }
body.dark::after { background: radial-gradient(circle, var(--tint-blob-warm-dark), transparent 64%); }

/* ---- icon ------------------------------------------------------------------ */
.ic {
  width: 20px; height: 20px; flex: 0 0 auto; display: block;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* ---- glass ----------------------------------------------------------------- */
/* Light glass, the material of every card: the v3 .glass class and the older
   card classes get it here in one list, so a screen built on older classes
   looks v3 too. */
.glass, .card, .hero-card, .mini-card, .gates-card, .gates-rows, .card-22, .pcard,
.win-card, .plan-card, .fee-card, .set-list, .axes-card, .letter-card, .proof-row,
.money-card, .warm-row, .tl, .rule-call, .next-bar, .note-card, .drop-card, .task-box,
.callout, .score-panel, .sit-row, .choice, .pick, .win-stats > div {
  background: var(--glass-light);
  -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
  border: 1px solid var(--glass-light-border);
  box-shadow: var(--glass-light-shadow);
}
.glass, .card, .hero-card, .gates-card, .gates-rows, .card-22, .pcard, .win-card,
.plan-card, .set-list, .axes-card, .letter-card { border-radius: var(--r-card); }
.mini-card, .money-card, .warm-row, .tl, .rule-call, .next-bar, .note-card, .drop-card,
.fee-card, .score-panel, .proof-row, .sit-row, .choice, .pick, .callout, .task-box {
  border-radius: var(--r-card-sm);
}
/* Glass inside glass only as a tile: a second blur layer over the first turns
   murky and drops text contrast below the threshold. */
.card-inset, .glass .glass, .card .card-inset {
  background: var(--tint-empty-tube); border: 1px solid var(--line);
  box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
  border-radius: var(--r-input);
}
/* Below the line the card does not turn red as a whole: v3 marks a part below the
   line with the flask and the number, and the card stays glass. */
.pcard.under { box-shadow: var(--glass-light-shadow); }
.rule-call.fail, .verdict.bad { background: var(--fail-bg); border: 1px solid var(--tint-no-line); }
.rule-call.ok, .verdict.ok { background: var(--pass-bg); border: 1px solid var(--tint-ok-line); }

/* Dark glass: the one main thing on a screen: the evening task, the selected item,
   the guarantee, the player. */
.dglass, .panel, .dark-card, .sheet-panel, .player, .replay {
  background: var(--glass-dark);
  -webkit-backdrop-filter: var(--glass-dark-blur); backdrop-filter: var(--glass-dark-blur);
  border: 1px solid var(--glass-dark-border);
  box-shadow: var(--glass-dark-shadow);
  color: var(--paper-card);
  border-radius: var(--r-panel);
}
.dglass .muted, .panel .muted, .dark-card .dc-l { color: var(--tint-on-dark); opacity: 1; }

/* ---- buttons: pills -------------------------------------------------------- */
.btn {
  border-radius: var(--r-pill); padding: 13px 20px; font-size: var(--fs-body);
  white-space: nowrap;
}
.btn-primary {
  background: linear-gradient(180deg, var(--accent-from), var(--accent-to));
  color: var(--paper-card); box-shadow: var(--shadow-button); border: 0;
}
.btn-primary:active { box-shadow: var(--shadow-button); }
/* The secondary action is quiet: a glass pill. */
.btn-quiet, .btn-warm, .btn-all, .lang-pill, .word-pills span {
  background: var(--glass-pill);
  -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
  color: var(--ink);
}
.btn-dark, .lang-pill.on { background: var(--ink); color: var(--paper-card); border: 1px solid var(--ink); box-shadow: none; }
.btn-ghost { background: transparent; color: var(--ink); border: 1.5px solid var(--line); box-shadow: none; }
.btn-danger { background: var(--fail-bg); color: var(--fail-ink); border: 1px solid var(--tint-no-line); box-shadow: none; }
/* A white pill on dark glass: “Start prova” on the task card. */
.btn-white { background: var(--paper-card); color: var(--ink); border: 0; box-shadow: var(--shadow-card-sm); }
/* A disabled button is a beige patch with muted text, not a translucent copy of
   the primary: translucent orange reads as “press me”. */
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--line); color: var(--ink-secondary); box-shadow: none; border-color: var(--line);
  opacity: 1;
}
.btn-big, .btn-hero, .btn-full, .btn-go, .btn-hero-sm { font-size: 18px; padding: 17px 26px; border-radius: var(--r-pill); }
.btn-block, .btn-wide, .btn-card, .btn-full { width: 100%; border-radius: var(--r-pill); }
.btn .ic { width: 18px; height: 18px; }
/* Round icon button: “back”, cross, bell. The visible circle is forty, the tap
   target forty-four. */
.icon-btn {
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min); flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: none; padding: 0; color: var(--ink); cursor: pointer; text-decoration: none;
}
.icon-btn > span {
  width: 40px; height: 40px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--glass-pill);
  -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
}
.icon-btn .ic { width: 18px; height: 18px; }
/* A “back” button opening a row puts its visible circle, not the wider tap box,
   on the column edge, in line with the title under it. */
.onb-top > .icon-btn:first-child { margin-inline-start: -2px; }
.on-dark .icon-btn > span, .dglass .icon-btn > span {
  background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); box-shadow: none;
  color: var(--paper-card);
}

/* ---- pills and tags -------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px; line-height: 1.2;
  color: var(--ink); padding: 6px 12px; border-radius: var(--r-pill);
  background: var(--glass-pill);
  -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
  text-decoration: none;
}
.pill .ic { width: 14px; height: 14px; }
.pill-dark, .pill.pill-dark {
  background: var(--glass-dark); border: 1px solid var(--glass-dark-border);
  box-shadow: none; color: var(--paper-card);
}
.pill-short { background: var(--fail-ink); color: var(--paper-card); border: 0; box-shadow: none; }
.pill-over { background: var(--pass-bg); color: var(--pass-text); border: 0; box-shadow: none; }
.pill-guarantee { background: var(--ink); color: var(--paper-card); border: 0; box-shadow: none; }
.pill-trap {
  background: var(--fail-ink); color: var(--paper-card); border: 0; box-shadow: none;
  font-size: 17px; padding: 8px 16px; border-radius: var(--r-tile);
}
/* A caps tag inside a pill: “SHORT”, “PASSES”, “FULL”. */
.pill-caps { font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; padding: 4px 10px; }

/* ---- segment ----------------------------------------------------------------- */
.seg {
  display: inline-flex; gap: 2px; padding: 4px; max-width: none; margin-top: 14px;
  border-radius: var(--r-pill);
  background: var(--glass-pill);
  -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
}
.seg a, .seg span, .seg button {
  flex: 1; border-radius: var(--r-pill); padding: 10px 22px; color: var(--ink-secondary);
  background: none; border: 0; box-shadow: none;
}
/* A segment you press is a full finger target (a11y.tap-target-min). */
.seg button { min-height: var(--a11y-tap-target-min); }
.seg [aria-current="page"] { background: var(--ink); color: var(--paper-card); box-shadow: none; }
.seg-themes { background: var(--glass-pill); }
.seg-themes { flex-wrap: wrap; max-width: 100%; border-radius: var(--r-card-sm); }
/* A topic is a two- or three-word name: on one line, and if two topics do not fit
   side by side, the second goes under the first rather than breaking mid-word. */
.seg-themes button { border-radius: var(--r-pill); white-space: nowrap; flex: 1 1 auto; }
.seg-themes button[aria-current="page"] { background: var(--ink); color: var(--paper-card); box-shadow: none; }

/* ---- toggle: forty-eight by twenty-eight, teal when on ------------------------ */
.switch { width: 52px; }
.switch::before { top: 8px; height: 28px; inset-inline: 2px; background: var(--line-strong); }
.switch i { top: 11px; width: 22px; height: 22px; inset-inline-start: 5px; }
.switch.on::before { background: var(--pass); }
.switch.on i { inset-inline-start: 25px; }

/* ---- list row: icon in a teal tile, label, value, chevron --------------------- */
.lrows { display: flex; flex-direction: column; }
.lrow {
  display: flex; align-items: center; gap: 12px; padding: 12px 0; min-height: var(--a11y-tap-target-min);
  color: inherit; text-decoration: none; background: none; border: 0; width: 100%; text-align: start;
  font: inherit; cursor: pointer;
}
div.lrow { cursor: default; }
.lrow + .lrow { border-top: 1px solid var(--line); }
.lrow-ic {
  width: 34px; height: 34px; flex: 0 0 auto; border-radius: var(--r-tile);
  background: var(--tint-teal-tile); color: var(--pass-text);
  display: inline-flex; align-items: center; justify-content: center;
}
.lrow-ic .ic { width: 17px; height: 17px; }
.lrow-t { flex: 1; min-width: 0; font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.lrow-t small { display: block; font-family: var(--font-body); font-weight: 600; font-size: 13px; color: var(--ink-secondary); margin-top: 1px; }
.lrow-v { font-size: 14px; color: var(--ink-secondary); white-space: nowrap; }
.lrow-go { color: var(--ink-secondary); }
.lrow-go .ic { width: 16px; height: 16px; }
.lrow.danger .lrow-t { color: var(--fail-ink); }
.lrow.danger .lrow-ic { background: var(--fail-bg); color: var(--fail-ink); }

/* ---- state icon in a circle (state screens) ----------------------------------- */
/* v3: a 96 glass disc with a 40 icon, a soft halo out to 116 around it and a thin
   ring at 148. Three tones: teal (default), alarm (`warm`) and money with the
   guarantee (`accent`). The ring is an outline with an offset: it follows the rounding. */
.state-ic {
  width: 96px; height: 96px; border-radius: var(--r-pill); flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border);
  box-shadow: 0 0 0 10px var(--tint-state-halo), var(--glass-light-shadow);
  outline: 1px solid var(--tint-state-ring); outline-offset: 25px;
  margin: 26px;
  color: var(--pass-text);
}
.state-ic .ic { width: 40px; height: 40px; }
.state-ic.warm { color: var(--fail-ink); box-shadow: 0 0 0 10px var(--tint-state-halo-warm), var(--glass-light-shadow); outline-color: var(--tint-state-ring-warm); }
.state-ic.accent { color: var(--accent-ink); box-shadow: 0 0 0 10px var(--tint-state-halo-accent), var(--glass-light-shadow); outline-color: var(--tint-state-ring-accent); }
.state-ic.ink { color: var(--ink); }

/* ---- v3 headings -------------------------------------------------------------- */
.kicker { font-size: 12px; letter-spacing: .1em; }
.display { letter-spacing: -.03em; line-height: 1.03; text-wrap: balance; }
.lede, .lead-p { font-size: 16px; line-height: 1.55; color: var(--ink-secondary); text-wrap: pretty; }
/* The hand-drawn line under a heading is a detail of the previous canvas; v3 has none. */
.squiggle { display: none; }

/* ---- answer option ------------------------------------------------------------- */
.opt {
  gap: 12px; padding: 16px; border-radius: var(--r-answer);
  background: var(--glass-light);
  -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
  border: 1px solid var(--glass-light-border); box-shadow: var(--glass-pill-shadow);
}
.opt .opt-key { width: 14px; font-size: 13px; color: var(--ink-secondary); }
.opt .opt-text { font-weight: 700; }
.opt .opt-radio { box-shadow: none; background: none; }
.opt .opt-radio svg { display: none; }
.opt.on { background: var(--ink); border: 1px solid var(--ink); padding: 16px; color: var(--paper-card); box-shadow: none; }
.opt.on .opt-key { color: var(--ink-faint); }
.opt.on .opt-radio { background: none; }
.opt.on .opt-radio svg { display: block; stroke: var(--paper-card); width: 18px; height: 18px; stroke-width: 2.4; }
.opt.right { background: var(--pass-bg); border: 1px solid var(--tint-ok-line); box-shadow: none; color: var(--ink); }
.opt.right .opt-key, .opt.right .opt-tick { color: var(--pass-text); }
.opt.right .opt-radio { background: none; }
.opt.wrong { background: var(--fail-bg); border: 1px solid var(--tint-no-line); box-shadow: none; color: var(--ink); }
.opt.wrong .opt-key, .opt-mine { color: var(--fail-ink); }
/* Options on a dark screen (listening): the same glass, dark. */
.on-dark .opt:not(.on):not(.right):not(.wrong) {
  background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); color: var(--paper-card); box-shadow: none;
}
.on-dark .opt.on { background: var(--paper-card); color: var(--ink); border-color: var(--paper-card); }
.on-dark .opt.on .opt-radio svg { stroke: var(--ink); }

/* ---- flask ----------------------------------------------------------------------

   The flask per design/handoff-v3/Tube final.dc.html: a tall test tube, not a
   squat jar. The gap between slots follows the count (sheet C2): 16 for three
   flasks (.n3), 12 by default, 8 for five (.n5). Inside its slot the flask has
   its own size: 58 × 150 by default, .sz-sm 30 × 70, .sz-xl 62 × 170; from
   561px .sz-lg 72 × 230 and .sz-xl 76 × 300. When five do not fit, the flask
   narrows to its slot and keeps its height. */
.tanks {
  --gap: 12px; --w: 58px; --h: 150px; --num: 24px;
  display: flex; gap: var(--gap); padding-inline-end: 8px; align-items: stretch;
}
.tanks.n3 { --gap: 16px; }
.tanks.n5 { --gap: 8px; }
.tanks.sz-sm { --w: 30px; --h: 70px; --num: 15px; --rise-k: .68; }
.tanks.sz-xl { --w: 62px; --h: 170px; --num: 26px; --rise-k: 1.06; }
@media (min-width: 561px) {
  .tanks.sz-lg { --w: 72px; --h: 230px; --num: 30px; --rise-k: 1.24; }
  .tanks.sz-xl { --w: 76px; --h: 300px; --num: 32px; --rise-k: 1.41; }
}
.tk { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; }
.tk-num {
  font-family: var(--font-display); font-weight: 800; font-size: var(--num); line-height: 1; white-space: nowrap;
  color: var(--ink); margin-bottom: 10px; font-variant-numeric: tabular-nums;
}
.tk-num small { font-size: calc(var(--num) / 2); color: var(--pass-text); }
/* The estimate “5–7” is smaller than a single number (A04: 16 versus 24). */
.tk.est .tk-num { font-size: calc(var(--num) * 2 / 3); line-height: 1.5; }
.tk.warm .tk-num { color: var(--fail-ink); }
.tk.none .tk-num, .tk.mic .tk-num { color: var(--ink-secondary); }
.tanks.sz-sm .tk-num { margin-bottom: 8px; }
/* Room for the side marker is always kept: 14 px from the slot. */
/* The flask is a size container: its waves, bubbles and sway are drawn in `cqw`, fractions
   of its own width, so a small flask has small bubbles and a narrowed one keeps them in
   proportion (the numbers below are the 58 px flask's, divided by 58). */
.tk-body { position: relative; width: min(var(--w), calc(100% - 14px)); height: var(--h); flex: none; container-type: size; }
.tk-tube {
  position: absolute; inset: 0; border-radius: var(--r-pill); overflow: hidden; isolation: isolate;
  background: var(--glass-tank); border: 1.5px solid var(--glass-tank-border);
}
.tk.short .tk-tube { border: 2px solid var(--fail); }
/* Half measured (one of two prove done): under the line but not short yet,
   so the rim stays neutral (kit.js tank, B-10). */
.tk.short.part .tk-tube { border: 1.5px solid var(--glass-tank-border); }
.tk.none .tk-tube, .tk.mic .tk-tube { background: var(--tint-empty-tube); border: 1.5px dashed var(--ink-faint); }
/* Water: the column extends 4 px below the bottom so the sway does not lift it off. */
.tk-water {
  position: absolute; left: 0; right: 0; bottom: -4px; height: calc(var(--lvl) + 4px); z-index: -1;
  background: linear-gradient(180deg, var(--water-pass-top), var(--water-pass-mid) 42%, var(--water-pass-deep));
}
.tk.warm .tk-water, .tk-water.warm {
  background: linear-gradient(180deg, var(--water-short-top), var(--water-short-mid) 42%, var(--water-short-deep));
}
.tk.full .tk-water {
  background: linear-gradient(180deg, var(--water-full-top), var(--water-full-mid) 42%, var(--water-full-deep));
}
.tk.full .tk-tube { border-color: var(--tint-full-rim); }
/* Two wave layers: the near one 7 px, the far one 9 px and half transparent. */
.tk-wave { position: absolute; left: 0; right: 0; overflow: hidden; }
.tk-wave.wf { top: -6px; height: 7px; }
.tk-wave.wb { top: -8px; height: 9px; opacity: .5; }
/* In a flask the waves scale with it (cqw of the flask, see .tk-body); the full-width water
   of the players keeps the fixed 7 and 9 px, since it is not inside a flask. */
.tk-body .tk-wave.wf { top: -10.3cqw; height: 12.1cqw; }
.tk-body .tk-wave.wb { top: -13.8cqw; height: 15.5cqw; }
.tk-wave svg { display: block; width: 200%; height: 100%; fill: var(--water-pass-top); }
.tk.warm .tk-wave svg, .tk-water.warm .tk-wave svg { fill: var(--water-short-top); }
/* Below the line the wave is lower and the water does not sway upwards: its crest
   does not reach the marker, and a “6” sits exactly at its own sixth. */
.tk.short .tk-wave { transform: scaleY(.45); transform-origin: bottom; }
.tk-surf {
  position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, transparent, var(--tint-surface), transparent);
}
.tk-sheen { position: absolute; inset: 0; background: linear-gradient(180deg, var(--tint-sheen), transparent 38%); }
/* A bubble is a full-height column of the water with the circle at its foot:
   rising is then a transform of the column by its own height (the water's),
   drawn by the compositor, not an animated `bottom` that relays the page out
   on every frame. */
.tk-bub { position: absolute; top: 0; bottom: 0; opacity: 0; pointer-events: none; }
.tk-bub > i {
  position: absolute; left: 0; bottom: 0; width: 100%; aspect-ratio: 1;
  display: block; border-radius: 50%;
  border: 1px solid var(--tint-bubble); box-shadow: 0 0 3px var(--tint-bubble-glow);
  background: radial-gradient(circle at 32% 30%, var(--tint-bubble-core) 0 16%, var(--tint-bubble-mid) 28%, var(--tint-bubble-edge) 72%);
}
.tk-bub.b1 { left: 40.5%; width: 9.3cqw; }
.tk-bub.b2 { left: 42.6%; width: 11cqw; }
.tk-bub.b3 { left: 15.4%; width: 9cqw; }
.tk-bub.b4 { left: 53.9%; width: 5.3cqw; }
.tk-bub.b5 { left: 80.5%; width: 6.4cqw; }
.tk-range {
  position: absolute; left: 0; right: 0; bottom: var(--lo); height: calc(var(--hi) - var(--lo)); z-index: -1;
  background: var(--tint-range-teal);
}
.tk.warm .tk-range { background: var(--tint-range-warm); }
.tk-groove {
  position: absolute; left: 9%; width: 82%; bottom: calc(var(--line) - 5px); height: 12px;
  overflow: visible; z-index: 3;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--ink) 22%, var(--ink) 78%, transparent);
  mask-image: linear-gradient(90deg, transparent, var(--ink) 22%, var(--ink) 78%, transparent);
}
.tk-groove path { fill: none; stroke-width: 2.4; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.tk-groove .sh { stroke: var(--tint-groove-shadow); transform: translateY(1.4px); }
.tk-groove .hl { stroke: var(--tint-groove); }
.tk-glint {
  position: absolute; left: 18%; top: 9%; bottom: 9%; width: 3px; border-radius: var(--r-pill); z-index: 4;
  background: linear-gradient(180deg, var(--tint-glint), transparent);
}
.tk.none .tk-glint, .tk.mic .tk-glint { display: none; }
.tk-sweep {
  position: absolute; top: 0; bottom: 0; left: 0; width: 40%;
  background: linear-gradient(90deg, transparent, var(--tint-sweep), transparent);
  transform: translateX(-160%) skewX(-16deg);
}
.tk-mic { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--ink-secondary); }
.tk-mic .ic { width: 16px; height: 16px; }
/* The side marker: a triangle at the line, to the right of the flask. Only on
   measured flasks: on an empty flask the line says nothing. */
.tk-notch {
  position: absolute; inset-inline-start: calc(100% + 2px); bottom: var(--line); transform: translateY(50%);
  width: 0; height: 0; opacity: .6;
  border-top: 4.5px solid transparent; border-bottom: 4.5px solid transparent;
  border-inline-end: 6px solid var(--ink);
}
.tk.none .tk-notch, .tk.mic .tk-notch { display: none; }
.tk-name {
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--ink-secondary);
  margin-top: 10px; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}
.tk-sub { font-size: 12.5px; color: var(--ink-secondary); white-space: nowrap; margin-top: 1px; }
.tk-sub.short { color: var(--fail-ink); }
.vf-group { list-style: none; margin: 10px 0 -2px; }
.goals.live { list-style: none; padding: 0; display: grid; gap: 6px; }
.goals.live li { display: flex; gap: 8px; align-items: flex-start; color: var(--ink-secondary); }
.goals.live li .ic { width: 16px; height: 16px; flex: none; margin-top: 3px; stroke: var(--line); }
.goals.live li.ok { color: var(--ink); }
.goals.live li.ok .ic { stroke: var(--pass-text); }
.ind-k { color: var(--ink-secondary); margin: -4px 0 0; }
.step-line { display: flex; align-items: center; gap: 10px; width: 100%; margin-top: 14px; padding: 12px 16px; text-align: start;
  border-radius: var(--r-card-md); background: var(--pass-bg); color: var(--pass-text); font: inherit; font-size: 14px; font-weight: 600; border: 0; cursor: pointer; }
.step-line .ic { width: 16px; height: 16px; flex: none; }
.step-line span { flex: 1; }
.time-rows { display: grid; gap: 10px; margin-top: 10px; }
.tr-row { display: grid; grid-template-columns: 56px 1fr 52px; align-items: center; gap: 12px; font-size: 14px; }
.tr-r { color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.tr-bar { height: 8px; border-radius: var(--r-pill); background: var(--track); overflow: hidden; }
.tr-bar i { display: block; height: 100%; border-radius: inherit; background: var(--water-pass-mid); }
.tr-s { text-align: end; font-variant-numeric: tabular-nums; }
.lets .let.on { background: var(--ink); color: var(--paper-card); border-color: var(--ink); }
.grid-legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; font-size: 12.5px; color: var(--ink-secondary); }
.grid-legend .lg { display: inline-flex; align-items: center; gap: 6px; }
.grid-legend i { width: 14px; height: 14px; border-radius: var(--r-tile); border: 1.5px solid var(--line); background: var(--paper-card); }
.grid-legend i.done { background: var(--ink); border-color: var(--ink); }
.grid-legend i.cur { border: 2px solid var(--accent-to); }
.grid-open { margin: 8px 0 0; font-weight: 700; font-size: 14px; }
.grid-time { display: flex; justify-content: space-between; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); font-size: 14px; color: var(--ink-secondary); }
.grid-time b { color: var(--ink); font-variant-numeric: tabular-nums; }
.vf-group .kicker { margin: 0; }
@media (max-width: 560px) { .tk-sub.v { display: none; } }
.tanks.n5 .tk-name { font-size: 11.5px; }
.tanks.sz-sm .tk-name { font-size: 11.5px; margin-top: 8px; }
.tanks.on-dark .tk-num, .tanks.on-dark .tk-name { color: var(--paper-card); }
.tanks.on-dark .tk-sub { color: var(--tint-on-dark); }
.tanks.on-dark .tk-notch { border-inline-end-color: var(--paper-card); }

@media (prefers-reduced-motion: no-preference) {
  @keyframes tk-wave { from { transform: translateX(0); } to { transform: translateX(-50%); } }
  @keyframes tk-swell { from { transform: translateY(0); } to { transform: translateY(-3px); } }
  @keyframes tk-swell-q { from { transform: translateY(0); } to { transform: translateY(-5.2cqw); } }
  /* Bubble (Tube final): rises from the bottom to the surface and fades at the
     wave; the inner circle sways from side to side. */
  @keyframes tk-rise {
    0% { transform: translateY(2%); opacity: 0; }
    8% { opacity: 1; }
    86% { opacity: .95; }
    100% { transform: translateY(calc(12cqw - 100%)); opacity: 0; }
  }
  @keyframes tk-sway { from { transform: translateX(-3.4cqw); } to { transform: translateX(3.4cqw); } }
  @keyframes tk-halo {
    0%, 100% { box-shadow: 0 0 26px 2px var(--tint-halo); }
    50% { box-shadow: 0 0 34px 6px var(--tint-halo); }
  }
  @keyframes tk-sweep {
    0%, 62% { transform: translateX(-160%) skewX(-16deg); }
    100% { transform: translateX(320%) skewX(-16deg); }
  }
  .tk-water { animation: tk-swell var(--motion-swell) ease-in-out infinite alternate; }
  .tk-body .tk-water { animation-name: tk-swell-q; }
  .tk.short .tk-water { animation: none; }
  .tk-wave.wf svg { animation: tk-wave var(--motion-wave) linear infinite; }
  .tk-wave.wb svg { animation: tk-wave var(--motion-wave-slow) linear infinite reverse; }
  /* A bubble rises at about the same pace in every flask: a taller flask gives it longer
     (--rise-k, about the square root of the height ratio, set with the flask's size). */
  .tk-bub { animation: tk-rise calc(var(--motion-rise) * var(--rise-k, 1)) linear infinite; }
  .tk-bub > i { animation: tk-sway var(--motion-sway) ease-in-out infinite alternate; }
  .tk-bub.b1 { animation-duration: calc(var(--motion-rise) * 1.304 * var(--rise-k, 1)); animation-delay: -.42s; }
  .tk-bub.b1 > i { animation-duration: calc(var(--motion-sway) * .645); }
  .tk-bub.b2 { animation-duration: calc(var(--motion-rise) * 1.22 * var(--rise-k, 1)); animation-delay: -3.51s; }
  .tk-bub.b2 > i { animation-duration: calc(var(--motion-sway) * 1.07); }
  .tk-bub.b3 { animation-duration: calc(var(--motion-rise) * .942 * var(--rise-k, 1)); animation-delay: -3.3s; }
  .tk-bub.b3 > i { animation-duration: calc(var(--motion-sway) * 1.055); }
  .tk-bub.b4 { animation-duration: calc(var(--motion-rise) * .848 * var(--rise-k, 1)); animation-delay: -1.31s; }
  .tk-bub.b5 { animation-duration: calc(var(--motion-rise) * .86 * var(--rise-k, 1)); animation-delay: -3.71s; }
  .tk-bub.b5 > i { animation-duration: calc(var(--motion-sway) * .74); }
  .tk.full .tk-tube { animation: tk-halo var(--motion-halo) ease-in-out infinite; }
  .tk-sweep { animation: tk-sweep var(--motion-sweep) 1.1s ease-in-out infinite; }
}
/* Without motion bubbles are not needed at all: a still dot on the water reads as
   a speck, not a bubble. */
@media (prefers-reduced-motion: reduce) { .tk-bub { display: none; } }

/* ---- flask card -------------------------------------------------------------- */
.tanks-card { padding: 20px 22px 22px; }
.tanks-card .head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 18px; }
.tanks-card .head .meta { font-size: 12.5px; }
.meta.short { color: var(--fail-ink); }
.meta.over { color: var(--pass-text); }

/* ---- dark task card: icon, kicker, title, white button ------------------------ */
.task-card { display: flex; align-items: center; gap: 20px; padding: 24px; }
.task-card .tc-ic {
  width: 64px; height: 64px; flex: 0 0 auto; border-radius: var(--r-card-md);
  background: var(--tint-on-dark-fill); display: flex; align-items: center; justify-content: center;
}
.task-card .tc-ic .ic { width: 24px; height: 24px; }
.task-card .tc-t { flex: 1; min-width: 0; }
.task-card .tc-k { font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--tint-on-dark); }
.task-card .tc-h { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 1.15; margin-top: 6px; color: var(--paper-card); }
.task-card .tc-p { font-size: 15px; line-height: 1.5; color: var(--tint-on-dark); margin-top: 8px; }
.task-card .tc-p b { color: var(--paper-card); }
.task-card .tc-r { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; flex: 0 0 auto; }
.task-card .tc-lift { font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--teal-glow); }
@media (max-width: 700px) {
  .task-card { flex-wrap: wrap; }
  .task-card .tc-r { width: 100%; align-items: stretch; }
}

/* ---- web header: glass band -------------------------------------------------- */
.topbar { position: sticky; top: 0; z-index: 30; padding: 14px 24px 0; background: none; border: 0; }
.header {
  max-width: var(--web-max); margin: 0 auto; padding: 8px 12px 8px 18px; gap: 18px;
  border-radius: var(--r-card);
  background: var(--glass-light);
  -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
  border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow);
}
.brand-name { font-size: 20px; }
.brand-name span { color: var(--accent-ink); }
.nav { gap: 4px; }
.nav a { position: relative; font-size: 15px; color: var(--ink-secondary); padding: 0 12px; }
.nav a[aria-current="page"] { color: var(--ink); }
.nav a[aria-current="page"]::after {
  content: ''; position: absolute; inset-inline: 12px; bottom: 6px; height: 2.5px;
  border-radius: var(--r-pill); background: var(--ink);
}
.run-chip > span {
  background: var(--paper-card); border: 1px solid var(--line); box-shadow: none; font-size: 12.5px; padding: 5px 11px;
}
.exam-chip { font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); white-space: nowrap; }
.avatar > span { width: 38px; height: 38px; background: var(--track); color: var(--ink-secondary); }
/* The content box, not the padded box, is --web-max wide, like the header band
   above it: the band and the cards then share both edges at every width. */
.wrap { max-width: calc(var(--web-max) + 48px); padding: 28px 24px 0; }

/* The floating tab bar replaces the header link row on a narrow screen, the same
   as on the phone (Today · Practice · Progress · You). Only the current tab has a
   visible label; on the others it lives for screen readers. */
.tabbar { display: none; }
.tabbar a { color: var(--ink-secondary); text-decoration: none; }
@media (max-width: 560px) {
  .header .nav { display: none; }
  .exam-chip { display: none; }
  /* Above the iPhone home indicator, not on it: the page extends under it
     (viewport-fit=cover), and the offset is counted from the safe area. */
  .tabbar {
    position: fixed; z-index: 40; left: 50%; bottom: max(18px, calc(env(safe-area-inset-bottom) + 6px)); transform: translateX(-50%);
    display: flex; gap: 2px; padding: 6px; border-radius: var(--r-pill);
    /* Denser than a card's glass: the bar floats over text, not over the paper, and a
       line read through it looks broken (the phones' bar is as dense). */
    background: linear-gradient(155deg, rgba(255,255,255,.95), rgba(255,255,255,.82));
    -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
    border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow);
  }
  .tabbar a {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    min-height: var(--a11y-tap-target-min); min-width: var(--a11y-tap-target-min);
    padding: 0 13px; border-radius: var(--r-pill);
    font-family: var(--font-display); font-weight: 800; font-size: 13px; white-space: nowrap;
  }
  .tabbar a .ic { width: 17px; height: 17px; }
  .tabbar a[aria-current="page"] { background: var(--ink); color: var(--paper-card); padding: 0 16px; }
  .tabbar a:not([aria-current="page"]) .tb-l { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  /* Whitespace is left under the bar: otherwise the last card goes under it. */
  .tabbar ~ .wrap { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
  /* The band's side padding equals .wrap's, so its edges line up with the cards. */
  .topbar { padding: 10px 16px 0; }
  .header { padding: 6px 8px 6px 14px; }
  .wrap { padding: 20px 16px 0; }
}

/* ---- home v3 (W02, W13, B01) --------------------------------------------------
   Two columns on a wide screen; one on a narrow screen, in a different order:
   the flasks go right under the title (W13, B01), not after all the cards of
   the left column. The columns dissolve (display: contents) and each card
   sets its own order. A grid with shared rows would let a tall right card
   stretch the left column's rows and open a hole under the title. */
.today-grid { display: grid; gap: 24px; align-items: start; grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr); }
.t-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.today .display { font-size: 44px; margin-top: 10px; }
.today .lede { margin-top: 12px; max-width: 580px; font-size: 17px; }
.t-head { margin-bottom: 6px; }
@media (max-width: 900px) {
  .today-grid { display: flex; flex-direction: column; gap: 16px; }
  .t-col { display: contents; }
  .t-head { order: 1; } .t-status { order: 2; } .t-stand { order: 3; } .t-task { order: 4; }
  .t-week { order: 5; } .t-trap { order: 6; } .t-side { order: 7; }
  .today .display { font-size: 34px; }
}
@media (max-width: 560px) { .today .display { font-size: 30px; } .today .lede { font-size: 15.5px; } }
/* Tablet (W13): under the task, two cards side by side (recording and run), then
   the trap and the week. */
@media (min-width: 600px) and (max-width: 900px) {
  .t-side { order: 5; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; align-items: stretch; }
  .t-side > * { margin: 0; }
  .t-trap { order: 6; } .t-week { order: 7; }
}

.week-card, .info-card { padding: 20px 22px; display: block; }
.week-card .head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.wk { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 9px; }
.wd {
  position: relative; display: flex; flex-direction: column; gap: 3px; min-height: 96px;
  padding: 12px 11px; border-radius: var(--r-card-md);
  background: var(--tint-empty-tube); border: 1px solid var(--line);
}
.wd-d { font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--ink-secondary); }
.wd-p { font-family: var(--font-display); font-weight: 800; font-size: 14.5px; color: var(--ink); overflow-wrap: anywhere; line-height: 1.2; }
.wd-m { margin-top: auto; color: var(--pass-text); }
.wd-m .ic { width: 16px; height: 16px; }
.wd.freeze { background: var(--pass-bg); border: 1px dashed var(--tint-ok-line); }
.wd.freeze .wd-p { color: var(--pass-text); }
.wd.today { background: var(--ink); border-color: var(--ink); }
.wd.today .wd-d { color: var(--tint-on-dark); }
.wd.today .wd-p { color: var(--paper-card); }
.wd.today .wd-m { color: var(--water-short-top); }
.wd.miss .wd-p { color: var(--ink-faint); }
.wd.before { background: transparent; border-style: dashed; }
.wd.plan { background: var(--glass-light); }
@media (max-width: 700px) {
  .wk { gap: 5px; }
  .wd { min-height: 78px; padding: 9px 6px; }
  .wd-p { font-size: 11.5px; }
}

.trap-row { display: flex; align-items: center; gap: 18px; padding: 18px 22px; border-radius: var(--r-card); }
.trap-row .pill-trap { flex: 0 0 auto; }
/* The trap of the first result (03, A04, W17): the red word on the left, a line on
   the right: the bold first sentence of the explanation and a muted “what it cost”. */
.trap-line { display: flex; align-items: flex-start; gap: 14px; padding: 16px 18px; border-radius: var(--r-card); }
.trap-line .pill-trap { flex: none; }
.trap-line .tr-why { font-size: 13.5px; line-height: 1.5; color: var(--ink-secondary); margin-top: 0; }
.trap-line .tr-why b { color: var(--ink); }
.tr-t { flex: 1; min-width: 0; }
.tr-line { font-size: 15.5px; line-height: 1.5; margin-top: 4px; }
.tr-why { font-size: 14px; line-height: 1.5; color: var(--ink-secondary); margin-top: 4px; }

.info-card { border-radius: var(--r-card); color: inherit; text-decoration: none; }
.ic-row { display: flex; align-items: center; gap: 14px; }
.ic-row .lrow-ic { width: 42px; height: 42px; }
.ic-row .lrow-ic.warm { background: var(--fail-bg); color: var(--fail-ink); }
.ic-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ic-t b { font-family: var(--font-display); font-weight: 800; font-size: 16.5px; }
.ic-t span { font-size: 14px; color: var(--ink-secondary); }
.span-bar { height: 8px; border-radius: var(--r-pill); background: var(--line); margin-top: 16px; overflow: hidden; }
.span-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--pass); }
.span-l { display: flex; justify-content: space-between; margin-top: 7px; font-size: 13px; color: var(--ink-secondary); }
.info-foot {
  display: inline-flex; align-items: center; min-height: var(--a11y-tap-target-min); margin-top: 4px;
  font-family: var(--font-display); font-weight: 800; font-size: 13.5px; color: var(--accent-ink); text-decoration: none;
}
.link-card:hover { transform: translateY(-1px); }

.status-row {
  display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-radius: var(--r-card-sm);
  color: inherit; text-decoration: none;
}
.status-row .sr-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.status-row .sr-t b { font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.status-row .sr-t span { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; }
.exam-chip { text-decoration: none; min-height: var(--a11y-tap-target-min); display: inline-flex; align-items: center; }
/* Narrow screen: a one-line header with the logo on the left, streak and avatar on
   the right (B01). The exam with its date goes away: it is in the home kicker. */
@media (max-width: 560px) {
  .header { flex-wrap: nowrap; }
  .header .row { margin-inline-start: auto; gap: 6px; }
  .exam-chip { display: none; }
  .wd-p { display: none; }
  .wd-i { display: block; }
  .wd { min-height: 70px; align-items: center; padding: 9px 4px; }
  .wd-m { margin-top: 0; }
}
.wd-i { display: none; color: var(--ink-secondary); margin-top: 6px; }
.wd-i .ic { width: 16px; height: 16px; }
.wd.today .wd-i { color: var(--paper-card); }
.wd.done .wd-i, .wd.freeze .wd-i { display: none; }

/* ---- progress v3 (W07, B03) ------------------------------------------------- */
.progress-v3 .display, .practice-v3 .display { font-size: 40px; margin-top: 10px; }
.cols[data-cols="1:1.35"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); gap: 24px; }
.trend-card { padding: 20px 22px 16px; }
.trend-card .head, .week-mini .head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.meta .dash { display: inline-block; width: 18px; border-top: 1.5px dashed var(--tint-line-dash); margin-inline-end: 7px; vertical-align: middle; }
.trend-row { display: grid; grid-template-columns: 104px minmax(0, 1fr) 84px; gap: 16px; align-items: center; padding: 14px 0; }
.trend-row + .trend-row { border-top: 1px solid var(--line); }
.tr-name { display: flex; flex-direction: column; gap: 2px; }
.tr-name b { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.tr-name span { font-size: 13px; color: var(--ink-secondary); }
.tr-name span.short { color: var(--fail-ink); }
.tr-plot { position: relative; height: 64px; display: flex; align-items: center; }
.tr-dot {
  position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%;
  background: var(--pass); box-shadow: 0 0 0 2px var(--paper-card);
}
.trend-row:has(.trend.short) .tr-dot { background: var(--fail); }
.tr-dot.last { width: 10px; height: 10px; margin: -5px 0 0 -5px; }
.tr-delta.over { background: var(--pass-bg); color: var(--pass-text); border: 0; box-shadow: none; }
.tr-delta.short { background: var(--fail-bg); color: var(--fail-ink); border: 0; box-shadow: none; }
.trend { width: 100%; height: 64px; overflow: visible; }
.trend .tr-line { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; stroke: var(--pass); }
.trend.short .tr-line { stroke: var(--fail); }
.trend .tr-area { fill: var(--tint-range-teal); opacity: .5; }
.trend.short .tr-area { fill: var(--tint-range-warm); }
.trend .tr-pass { stroke: var(--tint-line-dash); stroke-width: 1.5; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
.tr-val { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.tr-val b { font-family: var(--font-display); font-weight: 800; font-size: 24px; line-height: 1; }
.tr-val b small { font-size: 13px; color: var(--ink-secondary); }
.tr-val b.short { color: var(--fail-ink); }
.tr-val b.none { color: var(--ink-secondary); }
.tr-delta { font-size: 11.5px; padding: 3px 9px; }
.tr-axis { display: flex; justify-content: space-between; padding: 6px 100px 0 120px; font-size: 12.5px; color: var(--ink-secondary); }
@media (max-width: 560px) {
  .trend-row { grid-template-columns: 86px minmax(0, 1fr) 60px; gap: 10px; }
  .tr-axis { padding: 6px 70px 0 96px; }
}
.mt-0 { margin-top: 0; }
.week-mini, .mocks-card { padding: 20px; }
.wdots { list-style: none; margin: 12px 0 0; padding: 0; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.wdot { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; }
.wdot .c {
  width: 36px; height: 36px; border-radius: var(--r-pill); display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); color: var(--paper-card);
}
.wdot .c .ic { width: 15px; height: 15px; }
.wdot.done .c { background: var(--pass); border-color: var(--pass); }
.wdot.freeze .c { border: 1.5px dashed var(--pass-text); color: var(--pass-text); }
.wdot.today .c { border: 2px solid var(--accent-to); color: var(--accent-to); }
.wdot b { font-family: var(--font-display); font-weight: 800; font-size: 12px; }
.wdot .l { font-size: 11.5px; color: var(--ink-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.stat2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.wm-row { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 18px; align-items: center; }
@media (max-width: 700px) { .wm-row { grid-template-columns: minmax(0, 1fr); } }
.stat2 > div { border: 1px solid var(--line); border-radius: var(--r-card-md); padding: 12px 14px; background: var(--tint-empty-tube); }
.stat2 b { display: block; font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 1.1; }
.stat2 span { font-size: 13px; color: var(--ink-secondary); }
.mocks-card .lrow { padding: 10px 0; }
.lrow-ic.warm { background: var(--fail-bg); color: var(--fail-ink); }
.mk-next { display: flex; align-items: center; justify-content: space-between; gap: 10px; border-top: 1px solid var(--line); padding-top: 12px; margin-top: 6px; }
.mk-next b { font-family: var(--font-display); font-weight: 800; font-size: 14.5px; }

/* ---- practice v3 (W06, B02) -------------------------------------------------- */
.pr-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.pr-head .seg { margin-top: 0; }
.pr-cards { margin-top: 22px; }
.pcard3 { display: flex; flex-direction: column; gap: 10px; padding: 18px; border-radius: var(--r-card); }
.pcard3.short { border: 1.5px solid var(--tint-no-line); }
.pc-top { display: flex; align-items: center; gap: 12px; }
.pc-t { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pc-t b { font-family: var(--font-display); font-weight: 800; font-size: 19px; }
.pc-t span { font-size: 12.5px; color: var(--ink-secondary); }
.pc-sc { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 1; }
.pc-sc small { font-size: 13px; color: var(--ink-secondary); }
.pc-sc.short { color: var(--fail-ink); }
.pc-sc.none { color: var(--ink-secondary); }
.pc-note { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.45; flex: 1; }
.pc-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.pc-of { font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--ink-secondary); }
.pcard3 .btn-card { margin-top: 4px; }
/* Wide web (W06): “Start” is a content-width pill on the right, and a part
   below the line gets an orange edge. Narrower, “Start” is full width, as on
   the phone. */
@media (min-width: 901px) {
  .pc-foot .btn-card { width: auto; margin: 0 0 0 auto; padding: 10px 18px; font-size: 15px; }
  .pcard3.short { border: 2px solid var(--accent); }
}
.mock-card { padding: 24px; }
.on-dark-k { color: var(--tint-on-dark); }
.mc-h { font-family: var(--font-display); font-weight: 800; font-size: 24px; margin-top: 6px; color: var(--paper-card); }
/* Break countdown (W21): large, like the clock on the exam hall wall; digits do not jump. */
.mc-clock { display: block; font-family: var(--font-display); font-weight: 800; font-size: 72px; line-height: 1; margin-top: 14px; color: var(--paper-card); font-variant-numeric: tabular-nums; }
.mc-p { font-size: 14.5px; line-height: 1.5; color: var(--tint-on-dark); margin-top: 8px; }
.mc-steps { list-style: none; margin: 16px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.mc-steps li { border: 1px solid var(--tint-on-dark-line); background: var(--tint-on-dark-fill); border-radius: var(--r-input); padding: 10px 12px; display: flex; flex-direction: column; }
.mc-steps b { font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--paper-card); }
.mc-steps span { font-size: 12px; color: var(--tint-on-dark); }
.mc-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 18px; flex-wrap: wrap; }
.mc-foot > span { font-size: 13.5px; color: var(--tint-on-dark); }
.word-pills span { font-size: 14.5px; padding: 8px 14px; border-radius: var(--r-pill); }
@media (max-width: 560px) { .mc-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.mc-steps li > i { display: none; }
/* Wide web (W06): the run parts as rows with an icon and minutes on the right,
   under a rule; narrow: as tiles, as on the phone. */
@media (min-width: 901px) {
  .mc-steps { display: flex; flex-direction: column; gap: 0; }
  .mc-steps li { flex-direction: row; align-items: center; gap: 10px; background: none; border: 0; border-radius: 0;
    border-bottom: 1px solid var(--tint-on-dark-line); padding: 11px 0; }
  .mc-steps li:last-child { border-bottom: 0; }
  .mc-steps li > i { display: inline-flex; color: var(--tint-on-dark); }
  .mc-steps li > i .ic { width: 16px; height: 16px; }
  .mc-steps b { flex: 1; }
  .mc-steps span { font-size: 13px; }
}

/* ---- sittings v3 (W11, B06) ---------------------------------------------------- */
.sittings-v3 .display { margin-top: 10px; }
.sit3 { display: flex; align-items: center; gap: 16px; padding: 16px 18px; border-radius: var(--r-card-sm); }
.sit3.chosen { border: 1.5px solid var(--ink); }
.sit3.later { background: var(--tint-empty-tube); border: 1px dashed var(--line-strong); box-shadow: none; }
.sit3-d { width: 58px; flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; line-height: 1; }
.sit3-d b { font-family: var(--font-display); font-weight: 800; font-size: 28px; }
.sit3-d small { font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); margin-top: 3px; }
.sit3-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sit3-n { font-family: var(--font-display); font-weight: 800; font-size: 17px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sit3-s { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.4; }
.sit3-r { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.sit3-fee { font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--ink-secondary); }

/* ---- settings and You v3 (G01, B08, W12) -------------------------------------- */
.settings-v3 .display { margin-top: 0; }
.set3 { padding: 18px 20px 8px; border-radius: var(--r-card); }
.set3 .lrows { margin-top: 4px; }
.you-card { display: flex; align-items: center; gap: 14px; padding: 18px 20px; border-radius: var(--r-card); }
.you-av {
  width: 48px; height: 48px; flex: 0 0 auto; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--track); color: var(--ink-secondary);
  font-family: var(--font-display); font-weight: 800; font-size: 19px;
}
.you-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.you-t b { font-family: var(--font-display); font-weight: 800; font-size: 17px; overflow-wrap: anywhere; }
.you-t span { font-size: 13.5px; color: var(--ink-secondary); }

/* ---- which exam (A01) ------------------------------------------------------------ */
.solo.wide { max-width: 620px; }
.exam-list { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }
.exam-card {
  display: flex; align-items: center; gap: 16px; padding: 18px 20px; border-radius: var(--r-card);
  color: inherit; text-decoration: none;
}
.exam-card.on { border: 2px solid var(--ink); }
.ex-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ex-t b { font-family: var(--font-display); font-weight: 800; font-size: 19px; }
.ex-n { font-family: var(--font-display); font-weight: 800; font-size: 13.5px; color: var(--ink-secondary); }
.ex-p { font-size: 14.5px; color: var(--ink); }
.ex-s { font-size: 13px; color: var(--ink-secondary); }
.ex-r { width: 28px; height: 28px; border-radius: var(--r-pill); background: var(--ink); color: var(--paper-card); display: flex; align-items: center; justify-content: center; }
.ex-r .ic { width: 16px; height: 16px; }

/* ---- tasks v3: header, flask player, text, questions (W08, W03, C02–C05) ------ */
.header.prova-head { gap: 14px; padding: 8px 12px; border: 1px solid var(--glass-light-border); margin: 0 auto; }
.prova-head .prova-title { font-family: var(--font-display); font-weight: 800; font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.prova-head .ph-gap { flex: 1; }
.prova-head .prova-close { margin: 0; }
.prova-head .pill-dark { font-size: 13px; padding: 8px 14px; }
/* The mark and “Exit” only on the wide web (W03, W08): there the task header stands
   in place of the site header, and the title moves into a pill next to the clock. */
.prova-head .ph-brand, .prova-head .ph-exit { display: none; }
@media (min-width: 901px) {
  .prova-head .prova-close { display: none; }
  .prova-head .ph-brand { display: inline-flex; order: 0; }
  .prova-head .ph-gap { order: 1; }
  .prova-head .prova-title {
    order: 2; font-size: 12.5px; line-height: 1.2; padding: 7px 13px; border-radius: var(--r-pill);
    background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
    -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  }
  /* On the wide web the question and word count already sits in the column alongside. */
  .prova-head .ph-count, .prova-head .ph-words { display: none; }
  .prova-head .ph-clock { order: 4; }
  .prova-head .ph-exit { display: inline-flex; order: 5; padding: 9px 16px; font-size: 14px; }
}
/* Narrow phone: next to the cross and a status pill ("Text stays open",
   "Time is up") a title like "Answer sheet · Ascolto" does not fit on one
   line. It wraps to a second line inside the 44px row instead of losing its
   end to an ellipsis (nothing is clipped, so no glyph is cut either); the
   title itself takes the free width, so the empty spacer goes. */
@media (max-width: 560px) {
  .prova-head .ph-gap { display: none; }
  .prova-head .prova-title { flex: 1 1 0; min-width: 0; white-space: normal; line-height: 1.15; overflow: visible; overflow-wrap: anywhere; }
}
.pill .dot { width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--water-rec-mid); display: inline-block; }
.prova-body { padding-top: 6px; padding-bottom: 40px; }
.task3 { align-items: stretch; }
.qcol { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
/* Options that open a column (the review, W19) start level with the other
   column's first line; their top margin is for the gap under a question. */
.qcol > .opts:first-child { margin-top: 0; }
/* A title row with a pill on the right (the letter result, W10): the pill sits
   on the heading's line, not in the middle of the kicker and heading block. */
.row-between:has(> div > .display) { align-items: flex-end; }
.q-top { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.q-top .kicker { flex: 0 0 auto; }
.qstrip { flex: 1; display: flex; gap: 4px; min-width: 120px; }
.qstrip i { flex: 1; height: 4px; border-radius: var(--r-pill); background: var(--line-strong); }
.qstrip i.done { background: var(--ink); }
.qstrip i.cur { background: var(--accent-to); }
.qstrip i.right { background: var(--pass); }
.qstrip i.wrong { background: var(--fail-ink); }
.q-card { padding: 20px 22px; border-radius: var(--r-card); }
.q-card .q-stem { font-size: 26px; line-height: 1.25; margin-top: 6px; }
.under-note { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--ink-secondary); margin-top: 10px; }
.under-note .ic { width: 16px; height: 16px; }
/* Note (v3): an 18 icon without a tile, a 13.5 sentence in ink, 13 / 15, radius 20. */
.hint-card { display: flex; align-items: flex-start; gap: 12px; padding: 13px 15px; border-radius: var(--r-card-md); text-align: start; }
.hc-ic { flex: 0 0 auto; display: flex; color: var(--pass-text); }
.hc-ic.warm { color: var(--fail-ink); }
/* Warm note (B01·s7): a pink base with a thin red edge. */
.hint-card.warm { background: var(--fail-bg); border: 1px solid var(--tint-no-line); }
.hint-card.teal { background: var(--pass-bg); border: 1px solid var(--tint-ok-line); }
.hc-ic .ic { width: 18px; height: 18px; }
.hc-note { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink); }
/* Note-button (B07·s2): looks like a note; pressing it opens the exam-centre fields. */
.hint-btn { width: 100%; font: inherit; color: inherit; cursor: pointer; text-decoration: none; }
/* Info card: kicker and a 14 line, no icon, 15 / 17, radius 22. */
.hint-card.titled { display: block; padding: 15px 17px; border-radius: var(--r-card-sm); }
.hint-card.titled .hc-note { font-size: 14px; margin-top: 6px; }
.kicker-warm { color: var(--fail-ink); }
/* Hint cards built with an .lrow-ic icon tile (prova.js, screens.js) get the
   same note look: the icon without its tile. */
.hint-card > .lrow-ic { width: auto; height: auto; background: none; border-radius: 0; color: var(--pass-text); }
.hint-card > .lrow-ic .ic { width: 18px; height: 18px; }
.hint-card > .lrow-ic.warm { color: var(--fail-ink); }
.hc-t { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; line-height: 1.5; }
.hc-t b { font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.hc-t span { color: var(--ink); }
.act-row { display: flex; gap: 12px; margin-top: 4px; align-items: center; }
.act-row > .btn-primary, .act-row > a.btn-primary { flex: 1; }
.act-row.end { justify-content: flex-end; }
.act-row.end > .btn { flex: 0 0 auto; }
.act-row.wrap-row { flex-wrap: wrap; justify-content: space-between; }
.act-row.wrap-row > .btn-primary { flex: 0 0 auto; }
.btn-glass-dark { background: var(--tint-on-dark-fill); color: var(--paper-card); border: 1px solid var(--tint-on-dark-line); box-shadow: none; }

/* Flask player: dark glass, the water rises from the bottom with the recording. */
.tp-wrap { display: flex; flex-direction: column; min-width: 0; }
.tplayer {
  position: relative; overflow: hidden; isolation: isolate; min-height: 520px;
  display: flex; flex-direction: column; align-items: center; padding: 26px 22px;
  border-radius: var(--r-card);
}
/* Player kicker: recording playing is panel-accent, paused is panel-kicker, speaking recording is panel-rec. */
.tp-k { font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--panel-accent); position: relative; z-index: 2; }
.tplayer.rest .tp-k { color: var(--panel-kicker); }
.tplayer.rec .tp-k { color: var(--panel-rec); }
.tp-mid {
  position: relative; z-index: 2; margin: auto 0; display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 24px 30px; border-radius: var(--r-card); background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line);
  min-width: 200px; text-align: center;
}
.tp-btn {
  width: 96px; height: 96px; border-radius: var(--r-pill); border: 0; padding: 0; cursor: pointer;
  background: var(--paper-card); color: var(--ink); display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-card);
}
.tp-btn svg { width: 34px; height: 34px; fill: currentColor; }
/* Kit icons are drawn with a stroke: filled, the check of "Answers closed"
   turned into a black sliver (C02·6, B-16). The play and stop glyphs are not
   kit icons and keep their fill. */
.tp-btn svg.ic { fill: none; }
.tp-btn.idle { cursor: default; }
.tp-btn.rec { color: var(--water-rec-mid); box-shadow: 0 0 0 10px var(--tint-on-dark-fill); }
.tp-num { font-family: var(--font-display); font-weight: 800; font-size: 56px; line-height: 1; color: var(--paper-card); font-variant-numeric: tabular-nums; }
.tp-sub { font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--tint-on-dark); max-width: 260px; }
.tp-note { font-size: 13.5px; color: var(--tint-on-dark); max-width: 300px; }
.tp-note a { color: var(--paper-card); }
.tp-water {
  position: absolute; left: 0; right: 0; bottom: 0; height: var(--lvl); z-index: 1;
  background: linear-gradient(180deg, var(--water-pass-top), var(--water-pass-mid) 45%, var(--water-pass-deep));
  transition: height var(--motion-slow) linear;
}
.tp-water.rec { background: linear-gradient(180deg, var(--water-rec-top), var(--water-rec-mid) 45%, var(--water-rec-deep)); }
.tp-water.rec .tk-wave svg { fill: var(--water-rec-top); }
.tplayer.rest .tp-water { opacity: .75; }
/* When paused, under the clock goes a sentence, not a tag: a whole sentence in caps does not read. */
.tplayer.rest .tp-sub { text-transform: none; letter-spacing: 0; font-family: var(--font-body); font-weight: 600; font-size: 13.5px; line-height: 1.45; }
@media (max-width: 900px) { .tplayer { min-height: 340px; } .tp-num { font-size: 44px; } }
/* Phone: a compact player, so the question and options fit on the screen
   below it and listening needs no scrolling. The water and the clock stay. */
@media (max-width: 560px) {
  .tplayer { min-height: 0; padding: 16px 16px 18px; }
  .tp-mid { margin: 12px 0 0; padding: 14px 22px; gap: 6px; }
  .tp-btn { width: 68px; height: 68px; }
  .tp-btn svg { width: 26px; height: 26px; }
  .tp-num { font-size: 36px; }
}
/* Wide web (W08): the flask player at the full height of the question column; the
   number map without a legend and without the list of open items: the “N answered”
   count and the cells themselves already say it. The legend stays on the phone's
   number sheet. */
@media (min-width: 901px) {
  .task3 > .tp-wrap .tplayer { flex: 1 1 auto; }
  .task3 .grid-card .grid-legend, .task3 .grid-card .grid-open { display: none; }
}

/* Reading text and cloze. */
.tx-wrap { display: flex; flex-direction: column; min-width: 0; }
.text-card { padding: 22px 24px; border-radius: var(--r-card); }
.tx-h { font-family: var(--font-display); font-weight: 800; font-size: 24px; margin-top: 10px; }
.text-card .passage { margin-top: 12px; }
.text-card .passage p { font-size: 16px; line-height: 1.75; margin-top: 10px; }
.text-card .passage h3 { font-size: 16px; margin-top: 14px; }
.gap {
  display: inline-flex; align-items: center; justify-content: center; min-width: 30px; padding: 0 8px;
  border-radius: var(--r-input-sm); background: var(--line); font-family: var(--font-display); font-weight: 800; font-size: 14px;
  line-height: 1.6; vertical-align: baseline;
}
.gap.cur { background: var(--ink); color: var(--paper-card); }
.gap.done { background: var(--pass-bg); color: var(--pass-text); }
.gap.ex { background: transparent; border-bottom: 2px solid var(--line-strong); border-radius: 0; font-family: var(--font-body); font-weight: 700; }

.opt-pills { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.opt-pills .opt { border-radius: var(--r-pill); justify-content: center; padding: 14px 10px; }
.opt-pills .opt .opt-key, .opt-pills .opt .opt-radio { display: none; }
.opt-pills .opt .opt-text { flex: 0 1 auto; text-align: center; font-family: var(--font-display); font-weight: 800; }
.grid-card { padding: 18px 20px; border-radius: var(--r-card); }
.grid-card .all-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); margin-top: 12px; }
.all-grid button { border-radius: var(--r-input); background: var(--glass-light); border: 1px solid var(--line); color: var(--ink-secondary); }
.all-grid button.done { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
.all-grid button.right { background: var(--pass-bg); border-color: var(--tint-ok-line); color: var(--pass-text); }
.all-grid button.wrong { background: var(--fail-bg); border-color: var(--tint-no-line); color: var(--fail-ink); }
.all-grid button.cur { outline: none; border: 2px solid var(--accent-to); color: var(--accent-ink); }

/* The “vero / falso” list. */
.vf-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.vf-row { display: flex; align-items: center; gap: 14px; padding: 12px 14px 12px 18px; border-radius: var(--r-card-sm); }
.vf-row.cur { border: 1.5px solid var(--ink); }
.vf-n { width: 18px; flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); }
.vf-s { flex: 1; min-width: 0; font-size: 15.5px; line-height: 1.45; }
.vf-pair { display: flex; gap: 8px; flex: 0 0 auto; }
.vf-b {
  min-height: var(--a11y-tap-target-min); min-width: 70px; padding: 0 14px; border-radius: var(--r-pill); cursor: pointer;
  font-family: var(--font-display); font-weight: 800; font-size: 13.5px; text-transform: capitalize;
  background: var(--paper-card); border: 1px solid var(--line); color: var(--ink);
}
.vf-b.on { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
.vf-b:disabled { cursor: default; opacity: .85; }
@media (max-width: 560px) {
  .vf-row { flex-wrap: wrap; }
  .vf-pair { width: 100%; }
  .vf-b { flex: 1; }
}

/* Explanation (W19). */
.line-card { padding: 22px 24px; border-radius: var(--r-card); }
.lc-line { font-size: 22px; line-height: 1.5; }
.replay-row {
  display: flex; align-items: center; gap: 14px; width: 100%; margin-top: 18px; padding: 12px 14px; cursor: pointer; text-align: start;
  border: 0; border-radius: var(--r-card-sm); background: var(--tint-teal-tile); color: var(--ink); font: inherit;
}
.rr-btn { width: 44px; height: 44px; flex: 0 0 auto; border-radius: var(--r-pill); background: var(--ink); color: var(--paper-card); display: flex; align-items: center; justify-content: center; }
.rr-btn svg { width: 16px; height: 16px; fill: currentColor; }
.rr-t { display: flex; flex-direction: column; }
.rr-t b { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.rr-t small { font-size: 12.5px; color: var(--ink-secondary); }
.opt-tag { margin-inline-start: auto; font-family: var(--font-display); font-weight: 800; font-size: 12px; }
.opt.right .opt-tag { color: var(--pass-text); }
.opt.wrong .opt-tag { color: var(--fail-ink); }
.why-card .why { font-size: 15.5px; line-height: 1.6; margin-top: 8px; }

/* Prova result (C15). */
.centered-solo { text-align: center; margin: 0 auto; display: flex; flex-direction: column; align-items: center; }
.centered-solo .tanks-card { width: 100%; }
.centered-solo .btn-row { justify-content: center; }


/* ---- state screen template (v3: D04, D05, E01–E06, F01–F12, C12·s2) ----------
   A screen that starts with a state icon is built from one template: the icon
   centred in a soft halo, the text centred, the primary button full width, the
   secondary action as a quiet link rather than a second big button.
   It applies to .solo.center and to any .solo whose first child is .state-ic,
   so a state screen needs no extra class. */
.solo.center,
.solo:has(> .state-ic:first-child) { text-align: center; margin-inline: auto; }
.solo.center > .state-ic,
.solo:has(> .state-ic:first-child) > .state-ic { display: flex; margin: 30px auto 26px; }
.solo.center > .lede,
.solo:has(> .state-ic:first-child) > .lede { margin-inline: auto; max-width: 440px; }
/* Cards and rows inside read as usual: from the left. */
.solo.center > section, .solo.center > .pk-banner, .solo.center > .hint-card,
.solo:has(> .state-ic:first-child) > section,
.solo:has(> .state-ic:first-child) > .pk-banner { text-align: start; }
.solo.center > .btn-big,
.solo:has(> .state-ic:first-child) > .btn-big { width: 100%; }
.solo.center > .btn-quiet.btn-big,
.solo:has(> .state-ic:first-child) > .btn-quiet.btn-big {
  background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
  color: var(--ink-secondary); font-size: 15px; margin-top: 4px;
}
.solo.center > .link-quiet,
.solo:has(> .state-ic:first-child) > .link-quiet { display: flex; width: fit-content; margin-inline: auto; }
/* Button row on a state screen: stacked, the primary first and full width, the
   rest as quiet links under it. */
.solo:has(> .state-ic:first-child) > .btn-row { flex-direction: column; align-items: stretch; gap: 4px; }
.solo:has(> .state-ic:first-child) > .btn-row .btn-primary { order: -1; width: 100%; }
.solo:has(> .state-ic:first-child) > .btn-row .btn-quiet.btn-big {
  background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
  color: var(--ink-secondary); font-size: 15px;
}
.kicker-teal { color: var(--pass-text); }

/* Writing (W09, W10). */
.words-card { padding: 20px 22px; border-radius: var(--r-card); }
.wc-n { font-family: var(--font-display); font-weight: 800; }
.wc-n b { font-size: 28px; color: var(--ink); }
.wc-n b.ok { color: var(--pass-text); }
.wc-n small { font-size: 13px; color: var(--ink-secondary); margin-inline-start: 4px; }
.wc-bar { position: relative; height: 9px; border-radius: var(--r-pill); background: var(--line); margin-top: 12px; }
.wc-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--pass); transition: width var(--motion-fast) linear; }
.wc-bar b { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--ink); opacity: .6; }
.ax-dot { width: 22px; height: 22px; flex: 0 0 auto; border-radius: var(--r-pill); border: 1.5px dashed var(--ink-faint); }
.letter-card { padding: 22px 24px; border-radius: var(--r-card); min-height: 320px; }
.letter-card .letter { min-height: 300px; font-size: 16.5px; line-height: 1.75; }
.letter-card.read p { font-size: 16.5px; line-height: 1.9; margin-top: 12px; }
.letter-card.read p:first-child { margin-top: 0; }
mark.fix { background: var(--fail-bg); color: var(--ink); border-bottom: 2px solid var(--fail); padding: 0 3px; border-radius: var(--r-input-sm); }
mark.fix sup { color: var(--fail-ink); font-family: var(--font-display); font-weight: 800; font-size: 11px; margin-inline-start: 2px; }
.acc-keys { display: flex; gap: 8px; flex-wrap: wrap; }
.acc-key {
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min); border-radius: var(--r-input); cursor: pointer;
  font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink);
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
}
.ax3 { padding: 12px 0; }
.ax3 + .ax3 { border-top: 1px solid var(--line); }
.ax3-n { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.ax3-n small { font-family: var(--font-body); font-weight: 600; font-size: 12.5px; color: var(--ink-secondary); }
.ax3 .axis-score { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.ax3 .axis-score.under { color: var(--fail-ink); }
.ax3-bar { display: flex; gap: 4px; margin-top: 9px; }
.ax3-bar i { flex: 1; height: 7px; border-radius: var(--r-pill); background: var(--fail-bg); }
.ax3-bar i.on { background: var(--pass); }
.fix-n { width: 26px; height: 26px; flex: 0 0 auto; border-radius: var(--r-pill); background: var(--fail-ink); color: var(--paper-card); display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 800; font-size: 13px; }

/* Answer sheet (C07). */
.sheet3 { padding: 20px; border-radius: var(--r-card); }
.sheet3 .sp-grid { margin-top: 0; }
.sheet3 .bub.done { background: var(--paper-warm); border: 1.5px solid var(--ink); color: var(--ink); }
.sheet3 .bub.cur { background: var(--paper-card); border: 2px solid var(--accent-to); color: var(--accent-ink); }
.sheet3 .bub.pending { background: transparent; border: 1.5px solid var(--line-strong); color: var(--ink-faint); }
.lets .let { border-radius: var(--r-card-md); background: var(--glass-light); border: 1px solid var(--glass-light-border); box-shadow: var(--glass-pill-shadow); }
.lets .let:hover { border-color: var(--accent-to); }

/* Speaking (C12–C14). */
.rec-audio { width: 100%; margin-top: 10px; }
.lrow.tg { cursor: pointer; }
.lrow.tg .switch { pointer-events: none; }
.link-danger { background: none; border: 0; cursor: pointer; padding: 0; }

/* Run (W21, D03). */
.mk-parts { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.mkp { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border-radius: var(--r-card-md); border: 1px solid var(--line); background: var(--tint-empty-tube); }
.mkp small { font-size: 12px; color: var(--ink-secondary); font-family: var(--font-display); font-weight: 800; }
.mkp b { font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.mkp .ic { width: 16px; height: 16px; margin-top: 6px; }
.mkp.done { background: var(--pass-bg); border-color: var(--tint-ok-line); color: var(--pass-text); }
.mkp.done b { color: var(--ink); }
.mkp.now { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
.mkp.now small { color: var(--tint-on-dark); }
.mkp.now .ic { color: var(--water-short-top); }
.mkp.ahead .ic { color: var(--ink-secondary); }
.span-bar.dark i { background: var(--ink); }
.cols[data-cols="1.35:1"] { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
.cols[data-cols="1.6:1"] { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 24px; }
.cols[data-cols="1.4:1"] { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 24px; }
.cols[data-cols="1:1.1"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 24px; }
.cols[data-cols="1:1.05"] { gap: 24px; }

/* The bank is loading (F04): a bar with no percentages, as the network file size is unknown. */
.load-bar { height: 8px; border-radius: var(--r-pill); background: var(--line); overflow: hidden; margin-top: 18px; max-width: 320px; }
.load-bar i { display: block; height: 100%; width: 40%; border-radius: var(--r-pill); background: var(--pass); }
@media (prefers-reduced-motion: no-preference) {
  @keyframes pk-load { from { transform: translateX(-100%); } to { transform: translateX(260%); } }
  .load-bar i { animation: pk-load var(--motion-wave) ease-in-out infinite; }
}

/* One column below 900px, repeated here on purpose: the v3 ratio rules above
   (.cols[data-cols=…]) come after the first copy and would win at equal
   specificity, leaving two narrow columns on a phone. */
@media (max-width: 900px) { .cols, .cols[data-cols] { grid-template-columns: minmax(0, 1fr); } }
/* The caption under a flask wraps rather than overflowing: with five narrow flasks
   “over the line” does not fit on one line. */
.tk-sub { white-space: normal; text-align: center; line-height: 1.25; max-width: 100%; }

/* The reading text stays next to the questions while they are paged through (W03). */
@media (min-width: 901px) {
  .task3 .tx-wrap { position: sticky; top: 96px; align-self: start; }
  .task3 .tx-wrap .text-card { max-height: calc(100vh - 150px); overflow-y: auto; }
}
@media (max-width: 560px) { .prova-head .pill:not(.pill-dark) { display: none; } }

/* ---- product entry v3 (W1, A03–A15) ----------------------------------------- */
.landing3 .land-h { font-size: 52px; margin-top: 12px; }
@media (max-width: 900px) { .landing3 .land-h { font-size: 38px; } }
@media (max-width: 560px) { .landing3 .land-h { font-size: 32px; } }
.btn-row.center-y { align-items: center; }
/* A note beside the button (W04) is centred on it; its usual top margin would
   push it below the button's middle. Narrow, the button fills the row and the
   note goes under it, centred, as under the phone's button. */
.btn-row.center-y > .note-sm { margin-top: 0; }
@media (max-width: 560px) { .btn-row.center-y > .note-sm { width: 100%; text-align: center; } }
/* A quiet link under a row of content-width buttons starts where the row
   starts: centred in the column it lines up with nothing. Narrow, the button
   is full width and the link stays centred under it. */
@media (min-width: 561px) { .btn-row + .link-quiet { align-self: flex-start; } }
.exam-list.two { flex-direction: row; margin-top: 0; }
.exam-list.two > * { flex: 1; min-width: 0; }
@media (max-width: 700px) { .exam-list.two { flex-direction: column; } }
.landing3 .lrows { counter-reset: step; }
.step-n { counter-increment: step; width: 34px; flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 18px; color: var(--accent-ink); }
.step-n::before { content: counter(step, decimal-leading-zero); }
.onb-top { display: flex; align-items: center; gap: 12px; text-align: start; }
.onb-top b { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 17px; }
/* Onboarding step dots: done steps are dark dots, the current one a dark
   pill, future ones light dots; no “2 of 5” count. */
.onb-dots { display: inline-flex; align-items: center; gap: 5px; margin-inline-end: auto; }
/* v3: the dots sit right after the word “Setup”, not at the right edge. */
.onb-top:has(.onb-dots) b { flex: none; margin-inline-end: -2px; }
.onb-dots i { width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--line-strong); }
.onb-dots i.on { background: var(--ink); }
.onb-dots i.now { width: 18px; background: var(--ink); }
.vf-big { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.vf-big .btn { text-transform: capitalize; }
.pickrow { justify-content: space-between; }
/* v3 (A05, A06): an unselected row has no circle; only the selected one is marked. */
.pickrow .radio:not(.on) { visibility: hidden; }
.radio {
  width: 26px; height: 26px; flex: 0 0 auto; border-radius: var(--r-pill);
  border: 1.5px solid var(--line-strong); display: flex; align-items: center; justify-content: center;
}
.radio.on { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
.radio .ic { width: 15px; height: 15px; }
.koi-hero-sm { width: 150px; height: 150px; object-fit: contain; display: block; margin-top: 16px; }
.big-days { font-family: var(--font-display); font-weight: 800; font-size: 20px; white-space: nowrap; }
/* B01·s3: the nearest sitting as a line: icon 22, “Next sitting 3 December” 16,
   and “closes …” 13 on the right. */
.next-line { display: flex; align-items: center; gap: 12px; padding: 16px; border-radius: var(--r-card); text-align: start; }
.next-line .nl-ic { display: flex; color: var(--pass-text); }
.next-line .nl-ic .ic { width: 22px; height: 22px; }
.next-line b { flex: 1; font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.next-line .nl-v { font-size: 13px; color: var(--ink-secondary); white-space: nowrap; }
/* A09: a 12.5 caption without caps, three time options spread evenly across
   the full width, and “I will decide” dashed, centred under them. */
.hour-k { display: block; font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--ink-secondary); margin: 16px 4px 8px; }
.hour-pills { display: flex; gap: 8px; }
.hour-pills .lang-pill { flex: 1; justify-content: center; font-size: 15px; padding: 12px 0; }
.hour-own { display: flex; justify-content: center; margin-top: 10px; }
.hour-own .lang-pill.own { font-size: 13.5px; padding: 9px 14px; background: none; border: 1.5px dashed var(--line-strong); box-shadow: none; gap: 7px; }
.hour-own .lang-pill.own .ic { width: 15px; height: 15px; }
.oauth { display: flex; flex-direction: column; gap: 10px; }
.or-line { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--ink-secondary); margin: 12px 0; }
.or-line::before, .or-line::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.form-card .field { border-radius: var(--r-input); background: var(--paper-card); border: 1px solid var(--line-strong); }
/* Sign-in, sign-up, reset (A11–A14): the fields sit directly on the paper, with no
   card; a field is 18 glass with a 15.5 line, and a 12.5 label above it. */
.form-card.bare { background: none; border: 0; box-shadow: none; padding: 0; -webkit-backdrop-filter: none; backdrop-filter: none; }
.form-card.bare .f-label { font-size: 12.5px; margin: 8px 4px 6px; }
.form-card.bare .field { border-radius: var(--r-field); padding: 15px 16px; font-size: 15.5px;
  background: var(--glass-light); border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow); }

/* Landing as a grid (W1 and showcase 02): on wide, the text and button on the left
   and a sample of flasks on the right; on narrow, text, flasks, button, as on the phone. */
.land-grid {
  display: grid; gap: 20px; align-items: start;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  grid-template-areas: "text tanks" "exams tanks" "cta tanks";
}
.lg-text { grid-area: text; } .lg-tanks { grid-area: tanks; } .lg-cta { grid-area: cta; }
.lg-exams { grid-area: exams; }
/* L5: the tiles carry the country large and the exam under it in accent; an exam
   not open yet says so in the quiet ink. */
.country-card .cc-country { display: block; font-family: var(--font-display); font-weight: 800; font-size: 24px; color: var(--ink); }
.country-card .cc-exam { display: block; margin-top: 6px; font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--accent-ink); }
.country-card .cc-exam.soon { color: var(--ink-secondary); }
.lg-tanks .note-sm { margin-top: 10px; }
.lg-cta .btn-block { max-width: 420px; }
.lg-cta .note-sm { text-align: start; }
/* W1: on wide the button is content-width, and the “no account” line sits next to it. */
@media (min-width: 901px) {
  .lg-cta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
  .lg-cta .btn-block { width: auto; }
  .lg-cta .note-sm { margin: 0; }
  .lg-tanks { align-self: stretch; }
}
@media (max-width: 900px) {
  /* On narrow the countries come right after the button: the main message, “for
     every language”, must be on the first screen, the sample flasks after it. */
  .land-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "text" "exams" "cta"; }
  /* L5·390: no example on the narrow page; the tiles and the button are the page. */
  .lg-tanks { display: none; }
  .lg-cta .btn-block { max-width: none; }
  .lg-cta .note-sm { text-align: center; }
}
/* Country card on the landing (W1): the country large, the exam on the right in
   accent, the purpose and form of the exam as lines under them. */
.country-card { align-items: flex-start; }
.country-card .cc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.country-card .cc-top b { font-family: var(--font-display); font-weight: 800; font-size: 20px; }
.country-card .cc-badge { font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--accent-ink); }
.country-card .ex-s { font-size: 14px; color: var(--ink-secondary); }
.country-card .cc-shape { font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink); margin-top: 6px; }
.country-card.locked .cc-badge { color: var(--ink-secondary); }
.country-card .ex-lock { margin-top: 2px; }

/* A01: a 128 mascot in a 148 ring with a soft 116 halo (no glass disc), a
   trial-days pill, one glass list of exams. */
.koi-ring {
  position: relative; width: 148px; height: 148px; margin: 22px auto 0; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--tint-state-ring);
}
.koi-ring::before { content: ""; position: absolute; inset: 16px; border-radius: var(--r-pill); background: var(--tint-state-halo); }
.koi-ring img { position: relative; width: 128px; height: 128px; object-fit: contain; }
.pill-glass { display: inline-flex; align-items: center; gap: 8px; background: var(--glass-pill); }
.pill .dot.teal { background: var(--pass); }
.solo.center .pill-glass { margin-inline: auto; }
.ex-group { padding: 4px 18px; border-radius: var(--r-card); text-align: start; }
.ex-row {
  display: flex; align-items: center; gap: 14px; padding: 14px 0; color: inherit; text-decoration: none;
  min-height: var(--a11y-tap-target-min);
}
.ex-row + .ex-row { border-top: 1px solid var(--line); }
.ex-row .ex-t b { font-size: 16px; }
.ex-row .ex-t small { font-size: 13px; color: var(--ink-secondary); }

/* A03: a text line (18) and a statement (15); the selected answer is a dark pill. */
.q-src { font-size: 18px; line-height: 1.5; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.q-said { margin-top: 12px; font-size: 15px; line-height: 1.5; }
.vf-big .btn.on { background: var(--ink); border-color: var(--ink); color: var(--paper-card); box-shadow: none; }

/* A05: the “just looking” tile is orange, an exit from setup; the selected goal is a teal card. */
.lrow-ic.koi { background: var(--warm-bg); color: var(--accent-ink); }
/* v3 (A05, B04): a light-teal card with a thin teal edge, a tick without a circle,
   ink text at 13.5. */
.chosen-card {
  display: flex; align-items: flex-start; gap: 12px; padding: 13px 15px; border-radius: var(--r-card-md);
  background: var(--pass-bg); border: 1px solid var(--tint-ok-line); color: var(--ink); font-size: 13.5px; line-height: 1.5;
}
.cc-ic { flex: 0 0 auto; color: var(--pass-text); display: flex; }
.cc-ic .ic { width: 18px; height: 18px; }

/* Mascot with a speech bubble (A05·s3, A09·s2): a 170 × 150 frame, a 138 mascot at
   the bottom, a glass bubble at the top right tilted 4°. */
.koi-say { position: relative; width: 170px; height: 150px; margin: 14px auto 0; display: flex; align-items: flex-end; justify-content: center; }
.koi-say .koi-hero-sm { margin-top: 0; width: 138px; height: 138px; object-fit: contain; }
.koi-bubble {
  position: absolute; top: 6px; inset-inline-end: -6px; transform: rotate(4deg);
  padding: 8px 12px; border-radius: var(--r-card-sm); background: var(--glass-pill); border: 1px solid var(--glass-pill-border);
  box-shadow: var(--glass-light-shadow); font-family: var(--font-display); font-weight: 800; font-size: 13px; white-space: nowrap;
}
/* The thinking koi carries its own question mark at the top right: the
   bubble goes to the top left so it does not cover it (A09·s2). */
.koi-say.left .koi-bubble { inset-inline-end: auto; inset-inline-start: -30px; transform: rotate(-4deg); }
/* “7 days” on one line: the number 34, the word 15, muted. */
.days-card { display: flex; align-items: center; gap: 14px; padding: 16px 18px; border-radius: var(--r-card); text-align: start; }
.dc-big { display: inline-flex; align-items: baseline; flex: 0 0 auto; line-height: 1; gap: 4px; }
.dc-big b { font-family: var(--font-display); font-weight: 800; font-size: 34px; }
.dc-big small { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink-secondary); }
.dc-t { font-family: var(--font-body); font-weight: 600; font-size: 14px; line-height: 1.45; color: var(--ink-secondary); }
.dc-t b { color: var(--ink); }

/* A07: the segment full width and on one line; sittings are pressable rows. */
.seg.seg-fill { display: flex; max-width: none; margin-top: 14px; }
.seg.seg-fill button { flex: 1; white-space: nowrap; font-family: var(--font-display); font-weight: 800; font-size: 13.5px; }
.sit-pick { display: flex; flex-direction: column; gap: 10px; }
button.sit3 { width: 100%; font: inherit; text-align: start; cursor: pointer; border: 0; color: inherit; }
.sit3.pick.on { border: 0; }
.sit3.pick.on .sit3-d small, .sit3.pick.on .sit3-s { color: var(--tint-on-dark); }
/* A07 (v3): row 14 / 24, a 52 × 54 tile with the day at 19 and the month at 11 in
   caps; the selected one is dark glass with a white tick without a circle. */
.sit3.pick { padding: 14px; gap: 14px; border-radius: var(--r-row); }
.sit3.pick .sit3-d { width: 52px; height: 54px; justify-content: center; padding: 0; border-radius: 16px; background: var(--tint-teal-tile); }
.sit3.pick .sit3-d b { font-size: 19px; }
.sit3.pick .sit3-d small { font-size: 11px; text-transform: uppercase; margin-top: 5px; }
.sit3.pick .sit3-n { font-size: 16px; }
.sit3.pick .sit3-s { font-size: 12.5px; }
.sit3.pick.on .radio.on { background: none; color: var(--paper-card); border: 0; }
.sit3.pick.on .radio.on .ic { width: 18px; height: 18px; }
.sit3.pick.on .sit3-d { background: var(--tint-on-dark-fill); color: var(--paper-card); }
.sit3.pick.on .sit3-n { color: var(--paper-card); }
.sit3.closed { opacity: .55; }
.next-open { padding: 16px 18px; border-radius: var(--r-card); display: flex; flex-direction: column; gap: 4px; }
.next-open .no-date { font-family: var(--font-display); font-weight: 800; font-size: 26px; }

/* A09: “I will decide” is a dashed pill with a clock. */
.lang-pill.own { border-style: dashed; display: inline-flex; align-items: center; gap: 6px; }
.lang-pill.own .ic { width: 15px; height: 15px; }

/* Sign-in: “Forgot password?” on the right under the password (A12), the Apple mark, the email address (A13). */
.forgot-link { align-self: flex-end; margin: -12px 0 -4px; }
/* 44px tap height from padding; negative block margins keep the row where it
   is drawn (“Change”, “Forgot password?” on the sign-in form). */
.link-accent { border: 0; background: none; padding: 12px 0; margin-block: -8px; cursor: pointer; font: inherit; font-weight: 700; font-size: 14px; color: var(--accent-ink); }
.form-card { display: flex; flex-direction: column; }
.ic-apple { fill: currentColor; stroke: none; width: 18px; height: 18px; margin-inline-end: 8px; vertical-align: -3px; }
.sent-to { padding: 12px 16px; border-radius: var(--r-card-sm); display: flex; flex-direction: column; gap: 2px; text-align: start; }
.sent-to b { font-size: 16px; overflow-wrap: anywhere; }

/* ---- money and states v3 (E01–E11, F01–F12, G03–G07) -------------------------- */
.pricing3 .display { font-size: 40px; margin-top: 10px; }
@media (max-width: 560px) { .pricing3 .display { font-size: 30px; } }
.cmp { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.cmp-card { padding: 20px; border-radius: var(--r-card); display: flex; flex-direction: column; gap: 6px; }
.cmp-card.warm { background: var(--fail-bg); border: 1px solid var(--tint-no-line); }
.cmp-n { font-family: var(--font-display); font-weight: 800; font-size: 40px; line-height: 1; }
.cmp-card.warm .cmp-n { color: var(--fail-ink); }
.cmp-card span { font-size: 13.5px; line-height: 1.45; color: var(--ink-secondary); }
.dglass.cmp-card span { color: var(--tint-on-dark); }
@media (max-width: 560px) { .cmp { grid-template-columns: 1fr; } }
.tl3 { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; }
.tl3 li {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px;
  padding-block: 0 16px; padding-inline: 26px 0;
}
.tl3 li::before { content: ''; position: absolute; inset-inline-start: 4px; top: 6px; width: 10px; height: 10px; border-radius: var(--r-pill); background: var(--line-strong); }
.tl3 li::after { content: ''; position: absolute; inset-inline-start: 8px; top: 20px; bottom: 0; width: 2px; background: var(--line); }
.tl3 li:last-child { padding-bottom: 0; }
.tl3 li:last-child::after { display: none; }
.tl3 li.now::before { background: var(--pass); }
.tl3 li.done::before { background: var(--pass); }
.tl3 li.exam::before { background: var(--ink); }
.tl3 li.buy::before { background: var(--accent); }
.tl3 b { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.tl3 span { grid-column: 1; font-size: 13.5px; color: var(--ink-secondary); }
.tl3 em { grid-column: 2; grid-row: 1 / span 2; align-self: center; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.faq { display: flex; flex-direction: column; gap: 14px; margin-top: 10px; }
.faq p { display: flex; flex-direction: column; gap: 3px; }
.faq b { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.faq span { font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.lrow-v.strong { font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--ink); }
.order .lrow { padding: 14px 0; }
.lrows.steps { counter-reset: step; }
.qstrip.wide { width: 100%; }
.acc-pills { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.acc-opt3 { justify-content: center; padding: 22px 14px; border-radius: var(--r-card-md); }
.acc-opt3 .opt-text { flex: 0 1 auto; font-family: var(--font-display); font-weight: 800; font-size: 28px; text-align: center; }
.acc-glyph {
  width: 34px; height: 34px; flex: 0 0 auto; border-radius: var(--r-tile); background: var(--tint-teal-tile);
  display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 800; font-size: 20px; color: var(--pass-text);
}
.win3 .win-koi { justify-content: flex-start; }
.win3 .win-koi img { width: 170px; height: 170px; }
/* Narrow screen: button labels wrap and the action row stacks: “How the
   transfer went” next to “Review the answers” does not fit in 375 points. */
@media (max-width: 560px) {
  .btn { white-space: normal; text-align: center; }
  .act-row { flex-wrap: wrap; }
  .act-row > .btn { flex: 1 1 100%; }
}

/* ══ Motion v3 ═══════════════════════════════════════════════════════════════

   Taken from the styles of the sheet `design/handoff-v3/PrepKoi v3 Full Sheet.dc.html`
   by the numbers, not by eye; all durations and curves are tokens of the motion group.

   · Screen entrance: every top-level block rises (opacity and a 14 px shift over
     .6 s), staggered by 55 ms. markRise() in app.js picks the blocks and sets
     data-rise and the --i index; no order-based selectors.
   · Every flask on the screen (data-fill) fills from the bottom after
     --motion-fill-delay, then the water breathes.
   · A button responds to a finger by shrinking to .97, to a cursor by lifting a
     pixel; the orange one gets a sheen sweep once per cycle.
   · A card under the cursor lifts by 2 px, the current mark breathes with a ring,
     the sheet slides up over the scrim, the toast drops from the top, the state
     screen icon pops and its mark draws itself.
   · The recording dot spreads a ring, the streak flame flickers, the “live” dot blinks.

   All of this switches off under “reduce motion”. The colour response stays even
   then: it is not decoration but confirmation that the press registered. */

.btn, .opt, .vf-b, .lang-pill, .tp-btn, .icon-btn, .seg a, .tabbar a, .all-grid button,
.pcard3, .exam-card, a.lrow, a.glass, .switch, .switch i, .switch::before {
  transition: transform var(--motion-press) var(--motion-ease-enter),
              filter var(--motion-press) var(--motion-ease-enter),
              background-color var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease),
              color var(--motion-fast) var(--motion-ease),
              box-shadow var(--motion-press) var(--motion-ease-enter),
              inset-inline-start var(--motion-lift) var(--motion-ease-enter),
              opacity var(--motion-fast) var(--motion-ease);
}
.btn-primary { position: relative; overflow: hidden; isolation: isolate; }

@media (prefers-reduced-motion: no-preference) {
  @keyframes pk-rise { from { opacity: 0; transform: translateY(var(--motion-enter-shift)); } to { opacity: 1; transform: none; } }
  @keyframes pk-fill { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(-14px 0 0 0); } }
  /* The glint: at rest past the left edge for most of the cycle, then one quick pass
     (--motion-shine-sweep of --motion-shine, 0.9 of 5.5 s) that speeds up and slows down,
     like light caught by a moving surface rather than a slab sliding across. */
  @keyframes pk-shine {
    0%, 83.6% { transform: translateX(-180%) rotate(22deg); animation-timing-function: cubic-bezier(.5, 0, .25, 1); }
    100% { transform: translateX(560%) rotate(22deg); }
  }
  @keyframes pk-pulse {
    0%, 100% { box-shadow: 0 0 0 0 var(--tint-pulse); }
    50% { box-shadow: 0 0 0 7px var(--tint-pulse-end); }
  }
  @keyframes pk-sheet { from { transform: translateY(105%); } to { transform: none; } }
  @keyframes pk-fade { from { opacity: 0; } to { opacity: 1; } }
  @keyframes pk-drop { from { opacity: 0; transform: translateY(-18px) scale(.97); } to { opacity: 1; transform: none; } }
  @keyframes pk-lift-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-12px) scale(.98); } }
  @keyframes pk-pop { 0% { transform: scale(.6); opacity: 0; } 70% { transform: scale(1.08); opacity: 1; } 100% { transform: scale(1); } }
  @keyframes pk-draw { to { stroke-dashoffset: 0; } }
  @keyframes pk-rec {
    0%, 100% { box-shadow: 0 0 0 0 var(--tint-rec); }
    50% { box-shadow: 0 0 0 16px var(--tint-rec-end); }
  }
  @keyframes pk-flame {
    0%, 100% { transform: scale(1) rotate(0); }
    40% { transform: scale(1.08, 1.12) rotate(-3deg); }
    70% { transform: scale(.97, 1.04) rotate(2deg); }
  }
  @keyframes pk-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
  @keyframes pk-caustic { from { transform: translate(-4%, 2%) scale(1); } to { transform: translate(5%, -4%) scale(1.12); } }
  @keyframes pk-glint { 0%, 100% { transform: scale(.4); opacity: 0; } 50% { transform: scale(1); opacity: 1; } }
  @keyframes pk-select { 0% { transform: scale(1); } 45% { transform: scale(.975); } 100% { transform: scale(1); } }

  /* Screen entrance. */
  [data-rise] {
    animation: pk-rise var(--motion-enter) var(--motion-ease-enter) both;
    animation-delay: calc(var(--i, 0) * var(--motion-stagger));
  }
  /* The flask fills after --motion-fill-delay, and then the water breathes. */
  [data-fill] .tk-water {
    animation: pk-fill var(--motion-fill) var(--motion-fill-delay) var(--motion-ease-fill) both,
               tk-swell var(--motion-swell) calc(var(--motion-fill-delay) + var(--motion-fill)) ease-in-out infinite alternate;
  }
  [data-fill] .tk.short .tk-water { animation: pk-fill var(--motion-fill) var(--motion-fill-delay) var(--motion-ease-fill) both; }
  [data-fill] .tk-range {
    animation: pk-fade var(--motion-fill) var(--motion-fill-delay) var(--motion-ease-fill) both;
  }

  /* Buttons: finger and cursor. */
  :is(.btn, .vf-b, .lang-pill, .tp-btn, .icon-btn, .all-grid button):not(:disabled):active {
    transform: scale(var(--motion-press-scale)); filter: brightness(.97);
  }
  /* The sheen rests past the left edge and the animation fills backwards:
     otherwise it sits in the first third of the button during
     --motion-shine-delay, which restarts with every button rendered, that
     is, on every screen. */
  /* A narrow band, three times the button's height so its ends never show, with a soft
     falloff around a bright warm core: warm white laid over the orange, so it reads as light
     on a glossy surface. Added light (plus-lighter) turned the flanks yellow. */
  .btn-primary::after {
    content: ""; position: absolute; top: -100%; height: 300%; left: 0; width: 18%; min-width: 34px; z-index: -1;
    background: linear-gradient(90deg, transparent 0%, var(--tint-shine-edge) 30%, var(--tint-shine-core) 50%,
      var(--tint-shine-edge) 70%, transparent 100%);
    transform: translateX(-180%) rotate(22deg);
    animation: pk-shine var(--motion-shine) var(--motion-shine-delay) linear infinite backwards;
    pointer-events: none;
  }
  .btn-primary:disabled::after { content: none; }

  /* Choosing an option responds with a short “breath” rather than an instant swap. */
  .opt.on, .vf-b.on, .lang-pill.on, .all-grid button.done, .fit-opt.on { animation: pk-select var(--motion-press) var(--motion-ease-enter); }

  /* The current mark breathes with a ring: today's weekday, the current
     question, the current bubble on the answer sheet (as on the phone). */
  .wdot.today .c, .all-grid button.cur, .pulse, .bub.cur { animation: pk-pulse var(--motion-pulse) ease-in-out infinite; }

  /* Sheet, scrim, toast. */
  /* backwards, not both: a finished fade must stop applying, or the sheet's
     backdrop blur stays off and the page shows through the sheet. */
  .pk-scrim { animation: pk-fade var(--motion-scrim) backwards; }
  .pk-sheet { animation: pk-sheet var(--motion-sheet) var(--motion-ease-sheet) both; }
  .pk-toast { animation: pk-drop var(--motion-drop) var(--motion-ease-sheet) both; }
  .pk-toast.out { animation: pk-lift-out var(--motion-base) var(--motion-ease-out) both; }
  .pk-banner[data-rise] { animation-name: pk-drop; }

  /* The state screen icon: pops in and draws its mark. */
  .state-ic { animation: pk-pop var(--motion-pop) var(--motion-pop-delay) var(--motion-ease-sheet) both; }
  .state-ic .ic path {
    stroke-dasharray: 60; stroke-dashoffset: 60;
    animation: pk-draw var(--motion-draw) var(--motion-draw-delay) ease-out forwards;
  }

  /* Recording, streak, “live”. */
  .tp-btn.rec, .rec-dot { animation: pk-rec var(--motion-rec) ease-out infinite; }
  .run-chip .ic { transform-origin: 50% 90%; animation: pk-flame var(--motion-flame) ease-in-out infinite; }
  .pill-dark .dot, .pill .dot { animation: pk-blink var(--motion-blink) steps(1) infinite; }

  /* Full flask: glints on the water and sparks at the surface. */
  .tk-caustic { animation: pk-caustic var(--motion-caustic) ease-in-out infinite alternate; }
  .tk-spark { animation: pk-glint var(--motion-glint) ease-in-out infinite; }
  .tk-spark.s2 { animation-delay: .8s; }
  .tk-spark.s3 { animation-delay: 1.6s; }
}

/* ---- finger response on everything pressable ---------------------------------
   Not only buttons: list rows, cards, answer options, answer-sheet bubbles, links.
   A press with no response reads as “did not work”, and the person presses again.
   Three levels by target size: buttons and small targets shrink to .97 (the
   press-scale token), large cards and rows to .985 (otherwise the edge “jumps”),
   links in text fade to .6 and do not move. The selectors have zero weight
   (`:where`), so any component's own rule wins. */
:where(a[href], button, [role="button"], [role="switch"], [role="radio"], label[for], summary) {
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  /* A double tap on a button neither zooms the page nor waits for a second tap:
     in the app a button responds at once. */
  touch-action: manipulation;
  transition: transform var(--motion-press) var(--motion-ease-enter),
              filter var(--motion-press) var(--motion-ease-enter),
              opacity var(--motion-fast) var(--motion-ease),
              background-color var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease),
              color var(--motion-fast) var(--motion-ease),
              box-shadow var(--motion-press) var(--motion-ease-enter);
}
:where(a[href], button, [role="button"], [role="switch"], [role="radio"], label[for], summary):not(:disabled):active {
  filter: brightness(.96);
}
/* A long press on a button, tab or answer option is a press, not a text selection
   and not an “open link” menu: that is how the app behaves.
   Links inside text are left alone: people copy them. */
:where(button, .btn, .tabbar a, .opt, .lrow, .pickrow, .seg a, .chip, [role="radio"], [role="switch"]) {
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
:where(a:not([class]), .link-quiet, .link-accent, .link-danger, .nav-link, .info-foot, .meta, .bn-act, .brand, .foot-links a):active {
  opacity: .6; filter: none;
}
@media (prefers-reduced-motion: no-preference) {
  :where(button, [role="button"], [role="switch"], a.btn, a.icon-btn, .avatar, .run-chip, .exam-chip,
         .bub:not(.ro), .let, .acc-key, .all-grid button, .tk-link):not(:disabled):active {
    transform: scale(var(--motion-press-scale));
  }
  :where(a.lrow, button.lrow, .pickrow, .opt, .fit-opt, .sit3, a.glass, .hint-btn, .pcard3, .exam-card,
         .mock-next-card, .info-card, .replay-row, .tabbar a, .seg a):not(:disabled):active {
    transform: scale(var(--motion-press-scale-card));
  }
}

/* Cursor effects only where there is a cursor: on a phone “hover” sticks after a
   tap and leaves the card lifted. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .btn:not(:disabled):hover, .tp-btn:hover, .icon-btn:hover { transform: translateY(-1px); filter: brightness(1.04); }
  .opt:not(:disabled):hover, .pcard3:hover, .exam-card:hover, a.glass:hover, a.lrow:hover {
    transform: translateY(-2px);
  }
}

/* The streak flame in the header pill. */
.run-chip .ic { width: 14px; height: 14px; color: var(--accent-to); flex: 0 0 auto; }

/* Toast: one line over the page, top centre. */
.pk-toasts {
  position: fixed; top: 14px; left: 0; right: 0; z-index: 60; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 0 14px;
}
/* Phone: below the full-width header, so a toast does not cover the task title. */
@media (max-width: 560px) { .pk-toasts { top: calc(78px + env(safe-area-inset-top)); } }
.pk-toast {
  pointer-events: auto; display: flex; align-items: center; gap: 10px; max-width: 460px;
  padding: 11px 16px; border-radius: var(--r-pill);
  background: var(--glass-dark); color: var(--paper-card);
  -webkit-backdrop-filter: var(--glass-dark-blur); backdrop-filter: var(--glass-dark-blur);
  border: 1px solid var(--glass-dark-border); box-shadow: 0 18px 36px -18px var(--tint-toast-shadow);
  font-family: var(--font-display); font-weight: 800; font-size: 14px;
}
.pk-toast-dot { width: 8px; height: 8px; border-radius: var(--r-pill); flex: 0 0 auto; background: var(--water-pass-top); }
.pk-toast.no .pk-toast-dot { background: var(--water-short-top); }

/* Banner v3 (W28): an icon in a tile, a title and a line, the action on the right.
   Five tones: dark is no network; teal is done; red is a refusal; warm is a
   deadline or a streak at risk; beige is neutral (sign-in expired). */
.pk-banner {
  display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-radius: var(--r-card-sm);
  background: var(--paper-warm); border: 1px solid var(--line); margin-bottom: 12px;
}
/* After a note line in plain block flow (the mock intro) a banner keeps the card
   gap above it, the same as below it. */
.note-sm + .pk-banner { margin-top: var(--sp-gap); }
.pk-banner .bn-ic {
  width: 36px; height: 36px; flex: 0 0 auto; border-radius: var(--r-tile);
  display: flex; align-items: center; justify-content: center; background: var(--paper-card); color: var(--ink);
}
.pk-banner .bn-ic .ic { width: 17px; height: 17px; }
.pk-banner .bn-t { flex: 1; min-width: 0; }
.pk-banner .bn-t b { display: block; font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink); }
.pk-banner .bn-t span { display: block; font-size: 13.5px; color: var(--ink-secondary); }
.pk-banner .bn-act {
  flex: 0 0 auto; font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--ink);
  background: none; border: 0; padding: 6px 2px; cursor: pointer; text-decoration: none;
}
.pk-banner.ok { background: var(--pass-bg); border-color: var(--tint-ok-line); }
.pk-banner.ok .bn-ic, .pk-banner.ok .bn-act { color: var(--pass-text); }
.pk-banner.no { background: var(--fail-bg); border-color: var(--tint-no-line); }
.pk-banner.no .bn-ic, .pk-banner.no .bn-act { color: var(--fail-ink); }
.pk-banner.warm { background: var(--warm-bg); border-color: var(--tint-no-line); }
.pk-banner.warm .bn-ic, .pk-banner.warm .bn-act { color: var(--accent-ink); }
.pk-banner.dark { background: var(--ink); border-color: var(--ink); padding: 12px 18px; }
.pk-banner.dark .bn-ic { background: none; color: var(--paper-card); width: 20px; }
.pk-banner.dark .bn-t b { color: var(--paper-card); font-size: 14.5px; }
.pk-banner.dark .bn-act { color: var(--water-pass-top); }
/* On a narrow screen the action word goes under the text: on the right it squeezed
   the title and the line into a column three words wide. It starts on the text's
   own edge (icon plus gap), with no side padding. */
@media (max-width: 480px) {
  .pk-banner { flex-wrap: wrap; row-gap: 2px; }
  .pk-banner .bn-act { flex: 0 0 calc(100% - 50px); margin-inline-start: 50px; text-align: start; padding-inline: 0;
    min-height: var(--a11y-tap-target-min); display: inline-flex; align-items: center; margin-block: -6px; }
  .pk-banner.dark .bn-act { flex-basis: calc(100% - 34px); margin-inline-start: 34px; }
}
.closes-card .cc-n { margin-inline-end: 2px; }

/* Confirmation sheet over the scrim. */
.pk-scrim { position: fixed; inset: 0; z-index: 70; background: var(--tint-scrim); display: flex; align-items: flex-end; justify-content: center; }
.pk-sheet {
  width: min(560px, 100%); margin: 0 10px max(10px, env(safe-area-inset-bottom)); padding: 22px 22px 18px; border-radius: var(--r-panel);
  background: var(--glass-light); border: 1px solid var(--glass-light-border);
  -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
  box-shadow: var(--glass-light-shadow);
}
.pk-sheet .sh-ic {
  width: 40px; height: 40px; border-radius: var(--r-tile); display: flex; align-items: center; justify-content: center;
  background: var(--fail-bg); color: var(--fail-ink); margin-bottom: 16px;
}
.pk-sheet .sh-ic .ic { width: 18px; height: 18px; }
.pk-sheet h2 { font-family: var(--font-display); font-weight: 800; font-size: 26px; letter-spacing: -.02em; margin: 0 0 8px; }
.pk-sheet p { margin: 0 0 14px; color: var(--ink-secondary); }
.pk-sheet .sh-note { padding: 12px 14px; border-radius: var(--r-input); background: var(--paper-warm); font-size: 14px; margin-bottom: 18px; }
.pk-sheet .sh-acts { display: flex; gap: 10px; }
.pk-sheet .sh-acts .btn-primary { flex: 1; }
/* On a narrow screen the secondary action is a quiet link under the primary (E06),
   not a second big button: the “keep” decision must carry more weight. */
@media (max-width: 420px) {
  .pk-sheet .sh-acts { flex-direction: column; gap: 4px; }
  .pk-sheet .sh-acts .btn-quiet {
    background: none; border: 0; box-shadow: none; color: var(--ink-secondary); font-size: 15px;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
}
@media (min-width: 700px) { .pk-scrim { align-items: center; } .pk-sheet { margin: 0; } }

/* A field with an error: a red border and a line under the field, not a paragraph
   at the bottom of the form. A clear cross inside the field (W28); the field
   shakes “no” once when the error appears. */
.field.bad { border-color: var(--fail); border-width: 2px; box-shadow: 0 0 0 3px var(--tint-no-line); }
.field-err { display: flex; align-items: center; gap: 6px; margin: 6px 0 0; font-size: 13.5px; color: var(--fail-ink); }
.field-err .ic { width: 15px; height: 15px; flex: 0 0 auto; }
/* Confirmation under a field (E10): the same rhythm as an error, a different colour. */
.field-ok { display: flex; align-items: center; gap: 6px; margin: 8px 0 0; font-size: 13.5px; font-weight: 700; color: var(--pass-text); }
.field-ok .ic { width: 15px; height: 15px; flex: 0 0 auto; }
/* The part's clock has run out: the pill turns red, the sheet is not taken away (practice). */
.pill-dark.late { background: var(--fail-ink); border-color: var(--fail-ink); }
.pill-dark .pc-t { font-variant-numeric: tabular-nums; }

/* The primary button and the quiet link under it, stacked (A04, W17). */
.btn-col { display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
.btn-col .link-quiet { align-self: center; }
.save-card .oauth { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 4px; }
.save-card .link-quiet { display: flex; margin-inline: auto; }

/* Sittings (B06): closed registration is muted; a countdown to the deadline. */
.sit3.closed { opacity: .6; }
.closes-card .cc-row { display: flex; align-items: baseline; gap: 10px; margin: 4px 0 12px; color: var(--ink-secondary); }
.closes-card .cc-n { font-family: var(--font-display); font-weight: 800; font-size: 44px; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }

/* The recording did not arrive (C02·e): a light state in place of the player, centred. */
.state-card.no-audio { align-items: center; text-align: center; padding: 28px 22px 18px; gap: 10px; margin-top: 0; }
.state-card.no-audio .pk-banner { text-align: start; width: 100%; }
.state-card.no-audio .btn { align-self: stretch; }
.state-card.no-audio .sc-p { margin: 0; color: var(--ink-secondary); }
.field-wrap { position: relative; display: block; }
.field-wrap.bad .field { padding-inline-end: 46px; }
.field-x {
  position: absolute; inset-inline-end: 4px; top: 50%; transform: translateY(-50%);
  width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min);
  display: flex; align-items: center; justify-content: center;
  border: 0; background: none; color: var(--fail-ink); cursor: pointer; border-radius: var(--r-pill);
}
.field-x .ic { width: 16px; height: 16px; }
/* Nothing to clear, so no cross. */
.field-wrap .field:placeholder-shown ~ .field-x { display: none; }
.field-x:focus-visible { outline: 3px solid var(--accent); outline-offset: -4px; }
@keyframes pkShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); } 40% { transform: translateX(7px); }
  60% { transform: translateX(-5px); } 80% { transform: translateX(3px); }
}
@media (prefers-reduced-motion: no-preference) {
  .field-wrap.bad { animation: pkShake var(--motion-shake) var(--motion-ease-enter) 1; }
  /* Drill answer (C18): a wrong one shakes “no”, a right one flashes briefly. */
  .acc-opt3.wrong { animation: pkShake var(--motion-shake) var(--motion-ease-enter) 1; }
  .acc-opt3.right { animation: pk-select var(--motion-press) var(--motion-ease-enter) 1; }
}

/* Search (C1, W16): a glass pill with a magnifier. */
.pk-search {
  display: flex; align-items: center; gap: 10px; padding-inline: 16px 10px;
  min-height: calc(var(--a11y-tap-target-min) + 4px); border-radius: var(--r-pill);
  background: var(--glass-pill);
  -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
  color: var(--ink-secondary); cursor: text;
  transition: box-shadow var(--motion-press) var(--motion-ease-enter);
}
.kit .pk-search { max-width: 420px; }
.pk-search .ic { width: 16px; height: 16px; flex: 0 0 auto; }
.pk-search input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none; padding: 10px 0;
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-body-sm); color: var(--ink);
}
.pk-search input::placeholder { color: var(--ink-secondary); }
.pk-search:focus-within { box-shadow: 0 0 0 3px var(--accent), var(--glass-pill-shadow); }
.lang-rows .pickrow[hidden] { display: none; }

/* Full flask: glints on the water and three cross-shaped sparks at the surface. */
.tk-caustic {
  position: absolute; left: -30%; top: -10%; width: 160%; height: 120%; pointer-events: none;
  background: radial-gradient(38% 22% at 30% 28%, var(--tint-caustic), transparent 70%),
              radial-gradient(30% 18% at 68% 55%, var(--tint-caustic), transparent 70%),
              radial-gradient(34% 20% at 38% 82%, var(--tint-caustic), transparent 70%);
}
.tk-spark { position: absolute; top: 6px; width: 5px; height: 5px; opacity: 0; }
.tk-spark::before, .tk-spark::after { content: ""; position: absolute; background: var(--tint-glint); }
.tk-spark::before { left: 2px; top: 0; width: 1px; height: 5px; }
.tk-spark::after { left: 0; top: 2px; width: 5px; height: 1px; }
.tk-spark.s1 { left: 18%; } .tk-spark.s2 { left: 52%; top: 9px; } .tk-spark.s3 { left: 78%; top: 12px; }

/* ---- component state sheet (/kit) ------------------------------------------- */
.kit { display: flex; flex-direction: column; gap: 16px; }
.kit-sec .kicker { margin-bottom: 14px; }
.kit-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 14px; }
.kit-row.tight { gap: 6px; align-items: center; }
.kit-cell { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.kit-l { font-size: 12px; color: var(--ink-secondary); }
.kit-opts { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.kit-opts .kit-cell { align-items: stretch; }
.kit-tanks { max-width: 420px; }
.kit-tanks.sm { max-width: 260px; flex: 1; }
.kit-sheet { position: relative; min-height: 320px; border-radius: var(--r-card-sm); overflow: hidden; }
.kit-sheet .pk-scrim { position: relative; inset: auto; z-index: 0; min-height: 320px; padding-top: 40px; }
.kit-pulse { display: block; width: 34px; height: 34px; border-radius: var(--r-pill); border: 2px solid var(--accent-to); }
.kit-icons { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 10px; }
.kit-ic { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 4px; border-radius: var(--r-input); background: var(--tint-teal-tile); color: var(--pass-text); }
.kit-ic .ic { width: 22px; height: 22px; }
.kit-ic small { font-size: 11px; color: var(--ink-secondary); }
/* Press and hover, drawn static for the showcase. */
.is-press { transform: scale(var(--motion-press-scale)); filter: brightness(.97); }
.btn.is-hover { transform: translateY(-1px); filter: brightness(1.04); }
.opt.is-hover { transform: translateY(-2px); }

/* ---- block B v3: evening card, steps, own mistakes, progress, exam day ---------- */
/* Evening card (B01): the kicker and “aim” on one line, the title (22), a
   13.5 line, a white full-width “Start” without an icon; padding 18. */
.task-card.v3 { display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 22px 22px 20px; }
.task-card.v3 .tc-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; column-gap: 12px; row-gap: 2px; }
.task-card.v3 { padding: 18px; }
.task-card.v3 .tc-k { color: var(--panel-kicker); }
.task-card.v3 .tc-aim { font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--panel-accent); white-space: nowrap; }
.task-card.v3 .tc-p { font-size: 13.5px; line-height: 1.45; color: var(--panel-body); }
.task-card.v3 .tc-h { margin-top: 2px; font-size: 22px; }
.task-card.v3 .tc-p { margin-top: 0; }
.task-card.v3 .btn-block { margin-top: 10px; justify-content: center; }
.task-card.v3 .tc-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
/* Phone (B01): no part icon and no icon on the button. */
.task-card.v3 > .tc-ic, .task-card.v3 .btn-block .ic { display: none; }
/* From 600 px (W02, W13): as a row: a tile with the part icon, the text, a white
   content-width “Start” on the right. */
@media (min-width: 600px) {
  .task-card.v3 { flex-direction: row; align-items: center; gap: 18px; padding: 20px 22px; }
  .task-card.v3 > .tc-ic { display: flex; width: 56px; height: 56px; color: var(--paper-card); }
  .task-card.v3 .tc-body { flex: 1; gap: 6px; }
  /* “aim” follows the kicker: at the right edge of the text it would hang
     mid-card between the line and the button, attached to nothing. */
  .task-card.v3 .tc-top { justify-content: flex-start; column-gap: 14px; }
  .task-card.v3 .btn-block { width: auto; margin: 0; flex: 0 0 auto; padding: 13px 22px; }
  .task-card.v3 .btn-block .ic { display: inline-block; }
}
/* Home cards on a narrow screen are one width (X2). */
@media (max-width: 900px) { .today-grid { align-items: stretch; } }
/* Flask button: leads to the part's step ladder (B04). */
.tk-link { flex: 1; min-width: 0; display: flex; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; border-radius: var(--r-card-sm); }
.tk-link > .tk { flex: 1; }
.tk-link:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) {
  .tk-link { transition: transform var(--motion-fast) var(--motion-ease); }
  .tk-link:hover { transform: translateY(-2px); }
}
/* Ladder (B04): the prova name and the step in teal on one line, under them five
   full-width segments, 8 px; empty ones are pale teal. */
.step-row { padding: 12px 0; }
.step-row + .step-row { border-top: 1px solid var(--line); }
.sr-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.sr-top b { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.sr-step { font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--pass-text); white-space: nowrap; }
.step-bar { display: flex; gap: 4px; margin-top: 9px; }
.step-bar i { flex: 1; height: 8px; border-radius: var(--r-pill); background: var(--tint-state-halo); }
.step-bar i.on { background: var(--pass); }
/* Own mistakes. */
.mistake-card { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 16px 20px; border-radius: var(--r-card); }
.mc-stem { font-size: 17px; line-height: 1.5; }
.mc-why { font-size: 14.5px; line-height: 1.55; color: var(--ink-secondary); }
/* Progress: the next full run as a dark card (showcase 13). */
.mock-next-card { display: flex; align-items: center; gap: 16px; padding: 16px 18px; border-radius: var(--r-card); color: var(--paper-card); text-decoration: none; }
.mn-date { width: 52px; flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; line-height: 1; padding: 8px 0; border-radius: var(--r-input); background: var(--tint-on-dark-fill); }
.mn-date b { font-family: var(--font-display); font-weight: 800; font-size: 22px; }
.mn-date small { font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--tint-on-dark); margin-top: 3px; }
.mn-t { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.mn-t b { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.mn-t small { font-size: 13px; color: var(--tint-on-dark); }
.mock-next-card .lrow-go { color: var(--tint-on-dark); }
.centre-card .field-wrap { margin-top: 10px; }

/* ---- Block F per v3 ------------------------------------------------------------
   Win and “did not pass” are centred state screens: the mascot above the text, the
   flasks between the text and the primary button. “Share” is a round glass button
   next to the orange one (19). Result entry is four scores in a grid. */
.centered-solo.win3 .win-koi { justify-content: center; }
.centered-solo .koi-sm { align-self: center; }
.centered-solo > .glass, .centered-solo > .dglass, .centered-solo > .hint-card { width: 100%; text-align: start; }
.centered-solo > .link-quiet { display: flex; width: fit-content; margin-inline: auto; }
.btn-pair { display: flex; gap: 10px; width: 100%; align-items: center; }
.btn-pair .btn-primary { flex: 1; }
/* On a narrow screen every .btn is full width, which in a pair would give
   the quiet one the whole row and squeeze the primary. The pair shares the
   row instead: primary wider, quiet narrower, both labels on one line. */
@media (max-width: 560px) {
  .btn-pair > .btn { flex: 1 1 0; min-width: 0; padding-inline: 14px; white-space: nowrap; }
  .btn-pair > .btn-primary { flex-grow: 1.4; }
  /* The round “share” button (F06) stays round: it needs the width of its icon. */
  .btn-pair > .btn-round { flex: 0 0 58px; padding-inline: 0; }
}
.btn-round { width: 58px; height: 58px; padding: 0; border-radius: var(--r-pill); flex: 0 0 auto; display: grid; place-items: center; }
.btn-round .ic { width: 22px; height: 22px; }
.res-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.res-cell { display: flex; flex-direction: column; gap: 6px; font-weight: 700; font-size: 14px; color: var(--ink); }
.res-cell select.field { width: 100%; }
.solo:has(> .state-ic:first-child) > .hint-card { margin-top: 16px; }
.centered-solo > .koi-hero-sm { align-self: center; }
.solo > .set3 + .hint-card:not([class*="mt-"]), .solo > .hint-card + .hint-card:not([class*="mt-"]) { margin-top: 12px; }

/* ---- Block W per v3 ------------------------------------------------------------ */
/* W05 footer: a slab with the logo and the “not an exam centre” line, three columns
   of links. Below 900px the logo block takes its own row; the phone layout is below. */
.footer.foot3 { display: grid; grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); gap: 24px; align-items: start; }
.foot-brand { display: flex; flex-direction: column; gap: 8px; }
.foot-brand .brand-name { font-family: var(--font-display); font-weight: 800; }
.foot-col { display: flex; flex-direction: column; gap: 2px; }
.foot-col .kicker { margin-bottom: 4px; }
.foot-col a { color: var(--ink-secondary); text-decoration: none; font-size: var(--fs-secondary-sm); font-weight: 700; padding-block: 8px; }
.foot-col a:hover, .foot-col a:focus-visible { color: var(--accent-ink); text-decoration: underline; }
/* The slab in dark glass (W05): set apart from the page by a surface, not a rule. */
.footer.foot3 {
  background: var(--glass-dark); border: 1px solid var(--glass-dark-border); box-shadow: var(--glass-dark-shadow);
  -webkit-backdrop-filter: var(--glass-dark-blur); backdrop-filter: var(--glass-dark-blur);
  border-radius: var(--r-card); padding: 24px 28px; margin-block-end: 26px; color: var(--paper-card);
}
.foot3 .foot-logo { display: inline-flex; align-items: center; gap: 10px; }
.foot3 .brand-name { color: var(--paper-card); font-size: 18px; }
.foot3 .brand-name span { color: var(--panel-accent); }
.foot3 .muted { color: var(--tint-on-dark); opacity: 1; }
.foot3 .kicker { color: var(--panel-kicker); }
.foot3 .foot-col a { color: var(--paper-card); font-weight: 600; }
.foot3 .foot-col a:hover, .foot3 .foot-col a:focus-visible { color: var(--panel-accent); }
@media (max-width: 900px) {
  .footer.foot3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .foot-brand { grid-column: 1 / -1; }
}
/* Narrow screen: the footer is a quiet end of the page, as in the app, not
   the dark three-column slab, which would take over half a phone screen.
   Link rows centred without column headings, the logo and the “not an exam
   centre” line small at the bottom. The documents stay one tap away: without
   them a service in the EU may not take money. */
@media (max-width: 560px) {
  .footer.foot3 {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
    border-radius: 0; padding: 18px 4px 8px; margin-block-end: 8px;
    border-block-start: 1px solid var(--line); color: var(--ink-secondary); text-align: center;
  }
  .foot3 .foot-col { flex-direction: row; flex-wrap: wrap; justify-content: center; column-gap: 18px; row-gap: 0; }
  .foot3 .foot-col .kicker { display: none; }
  .foot3 .foot-col a { color: var(--ink-secondary); font-weight: 700; font-size: 13.5px;
    min-height: var(--a11y-tap-target-min); min-width: var(--a11y-tap-target-min); justify-content: center;
    display: inline-flex; align-items: center; padding-block: 0; }
  .foot3 .foot-col a:hover, .foot3 .foot-col a:focus-visible { color: var(--accent-ink); }
  .foot3 .foot-brand { order: 9; align-items: center; gap: 4px; margin-block-start: 10px; }
  .foot3 .foot-logo .brand-disc { width: 22px; height: 22px; }
  .foot3 .brand-name { color: var(--ink); font-size: 15px; }
  .foot3 .brand-name span { color: var(--accent-ink); }
  .foot3 .muted { color: var(--ink-tertiary); max-width: 34ch; }
}
/* Header for W1/W4/W15/W18: sign-in as a text link with a question before it, the
   level check in orange, “Secure checkout” and “Exam today” as pills. */
.header .nav-link { font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--ink); text-decoration: none;
  min-height: var(--a11y-tap-target-min); display: inline-flex; align-items: center; padding-inline: 8px; }
.header .nav-link:hover, .header .nav-link:focus-visible { color: var(--accent-ink); }
.header .nav-q { font-size: 13.5px; color: var(--ink-tertiary); }
/* Interface language in the header: icon and code; on a narrow screen only the icon,
   and the app header on narrow has none at all (it is in You → settings). */
.lang-btn { display: inline-flex; align-items: center; gap: 5px; min-height: var(--a11y-tap-target-min); min-width: var(--a11y-tap-target-min);
  justify-content: center; padding-inline: 8px; border-radius: var(--r-pill); color: var(--ink); text-decoration: none;
  font-family: var(--font-display); font-weight: 800; font-size: 13px; }
.lang-btn .ic { width: 18px; height: 18px; }
.lang-btn:hover, .lang-btn:focus-visible { color: var(--accent-ink); }
@media (max-width: 560px) {
  .lang-btn .lb-code { display: none; }
}
/* The app header has less room: tabs, streak, exam date, avatar. There the
   language icon shows only above 1100px; on tablet and phone the language is
   in settings (at 768 the icon would push the avatar past the edge). */
@media (max-width: 1100px) { .header:not(.mk) .lang-btn { display: none; } }
.foot-lang { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; min-height: var(--a11y-tap-target-min);
  color: var(--paper-card); text-decoration: none; font-weight: 700; font-size: var(--fs-secondary-sm); width: fit-content; }
.foot-lang .ic { width: 16px; height: 16px; }
.foot-lang:hover, .foot-lang:focus-visible { color: var(--panel-accent); }
@media (max-width: 560px) { .foot3 .foot-lang { color: var(--ink-secondary); margin-top: 0; } }
.secure-pill { display: inline-flex; align-items: center; gap: 6px; }
.secure-pill .ic { width: 14px; height: 14px; }
.exam-chip.today { background: var(--ink); color: var(--paper-card); border-radius: var(--r-pill); padding-inline: 14px; gap: 6px; }
.exam-chip.today .ic { width: 14px; height: 14px; }
.exam-chip .ec-short { display: none; }
/* B07: on a narrow screen on exam day the right of the header holds a dark “Today”
   pill instead of the avatar and streak, as on the phone. */
@media (max-width: 560px) {
  .exam-chip.today { display: inline-flex; font-size: 12.5px; padding: 12px 14px; margin-block: -3px; min-height: 0;
    background: var(--glass-dark); border: 1px solid var(--glass-dark-border); box-shadow: var(--glass-dark-shadow); }
  .exam-chip.today .ec-long { display: none; }
  .exam-chip.today .ec-short { display: inline; }
  .header .row:has(.exam-chip.today) .avatar,
  .header .row:has(.exam-chip.today) .run-chip { display: none; }
}
@media (max-width: 900px) { .header .nav-q { display: none; } }


/* “When you pay” on the wide price screen (W04): a horizontal timeline with three
   dots and large amounts above the captions. Logical properties: in RTL the line mirrors. */
@media (min-width: 1100px) {
  .pricing3 .tl3 { flex-direction: row; margin-top: 18px; }
  .pricing3 .tl3 li { flex: 1 1 0; display: flex; flex-direction: column; gap: 2px; padding-block: 26px 0; padding-inline: 0 14px; }
  .pricing3 .tl3 li::before { inset-inline-start: 0; top: 0; }
  .pricing3 .tl3 li::after { inset-inline-start: 16px; inset-inline-end: 4px; top: 4px; bottom: auto; width: auto; height: 2px; }
  .pricing3 .tl3 b { order: -2; font-size: 13px; }
  .pricing3 .tl3 em { order: -1; align-self: flex-start; font-size: 26px; margin-bottom: 2px; }
}
/* Trap card (W02): the text stretches, the action is on the right; on narrow, below. */
.trap-row .tr-t { flex: 1 1 auto; min-width: 0; }
.trap-row .tr-go { flex: 0 0 auto; gap: 6px; }
.trap-row .tr-go .ic { width: 15px; height: 15px; }
@media (max-width: 560px) { .trap-row { flex-wrap: wrap; } .trap-row .tr-go { margin-inline-start: auto; } }

/* Practice (W06): part cards 2×2 in the left column, a score bar with a line
   marker; the red trap words are the ones that caught the person. */
.grid4.two { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 0; }
@media (max-width: 560px) { .grid4.two { grid-template-columns: minmax(0, 1fr); } }
.pc-bar { position: relative; height: 6px; border-radius: var(--r-pill); background: var(--track); margin: 10px 0 12px; }
.pc-bar i { display: block; position: absolute; inset-block: 0; inset-inline-start: 0; border-radius: var(--r-pill); background: var(--pass); }
.pc-bar.short i { background: var(--fail); }
.pc-bar s { display: block; position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--ink); }
.pc-bar.none { background: none; border-top: 2px dashed var(--line-strong); height: 0; }
.word-pills span.caught { background: var(--fail-ink); color: var(--paper-card); border-color: var(--fail-ink); box-shadow: none; }
/* The selected sitting (W11) is a dark glass card. */
.sit3.chosen { background: var(--glass-dark); border: 1px solid var(--glass-dark-border); box-shadow: var(--glass-dark-shadow); color: var(--paper-card); }
.sit3.chosen .sit3-d small, .sit3.chosen .sit3-s, .sit3.chosen .sit3-fee { color: var(--tint-on-dark); }
/* The selected sitting (W11): price and tick on one line on the right. */
.sit3.chosen .sit3-r { flex-direction: row; align-items: center; gap: 12px; }
.sit3-ok { display: inline-flex; color: var(--paper-card); }
.sit3-ok .ic { width: 18px; height: 18px; }
@media (max-width: 560px) { .sit3-ok { display: none; } }
/* What to bring on exam day (W23): a dark card, rows with icons. */
.bring-card .lrow-t { color: var(--paper-card); }
.bring-card .lrow-ic { background: var(--tint-on-dark-fill); color: var(--paper-card); }
.bring-card .lrow { border-color: var(--tint-on-dark-line); }
/* W08·b: at high water the capsule is dark glass, the digits stay white. */
.tp-mid.high { background: var(--glass-dark); border-color: var(--glass-dark-border); -webkit-backdrop-filter: var(--glass-dark-blur); backdrop-filter: var(--glass-dark-blur); }
/* Run cost by part (W22): number and caption on one line. */
.cost-grid { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.cost-grid div { display: flex; align-items: baseline; gap: 10px; }
.cost-grid b { font-family: var(--font-display); font-weight: 800; font-size: 22px; color: var(--fail-ink); min-width: 1.2em; }
/* W22: on the wide web “what it cost” is tiles: a large number above the caption. */
@media (min-width: 901px) {
  .cost-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 10px; }
  .cost-grid div { flex-direction: column; align-items: flex-start; gap: 4px; padding: 14px; border-radius: var(--r-card-sm);
    background: var(--paper-card); border: 1px solid var(--line); }
  .cost-grid b { font-size: 26px; line-height: 1; }
  .cost-grid span { font-size: 13px; color: var(--ink-secondary); }
}
/* Time by part (W22): a line and a bar under it. */
.tm-row + .tm-row { border-top: 1px solid var(--line); }
.tm-row .lrow { border: 0; padding-bottom: 4px; }
.tm-row .lrow-v.short { color: var(--fail-ink); }
.tm-bar { height: 6px; border-radius: var(--r-pill); background: var(--track); margin: 0 0 12px; overflow: hidden; }
.tm-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--pass); }
.tm-bar.short i { background: var(--fail); }
/* Here .cc-n is a 44px number: the shared 34px width (meant for a date in a
   row) would make it run into “days”. */
.closes-card .cc-n { margin-inline-end: 4px; width: auto; }
/* List rows on dark glass (order W18 and others): light text, light rules. */
.dglass .lrow { border-color: var(--tint-on-dark-line); }
.dglass .lrow-t { color: var(--paper-card); }
.dglass .lrow-t small, .dglass .lrow-v { color: var(--tint-on-dark); }
.dglass .lrow-v.strong { color: var(--paper-card); }
.dglass > .kicker { color: var(--tint-on-dark); }
/* Single-column screens (first-plan steps, guest settings, help, documents) stand
   centred on a wide screen rather than pressed to the left with an empty right half
   (W15, W16). */
.screen > .solo { margin-inline: auto; }
/* An estimate below the line (W17) gets the same red edge as a measured “short”. */
.tk.est.warm .tk-tube { border: 2px solid var(--fail); }
/* On exam day on a medium screen the header lacks room for both the streak and
   “Exam today”: the main thing stays, the exam day. */
@media (max-width: 900px) { .header .row:has(.exam-chip.today) .run-chip { display: none; } }

/* ---- phone scale (v3, design/handoff-v3/_v3kit.js): screen title 30, lead 15,
   caption under a button 12.5. On the narrow web the screens are the same
   phone artboards. */
@media (max-width: 560px) {
  /* The per-screen titles are listed too: progress and practice set 40px with
     a heavier selector and would otherwise beat the phone scale. */
  .display, .display-sm, .progress-v3 .display, .practice-v3 .display { font-size: var(--fs-h1-mobile); }
  .lede, .lead-p { font-size: 15px; }
  .note-sm { font-size: 12.5px; }
  /* On the phone the flask card has no “Where you stand” header (B01, B03, A12·s2):
     only the wide web has it (W02). Its own caption, the scoresheet date, stays. */
  .tanks-card .head.default { display: none; }
  /* Flask caption 12, 11 under it (B01, A04). */
  .tk-name { font-size: 12px; }
  .tk-sub { font-size: 11px; }
}

/* ---- 404 (W05): mascot on the left, the word on the right; narrow: a centred column ---- */
.nf3 {
  max-width: 880px; margin: 0 auto; min-height: 52vh;
  display: flex; align-items: center; justify-content: center; gap: 40px;
  padding-block: 48px 32px;
}
.nf-koi { width: 220px; height: 220px; object-fit: contain; flex: 0 0 auto; }
.nf-t { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; min-width: 0; }
.nf-t .display { margin: 0; }
.nf-t .lede { margin: 0; }
.nf-acts { margin-top: 12px; flex-wrap: wrap; }
.nf-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.nf-links .pill { min-height: var(--a11y-tap-target-min); display: inline-flex; align-items: center; padding-inline: 14px; }
@media (max-width: 700px) {
  .nf3 { flex-direction: column; text-align: center; gap: 12px; padding-top: 24px; }
  .nf-koi { width: 150px; height: 150px; }
  .nf-t { align-items: center; }
  .nf-acts, .nf-links { justify-content: center; }
}

/* The submit row of the “true / false” list (W03, W14): sticks to the bottom of the
   window on glass; on the left how many are blank, on the right the button. */
.vf-foot {
  position: sticky; bottom: 12px; z-index: 5; margin-top: 14px;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 10px 10px 10px 18px; border-radius: var(--r-pill);
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
  -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
}
.vf-foot > .note-sm { margin: 0; flex: 1; min-width: 0; }
.vf-foot > .act-row { margin: 0; flex: 0 0 auto; margin-inline-start: auto; }
/* "N of 12 answered" beside "Hand in" (B-46): one label, the count next to it. */
.vf-foot .vf-count { margin: 0; align-self: center; white-space: nowrap; }
/* Orale preparation (C12): the head centred on a phone, and the topics, long
   Italian questions, in the text face (B-38). */
.oral-topics .lrow-t { font-family: var(--font-body); font-weight: 700; font-size: 15px; line-height: 1.4; }
@media (max-width: 560px) {
  .oral-head { align-items: center; text-align: center; }
}
/* On the phone the row joins the flow under the list: stuck, it would cover a
   third of the screen of statements. */
@media (max-width: 560px) {
  .vf-foot { position: static; flex-direction: column; align-items: stretch; padding: 0; background: none; border: 0; box-shadow: none;
    -webkit-backdrop-filter: none; backdrop-filter: none; }
  .vf-foot > .act-row { margin-inline-start: 0; }
}

/* ---- “passed” (19/F06, W25) -------------------------------------------------
   Narrow screen: a centred column, as on the phone; wide: two columns, the mascot
   with the title and the scoresheet on the left, steps and actions on the right. */
.win3w { max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; text-align: center; }
.w3-main, .w3-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.w3-head { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.w3-head .win-koi img { width: 170px; height: 170px; }
.w3-head .display { margin: 0; }
.win3w .lede { margin: 0 auto; }
.win3w .btn-pair { justify-content: center; }
.w3-steps { list-style: none; margin: 8px 0 0; padding: 0; counter-reset: w3; text-align: start; }
.w3-steps li { counter-increment: w3; position: relative; padding: 12px 0 12px 40px; display: flex; flex-direction: column; gap: 2px; }
.w3-steps li + li { border-top: 1px solid var(--line); }
.w3-steps li::before {
  content: counter(w3); position: absolute; inset-inline-start: 0; top: 12px;
  width: 26px; height: 26px; border-radius: var(--r-pill); background: var(--ink); color: var(--paper-card);
  font-family: var(--font-display); font-weight: 800; font-size: 13px; display: flex; align-items: center; justify-content: center;
}
.w3-steps b { font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.w3-steps span { font-size: 13.5px; color: var(--ink-secondary); }
@media (min-width: 901px) {
  .win3w { max-width: var(--web-max); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; text-align: start; align-items: start; padding-top: 12px; }
  .w3-head { flex-direction: row; align-items: center; gap: 18px; }
  .w3-head .win-koi img { width: 150px; height: 150px; }
  .win3w .lede { margin: 0; }
  .win3w .btn-pair { justify-content: flex-start; }
  .win3w .btn-pair .btn-big { flex: 1; }
}
/* “Did not pass” (W26) in the same layout; the quiet link centred in the column. */
.win3w .link-quiet { align-self: center; }
.win3w .w3-side .mock-card { text-align: start; }
@media (min-width: 901px) { .win3w .link-quiet { align-self: flex-start; } }

/* The marketing header on the phone: “Sign in” on one line, and the orange
   “Free level check” is hidden: on the landing and pricing pages their own
   primary button stands right under the header, and a second one next to the
   logo would squeeze “Sign in” onto two lines. */
.header .nav-link, .header .nav a { white-space: nowrap; }
@media (max-width: 560px) { .header .mk-cta { display: none; } }
/* Between phone and desktop the marketing row does not fit on one line: at about
   600px "How it works" broke into three lines and the orange button stuck out of
   the band (Max, 2026-09-28). Below 960px the two text links go (the footer has
   them), below 720px the button goes too, as on the phone. */
@media (max-width: 960px) { .header.mk .nav { display: none; } }
@media (max-width: 720px) { .header.mk .mk-cta { display: none; } }

/* Keeps the footer below the fold: main is at least the window height minus
   the header and margins, so on a short page (landing at 1280, 404, “passed”)
   the dark footer slab does not stick out at the bottom of the first screen,
   where it reads as a half-loaded block. Long pages are unaffected. */
.wrap > main:not(:last-child) { min-height: calc(100svh - 96px); }

/* ---- exam card: glass in the flag's colours (decision 31) -------------------
   Under the card glass are the three stripes of the country's flag, blurred into
   coloured light: vertical for Italy (green, white, red), horizontal for the
   Netherlands (red, white, blue). The exams differ before you read a word, and
   there is no flag picture on screen to compete with the primary button. The
   Netherlands is locked: the base is blurred more, the text is muted, a lock on
   the right, and it cannot be pressed. */
/* ⚠️ The blur comes from the gradient's own wide transitions, not from
   `filter: blur()`: Safari on iPhone does not clip a filtered layer to the
   rounding, so the card corners turn square and the coloured light spills
   onto the neighbouring card. A gradient is clipped like an ordinary
   background. */
.flag-glass { position: relative; overflow: hidden; isolation: isolate; }
.flag-glass::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  border-radius: inherit; opacity: .34;
}
.flag-it::before {
  background: linear-gradient(90deg, var(--flag-it-green) 0%, var(--flag-it-green) 8%,
    var(--paper-card) 44% 56%, var(--flag-it-red) 92%, var(--flag-it-red) 100%);
}
.flag-nl::before {
  background: linear-gradient(180deg, var(--flag-nl-red) 0%, var(--paper-card) 50%, var(--flag-nl-blue) 100%);
}
.flag-glass.locked { pointer-events: none; user-select: none; cursor: default; }
.flag-glass.locked::before { opacity: .28; }
.flag-glass.locked .ex-t { opacity: .72; }
.ex-lock {
  width: 30px; height: 30px; flex: 0 0 auto; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center; color: var(--ink-secondary);
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border);
}
.ex-lock .ic { width: 15px; height: 15px; }
/* Exam choice: two separate cards, each with its own base, not rows of one
   list. The selected one has an ink edge, like a selected v3 card. */
.ex-cards { padding: 0; background: none; border: 0; box-shadow: none; display: flex; flex-direction: column; gap: 10px; }
.ex-cards .ex-row { padding: 16px 18px; border-radius: var(--r-card); }
.ex-cards .ex-row + .ex-row { border-top: 0; }
.ex-cards .ex-row.on { box-shadow: inset 0 0 0 2px var(--ink), var(--glass-light-shadow); }
/* Exam overview (/cils-b1). Wide: the reading column on the left and a sticky
   start card on the right, so the choice stays in view while the person reads.
   Narrow: one column, the start card last, after everything it summarises.
   Decoration is the product's own: the koi, flag glass, flasks, a few bubbles. */
.about-wrap {
  position: relative; display: grid; gap: 28px; align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
  max-width: 1120px; margin-inline: auto;
}
.about-wrap::before {                 /* soft halo behind the title, in the product's teal */
  content: ""; position: absolute; z-index: -1; inset: -40px auto auto 0; width: min(520px, 100%); height: 360px;
  border-radius: 50%; background: radial-gradient(closest-side, var(--tint-state-halo), transparent);
  pointer-events: none;
}
.about-h { font-size: 48px; line-height: 1.02; margin-top: 6px; }
.about-lede { max-width: 620px; }
.about-stats { list-style: none; padding: 0; margin: 18px 0 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.about-stats li { padding: 14px 14px 12px; border-radius: var(--r-card-md); display: flex; flex-direction: column; gap: 2px; }
.about-stats b { font-family: var(--font-display); font-weight: 800; font-size: 28px; line-height: 1.1; color: var(--ink); }
.about-stats span { font-size: 12.5px; line-height: 1.35; color: var(--ink-secondary); }
.about-parts { list-style: none; padding: 0; margin: 10px 0 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.about-part { padding: 16px 18px 14px; border-radius: var(--r-card); display: flex; flex-direction: column; gap: 8px; }
.ap-top { display: flex; align-items: center; gap: 10px; }
.ap-top b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.ap-min { margin-inline-start: auto; font-size: 12.5px; font-weight: 700; color: var(--ink-secondary); background: var(--glass-pill); border: 1px solid var(--line); border-radius: var(--r-pill); padding: 3px 10px; }
.ap-what { font-size: 13.5px; line-height: 1.5; color: var(--ink-secondary); margin: 0; flex: 1; }
.ap-line { position: relative; height: 6px; border-radius: var(--r-pill); background: var(--track); overflow: hidden; }
.ap-line i { display: block; position: absolute; inset: 0 auto 0 0; border-radius: var(--r-pill); background: var(--pass); }
.ap-need { font-size: 12px; font-weight: 700; color: var(--pass-text); }
.about-duo { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 12px; margin-top: 12px; }
.about-rulecard, .about-daycard { padding: 18px 20px; border-radius: var(--r-card); }
.about-rule { font-size: 14px; line-height: 1.5; margin-top: 6px; }
.about-tanks { margin-top: 12px; }
.about-facts { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.about-facts li { display: flex; gap: 12px; align-items: flex-start; font-size: 13.5px; line-height: 1.45; color: var(--ink); }
.af-ic { flex: 0 0 auto; width: 30px; height: 30px; border-radius: var(--r-tile); display: flex; align-items: center; justify-content: center; background: var(--pass-bg); color: var(--pass-text); }
.af-ic .ic { width: 16px; height: 16px; }
.exam-about { overflow-x: clip; }
.about-aside { position: sticky; top: 150px; margin-top: 64px; }
.about-start { position: relative; padding: 64px 20px 18px; border-radius: var(--r-card); overflow: visible; }
.about-koi { position: absolute; top: -52px; inset-inline-end: 18px; width: 110px; height: auto; transform: rotate(-6deg); filter: drop-shadow(0 8px 14px var(--tint-groove-shadow)); }
.about-bubbles i { position: absolute; border-radius: 50%; border: 1.5px solid var(--tint-state-ring); background: var(--glass-pill); }
.about-bubbles i:nth-child(1) { width: 14px; height: 14px; top: -30px; inset-inline-end: 136px; }
.about-bubbles i:nth-child(2) { width: 9px; height: 9px; top: -50px; inset-inline-end: 150px; }
.about-bubbles i:nth-child(3) { width: 6px; height: 6px; top: -64px; inset-inline-end: 140px; }
.about-start-h { font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 1.15; margin: 0 0 12px; }
.about-opt {
  display: flex; align-items: center; gap: 12px; padding: 14px; margin-top: 10px; border-radius: var(--r-card-md);
  background: var(--paper-card); border: 1px solid var(--line); color: var(--ink); text-decoration: none;
  min-height: var(--a11y-tap-target-min);
}
.about-opt.primary { background: linear-gradient(180deg, var(--accent-from), var(--accent-to)); border-color: transparent; color: var(--paper-card); box-shadow: var(--shadow-button); }
.about-opt .ao-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.about-opt .ao-t b { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.about-opt .ao-t small { font-size: 12.5px; line-height: 1.4; color: var(--ink-secondary); }
.about-opt.primary .ao-t small { color: var(--tint-on-dark); }
.about-opt .ao-ic { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--pass-bg); color: var(--pass-text); }
.about-opt.primary .ao-ic { background: var(--tint-on-dark-line); color: var(--paper-card); }
.about-opt .ao-go .ic { width: 16px; height: 16px; }
.about-trial { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 14px 0 0; font-size: 12.5px; font-weight: 700; color: var(--ink-secondary); }
@media (max-width: 960px) {
  .about-wrap { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .about-aside { position: static; margin-top: 60px; }
}
@media (max-width: 640px) {
  .about-h { font-size: 34px; }
  .about-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .about-parts, .about-duo { grid-template-columns: minmax(0, 1fr); }
}

/* Cards in a column screen (.solo, .centered-solo) get a 12px gap by default.
   Zero specificity (:where), so any explicit margin class (mt-16 …) wins, and
   a card without one does not sit flush against its neighbour. */
:where(.solo, .centered-solo) > :where(*) + :where(section, .hint-card, .pk-banner, .glass, .dglass, .sit3, .ex-group, .hint-btn) {
  margin-top: 12px;
}

/* A sub-step (a new question next to the same player): app.js adds .sub-in to
   the [data-substep] column, which rises like an entering block, only shorter. */
@media (prefers-reduced-motion: no-preference) {
  .sub-in { animation: pk-rise var(--motion-slow) var(--motion-ease-enter) both; }
}

/* “Back” sits in the left margin on a wide screen (≥1000px), level with the
   first line: the screen body is centred, and an arrow above the title reads
   as a separate line with no meaning of its own. The section label, if any,
   stays in the column. Narrower, the arrow stays above the title. */
@media (min-width: 1000px) {
  :where(.solo) { position: relative; }
  :where(.solo) > .onb-top:first-child > .icon-btn[data-pk-back] {
    position: absolute; inset-inline-start: -72px; top: -2px;
  }
  :where(.solo) > .onb-top:first-child:not(:has(> :not(.icon-btn))) { min-height: 0; margin: 0; }
}
/* In a centred column (state screens) the “back” row stretches to the full width:
   otherwise the arrow stood in the middle above the icon. */
.centered-solo > .onb-top { align-self: stretch; }

/* ---- Interface-language menu (header, footer, settings row) ------------------
   screens.js uiLangMenu draws it, app.js (PK_UILANG) opens and places it: a
   popover under its trigger (above it in the footer), on paper so the names
   read on any background. One line per language keeps the whole list in view;
   on a short window the list scrolls inside while the note under it stays.
   The card holding an open menu is raised, so the next card does not paint
   over it. */
.ul-menu { position: relative; }
.ul-set { display: block; }
button.lang-btn, button.foot-lang { background: none; border: 0; padding-block: 0; cursor: pointer; }
/* The footer trigger starts at the footer text's edge, like the links beside it. */
button.foot-lang { padding-inline: 0; }
.lang-btn[aria-expanded="true"] { color: var(--accent-ink); }
.foot-lang[aria-expanded="true"] { color: var(--panel-accent); }
@media (max-width: 560px) { .foot3 .foot-lang[aria-expanded="true"] { color: var(--accent-ink); } }
.ul-pop {
  position: absolute; top: calc(100% + 6px); inset-inline-end: 0; z-index: 40;
  width: min(300px, calc(100vw - 24px)); max-height: min(720px, calc(100vh - 96px));
  display: flex; flex-direction: column; padding: 6px; text-align: start;
  background: var(--paper-card); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-card-sm); box-shadow: var(--shadow-card);
}
.ul-pop[hidden] { display: none; }
/* The menu opens with a short drop (base, ease), like the other surfaces that
   pop up; upward menus rise instead. `translate` rather than `transform`, which
   app.js uses to keep the menu inside the window. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes pk-ul-in { from { opacity: 0; translate: 0 -6px; } to { opacity: 1; translate: 0 0; } }
  @keyframes pk-ul-up { from { opacity: 0; translate: 0 6px; } to { opacity: 1; translate: 0 0; } }
  .ul-pop:not([hidden]) { animation: pk-ul-in var(--motion-base) var(--motion-ease) both; }
  .ul-foot .ul-pop:not([hidden]), .ul-flip .ul-pop:not([hidden]) { animation-name: pk-ul-up; }
}
.ul-foot .ul-pop, .ul-flip .ul-pop { top: auto; bottom: calc(100% + 6px); }
.ul-foot .ul-pop { inset-inline: 0 auto; }
.ul-list { overflow-y: auto; min-height: 0; }
.ul-item {
  display: flex; align-items: center; gap: 10px; min-height: var(--a11y-tap-target-min);
  padding: 6px 10px; border-radius: var(--r-input); cursor: pointer;
}
.ul-item:focus-visible { outline-offset: -3px; }
.ul-item[aria-disabled="true"] { cursor: default; }
.ul-item[aria-disabled="true"] .ul-t > span { opacity: .6; }
.ul-item:not([aria-disabled="true"]):hover, .ul-item:focus-visible { background: var(--tint-teal-tile); }
.ul-t { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.ul-t small { font-family: var(--font-body); font-weight: 600; font-size: 12.5px; color: var(--ink-secondary); }
.ul-sep {
  margin: 6px 10px 2px; padding-top: 8px; border-top: 1px solid var(--line);
  font-family: var(--font-display); font-weight: 800; font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-tertiary);
}
.ul-ic { display: inline-flex; color: var(--ink-tertiary); }
.ul-item.on .ul-ic { color: var(--pass-text); }
.ul-ic .ic, .ul-note-ic .ic { width: 16px; height: 16px; }
.ul-note {
  display: flex; align-items: center; gap: 8px; min-height: var(--a11y-tap-target-min);
  margin: 4px 0 0; padding: 8px 10px; border-top: 1px solid var(--line);
  font-size: 13px; font-weight: 600; line-height: 1.35; color: var(--ink-secondary); text-decoration: none;
}
a.ul-note { color: var(--ink); }
a.ul-note:hover { color: var(--accent-ink); }
.ul-note-ic { display: inline-flex; flex: none; color: var(--pass-text); }
:where(.glass, .dglass, .footer):has(.ul-menu.open) { position: relative; z-index: 20; }
.lrow + .ul-menu, .ul-menu + .lrow { border-top: 1px solid var(--line); }
/* The app header shows no language button below 1100px (it is in settings):
   the empty wrapper would still take a gap in the row. */
@media (max-width: 1100px) { .header:not(.mk) .ul-head { display: none; } }
/* The settings row's chevron points down while the menu is closed, up while open. */
.ul-set .lrow-go .ic { transform: rotate(90deg); }
.ul-set.open .lrow-go .ic { transform: rotate(-90deg); }

/* ---- v4 Exams block: catalog (E1), exam page (E2), "Is it for me?" (E3),
   "coming", first lesson (E4) -------------------------------------------------

   Built from the v3 parts: glass cards, flag glass, the tube, the state icon,
   the buttons. What is new is layout: a two-column exam page from 900 px, a
   centred question column, and the lesson card beside its words. */

/* Tube states of an exam without a published pass mark (kit.js). */
.tk-num.worded {
  font-size: calc(var(--num) * .56); line-height: 1.8; color: var(--ink);
}
.tk.passed .tk-num.worded { color: var(--pass-text); }
.tk.none .tk-num.worded, .tk.self .tk-num.worded { color: var(--ink-secondary); }
.tk.self .tk-tube { background: var(--tint-empty-tube); border: 1.5px dashed var(--ink-faint); }
.tk.self .tk-glint, .tk.self .tk-notch, .tk.unlined .tk-notch { display: none; }
.tk.passed .tk-tube { border-color: var(--tint-full-rim); }
.tk-mark {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 5;
  width: 26px; height: 26px; border-radius: var(--r-pill); background: var(--paper-card);
  display: flex; align-items: center; justify-content: center; color: var(--pass-text);
}
.tk-mark .ic { width: 15px; height: 15px; }

/* E1 catalog */
.exams-cat .exc-h { max-width: 620px; }
.exams-cat .lede { max-width: 620px; }
.exc-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 30px; }
.exc-grid.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 900px; }
.exc-grid.mine-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
.exc-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.exc-col .exc-also { margin: 0; }
.exc-card {
  display: flex; flex-direction: column; gap: 10px; padding: 24px; border-radius: var(--r-card);
  color: var(--ink); text-decoration: none; min-width: 0;
}
a.exc-card:hover { box-shadow: var(--shadow-card); }
.exc-card.mine { border: 2px solid var(--ink); }
.exc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.exc-top b { font-family: var(--font-display); font-weight: 800; font-size: 28px; letter-spacing: -.02em; }
.exc-badge { font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--accent-ink); }
.exc-purpose { font-size: 16px; color: var(--ink-secondary); }
.exc-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.exc-pills span {
  font-family: var(--font-display); font-weight: 800; font-size: 13px; padding: 6px 12px;
  border-radius: var(--r-pill); background: var(--glass-pill); border: 1px solid var(--glass-pill-border);
}
.exc-soon {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary);
}
.exc-soon .ic { width: 14px; height: 14px; }
.exc-tubes { padding: 16px 12px 12px; border-radius: var(--r-card-sm); background: var(--glass-pill); }
.exc-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line);
}
.exc-shape { font-family: var(--font-display); font-weight: 800; font-size: 14.5px; }
.exc-go {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--font-display); font-weight: 800; font-size: 14.5px; color: var(--accent-ink);
}
.exc-go .ic { width: 15px; height: 15px; }
.exc-go-link { align-self: flex-start; min-height: var(--a11y-tap-target-min); text-decoration: none; }
.exams-cat > .note-sm { margin-top: 20px; }
@media (max-width: 1000px) { .exc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) {
  .exc-grid, .exc-grid.n2, .exc-grid.mine-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 20px; }
  .exc-card { padding: 18px 18px 16px; }
  .exc-top b { font-size: 23px; }
  .exc-purpose { font-size: 14.5px; }
}
@media (max-width: 560px) { .exc-pills { display: none; } .exc-foot { margin-top: 0; padding-top: 10px; } }

/* E2 exam page */
.exp-top { display: none; }
.exp-grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.exp-main, .exp-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.exp-hero { padding: 28px 28px 26px; border-radius: var(--r-card); }
.exp-hero .kicker { color: var(--ink); }
.exp-h { font-size: 36px; margin-top: 12px; }
.exp-lede { font-size: 16px; line-height: 1.5; margin-top: 12px; color: var(--ink); }
.exp-by { font-size: 14px; color: var(--ink-secondary); margin-top: 6px; }
.exp-by a { color: var(--accent-ink); font-weight: 700; }
.exp-card { padding: 22px 22px 20px; border-radius: var(--r-card); }
.exp-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 16px; }
.exp-head .meta { font-family: var(--font-display); font-weight: 800; font-size: 13px; }
.exp-rows { list-style: none; margin: 10px 0 0; padding: 0; }
.exp-row {
  display: grid; grid-template-columns: 40px minmax(90px, .8fr) minmax(0, 1.6fr) 70px 90px;
  align-items: center; gap: 14px; padding: 12px 0; border-top: 1px solid var(--line);
}
.exp-row .lrow-ic { width: 40px; height: 40px; }
.exp-row b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.exp-what { font-size: 14.5px; color: var(--ink-secondary); line-height: 1.35; }
.exp-min { font-family: var(--font-display); font-weight: 800; font-size: 14.5px; white-space: nowrap; }
.exp-n { font-size: 14px; color: var(--ink-secondary); white-space: nowrap; }
.exp-pass .tanks { margin-top: 4px; }
.exp-lead { font-size: 15px; line-height: 1.5; margin: 10px 0 16px; }
.exp-note { font-size: 14.5px; line-height: 1.5; color: var(--ink-secondary); margin-top: 14px; }
.exp-scale {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 13.5px; color: var(--ink-secondary);
}
.exp-scale b { font-family: var(--font-display); font-weight: 800; color: var(--ink); }
.es-steps { display: inline-flex; align-items: baseline; gap: 6px; }
.es-steps i { font-style: normal; color: var(--ink-faint); }
.es-src { margin-inline-start: auto; }
.exp-price { font-family: var(--font-display); font-weight: 800; font-size: 19px; margin-top: 10px; }
.exp-text { font-size: 14.5px; line-height: 1.5; color: var(--ink-secondary); margin-top: 8px; }
.exp-also { display: flex; gap: 8px; align-items: flex-start; font-size: 14px; line-height: 1.45; margin-top: 12px; color: var(--ink); }
.exp-also .ic { width: 16px; height: 16px; flex: none; margin-top: 2px; color: var(--pass-text); }
.exp-acts { display: flex; flex-wrap: wrap; gap: 12px; }
.exp-acts .btn { flex: 1 1 auto; }
.exp-lesson { margin-top: 0; }
.exp-lesson .link-accent { display: inline-flex; align-items: center; min-height: var(--a11y-tap-target-min); padding: 0; margin: 0; text-decoration: none; }
@media (max-width: 900px) {
  .exp-grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .exp-top { display: flex; margin-bottom: 14px; }
  .exp-main, .exp-side { gap: 14px; }
}
@media (max-width: 560px) {
  .exp-hero { padding: 20px 18px 18px; }
  .exp-h { font-size: 28px; }
  .exp-card { padding: 18px 16px 16px; }
  .exp-row {
    grid-template-columns: 40px minmax(0, 1fr) auto; grid-template-areas: "ic name min" "ic what n";
    gap: 2px 12px; padding: 10px 0;
  }
  .exp-row .lrow-ic { grid-area: ic; }
  .exp-row b { grid-area: name; font-size: 16px; }
  .exp-what { grid-area: what; font-size: 13.5px; }
  .exp-min { grid-area: min; text-align: end; }
  .exp-n { grid-area: n; text-align: end; font-size: 13px; }
  .exp-acts .btn { flex: 1 1 100%; }
}

/* E3 "Is it for me?": one centred column, the round back button and Skip in
   its top row (the same back control as the exam page, E3·s1). */
.fit-col { max-width: 620px; margin: 0 auto; }
.fit-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.fit-skip {
  display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px;
  min-height: var(--a11y-tap-target-min); min-width: var(--a11y-tap-target-min);
  padding: 0; border: 0; background: none; cursor: pointer; text-decoration: none;
  font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink-secondary);
}
.fit-skip:hover { color: var(--ink); }
.fit-ans { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink-secondary); }
.fit-count { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink-secondary); text-align: center; }
.fit-bar { display: flex; gap: 6px; margin-top: 12px; }
.fit-bar i { flex: 1; height: 6px; border-radius: var(--r-pill); background: var(--track); }
.fit-bar i.on { background: var(--water-pass-mid); }
.fit-exam { margin-top: 26px; }
.fit-h { font-size: 36px; margin-top: 6px; }
.fit-lede { margin-top: 8px; max-width: none; }
.fit-opts { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: 22px; }
.fit-opts.multi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fit-opt {
  display: flex; align-items: center; gap: 14px; padding: 16px 20px; min-height: 64px; text-align: start;
  border-radius: var(--r-card-sm); color: var(--ink); cursor: pointer; font: inherit;
  background: var(--glass-light); border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow);
  -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
}
.fit-opt.on {
  background: var(--glass-dark), var(--ink); border-color: var(--glass-dark-border); box-shadow: var(--glass-dark-shadow);
  -webkit-backdrop-filter: var(--glass-dark-blur); backdrop-filter: var(--glass-dark-blur); color: var(--paper-card);
}
.fit-opt:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.fo-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fo-t b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.fo-t small { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.35; }
.fit-opt.on .fo-t small { color: var(--tint-on-dark); }
.fo-box {
  width: 26px; height: 26px; flex: none; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center; box-shadow: inset 0 0 0 1.5px var(--line-strong);
}
.fo-box.sq { border-radius: var(--r-tile); }
.fit-opt.on .fo-box { background: var(--paper-card); box-shadow: none; color: var(--ink); }
.fo-box .ic { width: 15px; height: 15px; }
.fit-go { display: flex; justify-content: flex-end; margin-top: 22px; }
.fit-go .btn { min-width: 180px; }
@media (max-width: 560px) {
  .fit-h { font-size: 30px; }
  .fit-opts.multi { grid-template-columns: minmax(0, 1fr); }
  .fit-count { font-size: 13.5px; }
  .fit-go .btn { width: 100%; }
}

/* E3 verdict: the reason on the left, tubes, sources and the next step on the right. */
.fit-verdict .fit-top.vt { max-width: none; justify-content: flex-start; gap: 18px; }
.fit-verdict .fit-top.vt .fit-count { color: var(--ink-tertiary); }
.fv-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 36px; align-items: center; margin-top: 16px; }
.fv-main .state-ic { margin: 26px 0 36px 26px; }
.fv-h { font-size: 44px; }
.fv-lede { max-width: 520px; }
.fv-left { font-family: var(--font-display); font-weight: 800; font-size: 16px; margin-top: 14px; color: var(--pass-text); }
.fv-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.fv-links { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.fv-links li { display: flex; gap: 8px; align-items: flex-start; font-size: 14.5px; line-height: 1.4; }
.fv-links li .ic { width: 15px; height: 15px; flex: none; margin-top: 3px; color: var(--ink-secondary); }
.fv-links a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; }
.fv-links a:hover { color: var(--accent-ink); }
.fv-checked { font-size: 13px; color: var(--ink-secondary); margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
@media (max-width: 900px) {
  .fv-grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .fv-h { font-size: 32px; }
}
/* Narrow: the ring (1 px outline 16 px out) starts at the content margin, like
   every other block, not at the viewport edge (E3·v1, B-23). */
@media (max-width: 560px) { .fv-main .state-ic { width: 72px; height: 72px; margin: 18px 0 30px 17px; outline-offset: 16px; } .fv-main .state-ic .ic { width: 30px; height: 30px; } .fv-h { font-size: 30px; } }

/* "Coming": the koi-less state screen with one action. */
.coming .state-ic { margin-inline-start: 26px; }
.coming .hint-card { margin-top: 20px; }

/* E4 first lesson: the card's picture beside its words, dots and buttons under them. */
.les-top { display: flex; justify-content: flex-end; min-height: var(--a11y-tap-target-min); }
.les-skip {
  display: inline-flex; align-items: center; justify-content: flex-end;
  min-height: var(--a11y-tap-target-min); min-width: var(--a11y-tap-target-min); padding-inline: 4px;
  font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--accent-ink); text-decoration: none;
}
.les-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: center; margin-top: 8px; }
.les-art { display: flex; justify-content: center; min-width: 0; }
.les-koi { width: 220px; height: auto; }
.les-tubes { width: 100%; padding: 26px 22px 20px; border-radius: var(--r-card); }
.les-parts { list-style: none; margin: 0; padding: 0; width: 100%; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.les-parts.n5 li:last-child { grid-column: 1 / -1; }
.les-parts li { display: flex; flex-direction: column; gap: 6px; padding: 18px; border-radius: var(--r-card-sm); }
.les-parts li .lrow-ic { width: 42px; height: 42px; margin-bottom: 6px; }
.les-parts li b { font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.les-parts li span:last-child { font-size: 14px; color: var(--ink-secondary); }
.les-tape {
  position: relative; overflow: hidden; width: 100%; height: 230px; border-radius: var(--r-panel);
  background: var(--screen-dark); display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding-top: 22px; isolation: isolate;
}
.lt-k { font-family: var(--font-display); font-weight: 800; font-size: 12.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--panel-kicker); }
.lt-play {
  position: relative; z-index: 2; margin-top: 30px; width: 64px; height: 64px; border-radius: var(--r-pill);
  background: var(--paper-card); color: var(--ink); display: flex; align-items: center; justify-content: center;
}
.lt-play .ic { width: 24px; height: 24px; }
.lt-water {
  position: absolute; left: 0; right: 0; bottom: 0; height: 62%; z-index: 1;
  background: linear-gradient(180deg, var(--water-pass-top), var(--water-pass-mid) 42%, var(--water-pass-deep));
}
.lt-water .tk-wave svg { fill: var(--water-pass-top); }
.les-kicker { margin: 0; }
.les-h { margin-top: 10px; }
.les-p { max-width: 480px; }
.les-nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 30px; flex-wrap: wrap; }
.les-dots { display: inline-flex; gap: 6px; align-items: center; }
.les-dots i { width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--line-strong); }
.les-dots i.on { width: 28px; background: var(--ink); }
.les-btns { display: inline-flex; gap: 12px; flex-wrap: wrap; }
@media (max-width: 900px) {
  .les-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .les-koi { width: 170px; }
}
@media (max-width: 560px) {
  .les-h { font-size: 30px; }
  .les-tape { height: 200px; }
  .les-nav { flex-direction: column; align-items: stretch; }
  .les-dots { justify-content: center; }
  .les-btns .btn { flex: 1 1 auto; }
}
/* Five worded tubes on a narrow row: the words above them stay one line each. */
@media (max-width: 560px) { .tanks.n5 .tk-num.worded { font-size: 11.5px; } }

/* ─── Many exams (design/handoff-v4-nl, design.css): the exam switcher
   (X1–X3) and the shared screens of an exam with the chance pass model
   (N1–N3, L3). The task screens' own components (question frame, players,
   recorder, samples, composer: N4–N10) come with the exam's task module. ── */
:root {
  /* The chance steps reuse the pass/short palette, so a Dutch tube and an
     Italian tube speak one colour language (teal good, warm not yet). */
  --chance-none: var(--fail-border);
  --chance-none-ink: var(--fail-ink);
  --chance-small: var(--water-short-top);
  --chance-small-line: var(--fail-border);
  --chance-small-ink: var(--accent-ink);
  --chance-fair: var(--pass-border);
  --chance-fair-ink: var(--pass-text);
  --chance-large: var(--pass);
  --chance-large-ink: var(--paper-card);
}

/* Exam flag and the header exam chip with its switch menu (X3). */
.x-flag {
  width: 22px; height: 22px; flex: 0 0 auto; border-radius: var(--r-pill); display: inline-block;
  background: linear-gradient(180deg, var(--flag-nl-red) 0 34%, var(--paper-card) 34% 66%, var(--flag-nl-blue) 66%);
  box-shadow: 0 0 0 1.5px var(--paper-card), 0 0 0 2.5px var(--line-strong);
}
.x-flag.it { background: linear-gradient(90deg, var(--flag-it-green) 0 34%, var(--paper-card) 34% 66%, var(--flag-it-red) 66%); }
.x-flag.lg { width: 34px; height: 34px; }
.x-wrap { position: relative; display: inline-flex; }
.x-chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--a11y-tap-target-min);
  padding-block: 0; padding-inline: 6px 10px; border-radius: var(--r-pill); border: 0; background: none; cursor: pointer;
  font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); white-space: nowrap;
}
.x-chip .ic { width: 14px; height: 14px; }
.x-chip[aria-expanded="true"] { background: var(--paper-card); color: var(--ink); box-shadow: var(--shadow-card-sm); }
.x-chip .x-short { display: none; }
.x-menu {
  position: absolute; z-index: 60; inset-block-start: calc(100% + 8px); inset-inline-end: 0; width: 340px;
  padding: 8px; border-radius: var(--r-card-sm); background: var(--paper-card);
  border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow), var(--shadow-card);
}
.x-menu .kicker { padding: 8px 10px 4px; margin: 0; }
.x-row {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 8px 10px; cursor: pointer;
  border: 0; background: none; border-radius: var(--r-input); text-align: start; color: var(--ink); text-decoration: none; font: inherit;
}
.x-row.on { background: var(--glass-dark); color: var(--paper-card); }
.x-row-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.x-row-t b { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.x-row-t small { font-size: 12.5px; color: var(--ink-secondary); }
.x-row.on .x-row-t small { color: var(--tint-on-dark); }
.x-ok { width: 24px; height: 24px; flex: 0 0 auto; border-radius: var(--r-pill); background: var(--paper-card); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; }
.x-ok .ic { width: 14px; height: 14px; }
.x-menu hr { border: 0; border-top: 1px solid var(--line); margin: 6px 10px; }
.x-menu .x-foot { display: flex; align-items: center; gap: 10px; min-height: var(--a11y-tap-target-min); padding: 0 10px; font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--accent-ink); text-decoration: none; }
.x-menu .x-foot .ic { width: 16px; height: 16px; }
/* Below the full header width the chip keeps the flag and the level ("A2"):
   the four links, the run, the language and the avatar take the rest. */
@media (max-width: 1100px) {
  .x-chip .x-long { display: none; }
  .x-chip .x-short { display: inline; }
}
@media (max-width: 560px) {
  .x-chip { padding-inline: 2px 4px; gap: 4px; }
  .x-chip .x-flag { width: 20px; height: 20px; }
  .x-chip .ic { width: 12px; height: 12px; }
  .x-menu { position: fixed; inset-inline: 12px; inset-block-start: 76px; width: auto; }
}

/* An exam row in Settings → Exam (X2) with its mini tubes; the active card
   on the signed-in catalog (X1) carries the ink border. */
.x-lede { margin-top: 0; }
.x-exam {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 14px;
  padding: 16px 18px; border-radius: var(--r-row);
}
.x-exam.on { background: var(--glass-dark); border: 1px solid var(--glass-dark-border); box-shadow: var(--glass-dark-shadow); color: var(--paper-card); }
.x-exam-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.x-exam-t b { font-family: var(--font-display); font-weight: 800; font-size: 18px; line-height: 1.2; }
.x-exam-t span { font-size: 13.5px; color: var(--ink-secondary); }
.x-exam.on .x-exam-t span { color: var(--tint-on-dark); }
.x-exam-r { display: flex; align-items: center; gap: 12px; }
.x-mini { display: flex; gap: 5px; align-items: flex-end; }
.x-mini i { width: 12px; height: 30px; border-radius: var(--r-pill); background: var(--tint-empty-tube); border: 1px solid var(--glass-tank-border); position: relative; overflow: hidden; display: block; }
.x-mini i::after { content: ''; position: absolute; inset-inline: 0; bottom: 0; height: var(--l, 0%); background: linear-gradient(180deg, var(--water-pass-top), var(--water-pass-deep)); }
.x-mini i.w::after { background: linear-gradient(180deg, var(--water-short-top), var(--water-short-deep)); }
.x-mini i.d { border-style: dashed; border-color: var(--ink-faint); }
.x-exam.on .x-mini i { border-color: var(--tint-on-dark-line); background: var(--tint-on-dark-fill); }
.exc-card.x-active { border: 1.5px solid var(--ink); }
@media (max-width: 560px) {
  .x-exam { grid-template-columns: auto minmax(0, 1fr); }
  .x-exam-r { grid-column: 1 / -1; justify-content: space-between; }
}

/* The chance band with the person's pin (N1, N10) and the chance pill. */
.nl-band { margin-top: 12px; }
.nl-band-bar { position: relative; display: flex; gap: 3px; height: 14px; }
.nl-band-bar > span { display: block; height: 100%; border-radius: var(--r-pill); flex: var(--n) 1 0; }
.nl-band-bar > .c0 { background: var(--chance-none); }
.nl-band-bar > .c1 { background: var(--chance-small); }
.nl-band-bar > .c2 { background: var(--chance-fair); }
.nl-band-bar > .c3 { background: var(--chance-large); }
.nl-band-bar > .dim { opacity: .55; }
.nl-band-mk {
  position: absolute; inset-block-start: 50%; inset-inline-start: var(--at); transform: translate(-50%, -50%);
  width: 22px; height: 22px; border-radius: var(--r-pill); background: var(--ink);
  box-shadow: 0 0 0 3px var(--paper-card), var(--shadow-card-sm);
}
[dir="rtl"] .nl-band-mk { transform: translate(50%, -50%); }
.nl-band-mk b {
  position: absolute; inset-block-end: calc(100% + 7px); inset-inline-start: 50%; transform: translateX(-50%);
  font-family: var(--font-display); font-weight: 800; font-size: 13px; line-height: 1; white-space: nowrap;
  padding: 5px 8px; border-radius: var(--r-pill); background: var(--ink); color: var(--paper-card);
}
.nl-band-mk.ghost { background: var(--paper-card); box-shadow: 0 0 0 2px var(--ink-faint); width: 12px; height: 12px; }
.nl-band.has-mk { padding-top: 26px; }
.nl-band-l { display: flex; gap: 3px; margin-top: 7px; }
.nl-band-l > span { flex: var(--n) 1 0; min-width: 0; font-family: var(--font-display); font-weight: 800; font-size: 11.5px; color: var(--ink-tertiary); line-height: 1.25; }
.nl-band-l > span small { display: block; font-family: var(--font-body); font-weight: 600; font-size: 11px; color: var(--ink-tertiary); }
.nl-band-l > span.on { color: var(--ink); }
.nl-band-l > span.on.c0 { color: var(--chance-none-ink); }
.nl-band-l > span.on.c2 { color: var(--chance-fair-ink); }
.nl-band-bar.line > span { flex: 1 1 0; }
.nl-band-line { position: absolute; inset-block: -6px; inset-inline-start: var(--at); width: 0; border-inline-start: 2px dashed var(--ink); }
.nl-band-line b { position: absolute; inset-block-start: calc(100% + 4px); inset-inline-start: -1px; transform: translateX(-50%); font-family: var(--font-display); font-weight: 800; font-size: 11.5px; white-space: nowrap; }
.nl-chance { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: var(--r-pill); font-family: var(--font-display); font-weight: 800; font-size: 12.5px; line-height: 1.2; white-space: nowrap; }
.nl-chance.c0 { background: var(--fail-bg); color: var(--chance-none-ink); }
.nl-chance.c1 { background: var(--warm-bg); color: var(--chance-small-ink); box-shadow: inset 0 0 0 1px var(--chance-small-line); }
.nl-chance.c2 { background: var(--pass-bg); color: var(--chance-fair-ink); }
.nl-chance.c3 { background: var(--chance-large); color: var(--chance-large-ink); }
.nl-chance.done { background: var(--ink); color: var(--paper-card); }
.nl-chance.self { background: var(--paper-card); color: var(--ink-secondary); box-shadow: inset 0 0 0 1.5px var(--line-strong); }
.nl-chance .ic { width: 13px; height: 13px; }
/* A chance tube with no chance yet: warm water without the red rim (the rim
   means "under a published line", which these parts do not have). */
.tk.chance.warm .tk-num.worded { color: var(--fail-ink); }

/* Part rows (Progress N1) and the person's own marks. */
.nl-prow { padding: 18px 0; }
.nl-prow + .nl-prow { border-top: 1px solid var(--line); }
.nl-prow-h { display: flex; align-items: center; gap: 12px; }
.nl-prow-h .lrow-t { font-size: 17px; }
.nl-prow-trail { display: flex; gap: 6px; margin-top: 12px; flex-wrap: wrap; align-items: center; }
.nl-prow-trail .meta { margin-inline-end: 4px; }
.nl-dots { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.nl-dots i { width: 10px; height: 10px; border-radius: var(--r-pill); background: var(--track); display: block; }
.nl-dots i.s1 { background: var(--fail); }
.nl-dots i.s2 { background: var(--pass); }
.nl-dots i.s3 { background: var(--pass-text); }

/* Practice cards (N1): a part passed at the exam body stays, quieter; the
   part's practice exams from the bank, each with its two ways in. */
.pcard3.done { background: var(--tint-empty-tube); border: 1px solid var(--line); box-shadow: none; }
.pc-sc.ok { color: var(--pass-text); }
.pc-sc.ok .ic { width: 22px; height: 22px; }
.nl-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.nl-mocks { margin-top: 2px; border-top: 1px solid var(--line); }
.nl-mocks summary {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: var(--a11y-tap-target-min);
  cursor: pointer; list-style: none; font-family: var(--font-display); font-weight: 800; font-size: 13.5px; color: var(--ink-secondary);
}
.nl-mocks summary::-webkit-details-marker { display: none; }
.nl-mocks summary .ic { width: 16px; height: 16px; }
.nl-mocks[open] summary .ic { transform: rotate(180deg); }
.nl-mocks ol { list-style: none; margin: 0; padding: 0 0 4px; display: flex; flex-direction: column; }
.nl-mrow { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; padding: 4px 0; }
.nl-mrow + .nl-mrow { border-top: 1px solid var(--line); }
.nl-mrow-t { flex: 1 1 110px; min-width: 0; display: flex; flex-direction: column; font-family: var(--font-display); font-weight: 800; font-size: 13.5px; }
.nl-mrow-t small { font-family: var(--font-body); font-weight: 600; font-size: 12px; color: var(--ink-secondary); }
.nl-mrow-go { display: inline-flex; gap: 6px; flex: 0 0 auto; }
.nl-mlink {
  display: inline-flex; align-items: center; min-height: var(--a11y-tap-target-min); padding: 0 12px; border-radius: var(--r-pill);
  font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink); text-decoration: none;
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border);
}

/* Exams at the exam body (N2): one row per part in five states. */
.nl-book {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 16px;
  padding: 16px 18px; border-radius: var(--r-card-sm);
}
.nl-book .lrow-ic { width: 44px; height: 44px; border-radius: var(--r-input-sm); }
.nl-book .lrow-ic .ic { width: 20px; height: 20px; }
.nl-book-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.nl-book-n { font-family: var(--font-display); font-weight: 800; font-size: 17px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nl-book-s { font-size: 13.5px; color: var(--ink-secondary); line-height: 1.4; }
.nl-book-r { display: flex; align-items: center; gap: 12px; }
.nl-book-d { display: flex; flex-direction: column; align-items: center; line-height: 1; min-width: 44px; }
.nl-book-d b { font-family: var(--font-display); font-weight: 800; font-size: 26px; }
.nl-book-d small { font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--ink-secondary); margin-top: 3px; }
.nl-book.booked { border: 1.5px solid var(--ink); }
.nl-book.passed { background: var(--pass-bg); border: 1px solid var(--tint-ok-line); box-shadow: none; }
.nl-book.passed .lrow-ic { background: var(--pass); color: var(--paper-card); }
.nl-book.failed { border: 1.5px solid var(--tint-no-line); }
.nl-book.failed .lrow-ic { background: var(--fail-bg); color: var(--fail-ink); }
.nl-book.waiting .lrow-ic { background: var(--warm-bg); color: var(--accent-ink); }
.nl-book.open { background: var(--tint-empty-tube); border: 1px dashed var(--line-strong); box-shadow: none; }
.nl-mark { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 1; display: flex; flex-direction: column; align-items: center; }
.nl-mark small { font-size: 11.5px; color: var(--ink-secondary); margin-top: 3px; letter-spacing: .04em; text-transform: uppercase; }
.nl-mark.no { color: var(--fail-ink); }
.nl-mark.ok { color: var(--pass-text); }
@media (max-width: 560px) {
  .nl-book { grid-template-columns: 40px minmax(0, 1fr); gap: 12px; padding: 14px; }
  .nl-book .lrow-ic { width: 40px; height: 40px; }
  .nl-book-r { grid-column: 2; justify-content: space-between; }
}
.nl-steps-card { padding: 22px; }
.nl-howto { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.nl-howto li { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 12px; align-items: start; font-size: 14.5px; line-height: 1.5; color: var(--panel-body); }
.nl-howto li > i { width: 30px; height: 30px; border-radius: var(--r-pill); background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); color: var(--paper-card); display: flex; align-items: center; justify-content: center; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.nl-howto b { color: var(--paper-card); font-family: var(--font-display); font-weight: 800; }
/* The date sheet (N2·date): three fields under the question. */
.nl-date-sheet { max-width: 560px; }
.nl-date-fields { width: 100%; text-align: start; margin-top: 8px; display: flex; flex-direction: column; gap: 4px; }
.sh-note.warn { background: var(--warm-bg); color: var(--accent-ink); }

/* Result entry (N3) and after it. */
.nl-solo { max-width: 620px; margin: 8px auto 0; display: flex; flex-direction: column; align-items: center; text-align: center; }
.nl-solo .lede { margin-inline: auto; }
.nl-solo .btn-block { max-width: 420px; }
.nl-back { align-self: stretch; }
.nl-w100, .nl-res-card { width: 100%; text-align: start; }
.nl-koi { width: 150px; height: 150px; object-fit: contain; }
.nl-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.nl-pick button {
  min-height: 64px; border-radius: var(--r-row); display: flex; align-items: center; justify-content: center; gap: 10px; padding: 0 12px;
  font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink); cursor: pointer;
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
}
.nl-pick button .ic { width: 20px; height: 20px; flex: 0 0 auto; }
.nl-pick button[aria-pressed="true"] { background: var(--glass-dark); color: var(--paper-card); border-color: var(--glass-dark-border); box-shadow: var(--glass-dark-shadow); }
.nl-pick button[aria-pressed="true"] .ic { color: var(--teal-glow); }
.nl-marks { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 6px; margin-top: 12px; }
.nl-marks button {
  min-height: var(--a11y-tap-target-min); border-radius: var(--r-tile); cursor: pointer;
  border: 1.5px solid var(--line-strong); background: var(--paper-card);
  font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--ink-secondary);
}
.nl-marks button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
@media (max-width: 560px) {
  .nl-pick { grid-template-columns: minmax(0, 1fr); }
  .nl-marks { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
.nl-steps-plan { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; }
.nl-steps-plan li { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 12px 0; min-height: 56px; }
.nl-steps-plan li + li { border-top: 1px solid var(--line); }
.nl-steps-plan li > i { width: 34px; height: 34px; border-radius: var(--r-tile); background: var(--tint-teal-tile); color: var(--pass-text); display: flex; align-items: center; justify-content: center; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.nl-steps-plan b { font-family: var(--font-display); font-weight: 800; font-size: 15px; display: block; }
.nl-steps-plan small { font-size: 13px; color: var(--ink-secondary); }
@media (max-width: 560px) { .nl-steps-plan li { grid-template-columns: 34px minmax(0, 1fr); } .nl-steps-plan li > .btn { grid-column: 2; justify-self: start; } }

/* Pricing without a price (L3): the dark card's word, the other exam's own
   package, the parts the package covers (passed ones struck through). */
.nl-price-tbd { font-family: var(--font-display); font-weight: 800; font-size: 34px; line-height: 1.05; color: var(--paper-card); margin-top: 6px; }
.nl-owned { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-radius: var(--r-card-sm); }
.nl-owned .x-flag { width: 28px; height: 28px; }
.nl-owned-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.nl-owned-t b { font-family: var(--font-display); font-weight: 800; font-size: 15.5px; }
.nl-owned-t span { font-size: 13.5px; color: var(--ink-secondary); }
.nl-parts5 { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.nl-parts5 span { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 12px; border-radius: var(--r-pill); font-family: var(--font-display); font-weight: 800; font-size: 13px; background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); color: var(--paper-card); }
.nl-parts5 span.off { color: var(--tint-on-dark); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.nl-parts5 span .ic { width: 13px; height: 13px; }

/* The overview grid of a question frame (N4): a bookmarked question carries
   an orange corner fold (readable on white and on ink), and the current
   question keeps its ring once it is answered. */
.all-grid button { position: relative; }
.all-grid button.flag { overflow: hidden; }
.all-grid button.flag::after {
  content: ''; position: absolute; inset-block-start: -1.5px; inset-inline-end: -1.5px; width: 14px; height: 14px;
  border-start-end-radius: var(--r-tile); background: linear-gradient(225deg, var(--accent) 50%, transparent 50%);
}
[dir="rtl"] .all-grid button.flag::after { background: linear-gradient(135deg, var(--accent) 50%, transparent 50%); }
.nl-ov .all-grid button.cur.done { color: var(--paper-card); border-color: var(--ink); outline: 2px solid var(--accent); outline-offset: 2px; }

/* Five worded tubes: "self-check" is the longest word over a tube and fits
   its column a size down (two of them side by side would touch). */
.tanks.n5 .tk.self .tk-num.worded { font-size: 13px; letter-spacing: -.01em; white-space: nowrap; }
@media (max-width: 560px) { .tanks.n5 .tk.self .tk-num.worded { font-size: 11px; letter-spacing: -.03em; } }

/* Dutch players — speaking and writing (design/handoff-v4-nl N8, N9, N10;
   web/ui/nl/recorder.js, spreken.js, schrijven.js). Colours, radii and
   motion only through tokens. The first group holds what every Dutch task
   screen shares and the multiple-choice block below builds on (the proposed
   tokens, the players' base, the option-size play button, photo captions and
   the full-screen photo); the bar, the overview, the photo frames and the
   player variants are declared with the multiple-choice players. */
:root {
  /* Design v4 proposed tokens, as aliases of existing ones (README §4). */
  --nl-bar-h: 64px;
  --nl-photo-ratio: 4 / 3;
  --nl-r-photo: var(--r-input-sm);
  --nl-r-box: var(--r-bar-top);
  --nl-speak: var(--motion-fill);
}

/* ─ shared by every Dutch task screen ─ */
.nl-ov .all-grid.nl-ov-grid { grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 6px; }
@media (max-width: 560px) { .nl-ov .all-grid.nl-ov-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; } }
.nl-pics figure { min-width: 0; }
.nl-pics figcaption { position: absolute; inset-block-start: 8px; inset-inline-start: 8px; min-width: 28px; height: 28px; padding: 0 8px; border-radius: var(--r-pill); background: var(--paper-card); color: var(--ink); font-family: var(--font-display); font-weight: 800; font-size: 14px; display: flex; align-items: center; justify-content: center; box-shadow: var(--shadow-card-sm); pointer-events: none; }
.nl-zoom { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; border-radius: var(--nl-r-photo); }
.nl-zoomed { position: fixed; inset: 0; z-index: 80; background: var(--tint-viewer); display: flex; align-items: center; justify-content: center; padding: 24px; }
.nl-zoomed img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--nl-r-photo); box-shadow: var(--shadow-card); }
.nl-zoomed .icon-btn { position: absolute; inset-block-start: 16px; inset-inline-end: 16px; }
/* The players' base: the play button, the label and time, the track (--p is
   the position), the skip buttons. */
.nl-player { min-width: 0; }
.nl-pp {
  width: 44px; height: 44px; border-radius: var(--r-pill); border: 0; cursor: pointer; flex: 0 0 auto;
  background: var(--ink); color: var(--paper-card); display: inline-flex; align-items: center; justify-content: center; box-shadow: var(--shadow-card-sm);
}
.nl-pp .ic { width: 18px; height: 18px; }
.nl-pl-main { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.nl-track { position: relative; height: 6px; border-radius: var(--r-pill); background: var(--track); }
.nl-track i { position: absolute; inset-block: 0; inset-inline-start: 0; width: var(--p, 0%); border-radius: var(--r-pill); background: var(--pass); }
.nl-track b { position: absolute; top: 50%; inset-inline-start: var(--p, 0%); width: 16px; height: 16px; margin-inline-start: -8px; transform: translateY(-50%); border-radius: var(--r-pill); background: var(--paper-card); box-shadow: 0 0 0 2px var(--pass), var(--shadow-card-sm); }
.nl-pp:disabled { opacity: .4; cursor: default; }
/* An option-size play button with a ring for progress (N6, N7, N8). */
.nl-mini {
  width: 44px; height: 44px; flex: 0 0 auto; border-radius: var(--r-pill); cursor: pointer; position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow); color: var(--ink);
}
.nl-mini .ic { width: 16px; height: 16px; }
.nl-mini.on { background: var(--ink); color: var(--paper-card); border-color: var(--ink); }
.nl-mini .nl-ring { position: absolute; inset: -3px; width: calc(100% + 6px); height: calc(100% + 6px); transform: rotate(-90deg); pointer-events: none; }
.nl-mini .nl-ring circle { fill: none; stroke: var(--pass); stroke-width: 3; stroke-linecap: round; }
[dir="rtl"] .nl-mini .nl-ring { transform: rotate(-90deg) scaleY(-1); }
.nl-m0 { margin: 0; }
.nl-h2 { font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 1.2; margin: 6px 0 0; }
.nl-rule { width: 100%; border: 0; border-top: 1.5px solid var(--line-strong); margin: 8px 0; }

/* ─ Spreken (N8) ─ */
.nl-sp { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 24px; align-items: start; }
@media (max-width: 900px) { .nl-sp { grid-template-columns: minmax(0, 1fr); gap: 16px; } }
/* Phone and narrow web (design N8·selfcheck): the task and the answer, then
   the samples, then the checklist and the pick. */
@media (max-width: 900px) {
  .nl-sp.self > .stack-lg:first-child { display: contents; }
  .nl-sp.self > .nl-samples { order: 1; }
  .nl-sp.self .nl-checkcard { order: 2; }
  /* The model check follows the person's own mark (design v5 M3·avail), then Save. */
  .nl-sp.self .nl-model { order: 3; }
  .nl-sp.self .nl-savebar { order: 4; }
}
/* The video person (design v5 N11): her portrait in a circle, rings that
   radiate while she speaks (red while the candidate records), the seek ring
   over the photo's edge. On the paper, no card. */
.nl-pt { --pt-d: var(--sp-portrait); display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 6px 0 4px; text-align: center; }
@media (min-width: 1000px) { .nl-pt:not(.compact) { --pt-d: var(--sp-portrait-wide); } }
.nl-pt-stage { position: relative; width: calc(var(--pt-d) + 70px); height: calc(var(--pt-d) + 70px); max-width: 100%; display: flex; align-items: center; justify-content: center; }
.nl-pt-r, .nl-pt-halo { position: absolute; inset-block-start: 50%; inset-inline-start: 50%; width: var(--pt-d); height: var(--pt-d); margin-block-start: calc(var(--pt-d) / -2); margin-inline-start: calc(var(--pt-d) / -2); border-radius: var(--r-pill); opacity: 0; pointer-events: none; }
.nl-pt-r { border: 2px solid var(--tint-pt-ring-1); }
.nl-pt-r.r2 { border-color: var(--tint-pt-ring-2); }
.nl-pt-r.r3 { border-color: var(--tint-pt-ring-3); }
.nl-pt-halo { width: calc(var(--pt-d) + 20px); height: calc(var(--pt-d) + 20px); margin-block-start: calc(var(--pt-d) / -2 - 10px); margin-inline-start: calc(var(--pt-d) / -2 - 10px); background: var(--tint-pt-halo); }
.nl-pt-stage.rec .nl-pt-r { border-color: var(--tint-pt-rec-1); }
.nl-pt-stage.rec .nl-pt-r.r2 { border-color: var(--tint-pt-rec-2); }
.nl-pt-stage.rec .nl-pt-r.r3 { border-color: var(--tint-pt-rec-3); }
.nl-pt-stage.rec .nl-pt-halo { background: var(--tint-pt-rec-halo); }
.nl-pt-stage.talk .nl-pt-r, .nl-pt-stage.rec .nl-pt-r, .nl-pt-stage.talk .nl-pt-halo, .nl-pt-stage.rec .nl-pt-halo { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .nl-pt-stage.talk .nl-pt-r, .nl-pt-stage.rec .nl-pt-r { animation: nl-pt-ring var(--motion-ring-1) ease-out 0s infinite; }
  .nl-pt-stage.talk .nl-pt-r.r2, .nl-pt-stage.rec .nl-pt-r.r2 { animation-duration: var(--motion-ring-2); animation-delay: .5s; }
  .nl-pt-stage.talk .nl-pt-r.r3, .nl-pt-stage.rec .nl-pt-r.r3 { animation-duration: var(--motion-ring-3); animation-delay: 1.1s; }
  .nl-pt-stage.talk .nl-pt-halo { animation: nl-pt-talk var(--motion-talk) ease-in-out infinite; }
  .nl-pt-stage.rec .nl-pt-halo { animation: nl-pt-talk var(--motion-talk-listen) ease-in-out infinite; }
  @keyframes nl-pt-ring { 0% { transform: scale(1); opacity: .6; } 100% { transform: scale(1.32); opacity: 0; } }
  @keyframes nl-pt-talk { 0% { transform: scale(1); } 14% { transform: scale(1.07); } 26% { transform: scale(1.02); } 41% { transform: scale(1.1); } 55% { transform: scale(1.04); } 68% { transform: scale(1.08); } 82% { transform: scale(1.01); } 100% { transform: scale(1); } }
}
.nl-pt-face { position: relative; z-index: 1; width: var(--pt-d); height: var(--pt-d); padding: 0; border: 0; border-radius: var(--r-pill); overflow: hidden; cursor: pointer;
  background: linear-gradient(165deg, var(--portrait-top), var(--portrait-bottom)); box-shadow: var(--shadow-portrait); }
.nl-pt-face[aria-disabled="true"] { cursor: default; }
.nl-pt-face img { display: block; width: 100%; height: 100%; object-fit: cover; }
.nl-pt-fig { display: flex; align-items: flex-end; justify-content: center; width: 100%; height: 100%; }
.nl-pt-fig svg { width: 80%; height: 80%; }
.nl-pt-fig .fig { fill: var(--ink-tertiary); }
.nl-pt-seek { position: absolute; z-index: 2; inset-block-start: 50%; inset-inline-start: 50%; width: var(--pt-d); height: var(--pt-d); margin-block-start: calc(var(--pt-d) / -2); margin-inline-start: calc(var(--pt-d) / -2); overflow: visible; pointer-events: none; border-radius: var(--r-pill); }
.nl-pt-track, .nl-pt-arc, .nl-pt-hit { fill: none; stroke-width: 5; }
.nl-pt-track { stroke: var(--tint-pt-track); }
/* Both turn about the circle's centre in the SVG's own units. */
.nl-pt-arc, .nl-pt-knob { transform-box: view-box; transform-origin: 110px 110px; }
.nl-pt-arc { stroke: var(--pass); stroke-linecap: round; transform: rotate(-90deg); }
.nl-pt-knob { transform: rotate(var(--a, 0deg)); }
.nl-pt-knob circle { fill: var(--paper-card); filter: drop-shadow(var(--shadow-portrait-knob)); }
.nl-pt-hit { stroke: transparent; stroke-width: 26; pointer-events: stroke; cursor: pointer; touch-action: none; }
.nl-pt-n { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 1; color: var(--ink); }
.nl-pt-s { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 22px; margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 14px; color: var(--pass-text); }
.nl-pt-s .cue-eq { color: var(--pass); }
.nl-pt-s.rec { color: var(--water-rec-deep); }
.nl-pt-s.rec i { width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--fail); }
@media (prefers-reduced-motion: no-preference) { .nl-pt-s.rec i { animation: pk-blink var(--motion-rec) steps(1) infinite; } }
.nl-pt-t { font-family: var(--font-body); font-weight: 700; font-variant-numeric: tabular-nums; }
.nl-pt-v { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 12.5px; font-weight: 700; color: var(--pass-text); }
.nl-pt-v .ic { width: 14px; height: 14px; }
/* In the self-check: a small circle beside the name. */
.nl-pt.compact { --pt-d: 72px; flex-direction: row; gap: 14px; padding: 14px 18px; text-align: start; }
.nl-pt-face.sm { flex: 0 0 auto; }
.nl-pt-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.nl-pt-n.sm { font-size: 20px; }
.nl-pt.compact .nl-pt-s { justify-content: flex-start; }
.nl-pt.compact .nl-speak { height: 28px; overflow: hidden; }
.nl-pt.compact .nl-speak i { background: var(--pass); }
.nl-pt.compact .nl-speak.still i { background: var(--line); }
.nl-on-dark { color: var(--tint-on-dark); margin: 0; }
.nl-speak { display: flex; align-items: center; gap: 4px; height: 44px; }
.nl-speak i { width: 5px; height: var(--h); border-radius: var(--r-pill); background: var(--teal-glow); display: block; transform: scaleY(.35); }
.nl-speak.still i { background: var(--panel-ring); }
@media (prefers-reduced-motion: no-preference) {
  .nl-speak:not(.still) i { animation: nl-speak var(--nl-speak) ease-in-out infinite alternate; animation-delay: calc(var(--d) * -1s); }
  @keyframes nl-speak { from { transform: scaleY(.35); } to { transform: scaleY(1); } }
}
.nl-scene { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 8px; margin: 0; font-size: 13.5px; line-height: 1.4; color: var(--tint-on-dark); }
.nl-scene .ic { width: 18px; height: 18px; flex: 0 0 auto; color: var(--teal-glow); }
.nl-scene-t { font-variant-numeric: tabular-nums; }
.nl-task { padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.nl-task-t { display: flex; align-items: flex-start; gap: 12px; }
.nl-task-t p { margin: 0; flex: 1; font-size: 17px; line-height: 1.5; font-weight: 700; }
/* The recorder: record button in a countdown ring, then play back, record
   again, delete. */
.nl-rec { padding: 24px; display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; }
.nl-rec .kicker { margin: 0; }
.nl-rec.live .nl-rec-k { color: var(--fail-ink); }
.nl-rec-ring { position: relative; width: 148px; height: 148px; display: flex; align-items: center; justify-content: center; }
.nl-rec-arc {
  position: absolute; inset: 0; border-radius: var(--r-pill);
  background: conic-gradient(var(--fail) var(--lvl, 0%), var(--line) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), var(--ink) calc(100% - 6px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 6px), var(--ink) calc(100% - 6px));
}
.nl-rec-btn {
  width: 104px; height: 104px; border-radius: var(--r-pill); border: 0; cursor: pointer; position: relative; z-index: 1;
  background: linear-gradient(180deg, var(--water-rec-top), var(--water-rec-mid) 55%, var(--water-rec-deep));
  color: var(--paper-card); display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 14px 28px -14px var(--tint-rec), inset 0 1px 0 var(--tint-shine);
}
.nl-rec-btn .ic { width: 38px; height: 38px; }
.nl-rec-btn.stop .ic { width: 34px; height: 34px; }
@media (prefers-reduced-motion: no-preference) {
  .nl-rec.live .nl-rec-btn { animation: nl-recpulse var(--motion-rec) ease-out infinite; }
  @keyframes nl-recpulse { from { box-shadow: 0 0 0 0 var(--tint-rec); } to { box-shadow: 0 0 0 18px var(--tint-rec-end); } }
}
.nl-rec-time { display: flex; flex-direction: column; align-items: center; }
.nl-rec-time b { font-family: var(--font-display); font-weight: 800; font-size: 34px; line-height: 1; font-variant-numeric: tabular-nums; }
.nl-rec-time small { display: block; font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-secondary); margin-top: 6px; }
.nl-rec.live .nl-rec-time b { color: var(--fail-ink); }
/* The recorder dock (N11): fixed above the bottom bar, as wide as it; the page
   keeps room for it so nothing hides behind. */
.nl-stage.has-dock { padding-bottom: calc(var(--nl-bar-h) + 56px + 150px); }
.nl-sp.docked { grid-template-columns: minmax(0, 1fr); justify-items: center; }
.nl-sp.docked > .nl-task, .nl-sp.docked > .nl-rec { width: 100%; max-width: 720px; }
.nl-rdock {
  position: fixed; z-index: 39; inset-inline: 0; margin-inline: auto; bottom: calc(18px + var(--nl-bar-h) + 10px);
  width: min(560px, calc(100% - 48px)); padding: 10px; border-radius: var(--r-dock); color: var(--paper-card);
  background: linear-gradient(155deg, var(--panel-from), var(--panel-to)); border: 1px solid var(--glass-dark-border); box-shadow: var(--shadow-panel);
  display: flex; flex-direction: column; gap: 10px;
}
.nl-rdock.done { padding: 12px 12px 12px 16px; }
.nl-rdock.rec { flex-direction: row; align-items: center; gap: 12px; padding: 14px 16px;
  background: linear-gradient(160deg, var(--water-rec-mid), var(--water-rec-deep)); border-color: transparent; }
.nl-rd-go {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px; width: 100%; min-height: 54px; padding: 0 24px;
  border: 0; border-radius: var(--r-pill); cursor: pointer; background: var(--paper-card); color: var(--ink); box-shadow: var(--shadow-card-sm);
  font-family: var(--font-display); font-weight: 800; font-size: 17px;
}
.nl-rdock.done .nl-rd-go { min-height: 46px; font-size: 15px; }
.nl-rd-go.rec i { width: 13px; height: 13px; border-radius: var(--r-pill); background: var(--fail); }
.nl-rd-go small { font-family: var(--font-body); font-weight: 700; font-size: 13.5px; color: var(--ink-secondary); }
.nl-rd-go.ghost { min-height: 44px; background: var(--tint-on-dark-fill); color: var(--paper-card); box-shadow: none; font-size: 15px; }
.nl-rd-row { display: flex; align-items: center; gap: 10px; }
.nl-rd-ic { flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--r-pill); cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); color: var(--paper-card); }
.nl-rd-ic .ic { width: 18px; height: 18px; }
.nl-rd-t { flex: 1; min-width: 0; }
.nl-rd-k { display: flex; align-items: center; gap: 7px; margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 11px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--panel-rec); }
.nl-rd-k i { width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--paper-card); }
.nl-rd-time { display: flex; align-items: baseline; gap: 8px; margin: 2px 0 0; }
.nl-rd-time b { font-family: var(--font-display); font-weight: 800; font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; }
.nl-rd-time small { font-size: 13px; color: var(--panel-rec); }
.nl-rdock .nl-rec-lvl { height: 26px; margin-top: 4px; }
.nl-rdock .nl-rec-lvl i { background: var(--paper-card); width: 3px; }
.nl-rd-stop { flex: 0 0 auto; width: 64px; height: 64px; border: 0; border-radius: var(--r-pill); cursor: pointer; display: flex; align-items: center; justify-content: center;
  background: var(--paper-card); color: var(--water-rec-deep); }
.nl-rd-stop .ic { width: 26px; height: 26px; }
@media (prefers-reduced-motion: no-preference) {
  .nl-rd-stop { animation: nl-recpulse var(--motion-rec) ease-out infinite; }
  .nl-rd-k i { animation: pk-blink var(--motion-rec) steps(1) infinite; }
}
@media (max-width: 560px) {
  .nl-rdock { width: calc(100% - 24px); bottom: calc(max(12px, calc(env(safe-area-inset-bottom) + 4px)) + var(--nl-bar-h) + 8px); }
}
.nl-bar .nl-next[aria-disabled="true"] { opacity: .45; cursor: default; }
/* While the candidate records, the video person's red halo follows the voice. */
/* ─ Sound-driven motion (design decision 43) ─
   frame.js puts the playing file's loudness on the root (--nl-amp1..3, class
   nl-amp), recorder.js the microphone's (--nl-mic, class nl-mic). Bars, halos,
   rings and glows follow them; without them, or with Reduced Motion, the
   looped or still looks above stay. */
.nl-rdock { isolation: isolate; overflow: hidden; }
.dock5 { position: relative; isolation: isolate; overflow: hidden; }
.nl-rdock.rec { background: linear-gradient(115deg, var(--water-rec-mid), var(--water-rec-deep) 45%, var(--water-rec-mid) 70%, var(--water-rec-deep));
  background-size: 260% 100%; }
.nl-rdock::before, .dock5::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0; }
.nl-rdock.rec::before { background: radial-gradient(circle at 88% 50%, var(--tint-mic-glow), transparent 58%); }
.dock5::before { background: radial-gradient(circle at 84% 60%, var(--tint-amp-glow), transparent 55%); }
/* The recorder's morphs (spreken.js morph): --m-t is how far into the move a
   redraw lands, so the motion carries on across redraws. */
.nl-rdock::after { content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; pointer-events: none; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  /* Record → recording: the white pill fills the dock and turns red. */
  .nl-rdock.rec.m-from-idle { animation: nl-m-grow var(--motion-morph) var(--motion-ease-enter) both, nl-flow var(--motion-flow) ease-in-out infinite alternate;
    animation-delay: var(--m-t, 0ms), 0ms; }
  .nl-rdock.rec.m-from-idle::after { background: var(--paper-card); animation: nl-m-flash var(--motion-morph) var(--motion-ease-enter) both; animation-delay: var(--m-t, 0ms); }
  .nl-rdock.rec.m-from-idle > * { animation: nl-m-in var(--motion-morph) var(--motion-ease-enter) both; animation-delay: calc(var(--m-t, 0ms) + 120ms); }
  .nl-rdock.rec.m-from-idle .nl-rd-stop { animation: nl-m-pop var(--motion-morph) var(--motion-ease-enter) both; animation-delay: calc(var(--m-t, 0ms) + 160ms); }
  @keyframes nl-m-grow { from { clip-path: inset(10px round 27px); } to { clip-path: inset(0 round 24px); } }
  @keyframes nl-m-flash { from { opacity: 1; } 55% { opacity: .35; } to { opacity: 0; } }
  @keyframes nl-m-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
  @keyframes nl-m-pop { from { opacity: 0; transform: scale(.4); } 70% { opacity: 1; transform: scale(1.08); } to { transform: none; } }
  /* Stop → recorded: the red sinks to dark from Stop's corner, the play disc lands. */
  .nl-rdock.done.m-from-rec::after { background: linear-gradient(160deg, var(--water-rec-mid), var(--water-rec-deep));
    animation: nl-m-sink var(--motion-morph) var(--motion-ease-enter) both; animation-delay: var(--m-t, 0ms); }
  .nl-rdock.done.m-from-rec .nl-rd-row > *, .nl-rdock.done.m-from-rec .nl-rd-go { animation: nl-m-in var(--motion-morph) var(--motion-ease-enter) both;
    animation-delay: calc(var(--m-t, 0ms) + 140ms); }
  .nl-rdock.done.m-from-rec .nl-pp { animation: nl-m-pop var(--motion-morph) var(--motion-ease-enter) both; animation-delay: calc(var(--m-t, 0ms) + 100ms); }
  @keyframes nl-m-sink { from { opacity: 1; clip-path: circle(150% at 88% 50%); } to { opacity: 1; clip-path: circle(0 at 88% 50%); } }
  /* Deleted → Record again: the pill comes back. */
  .nl-rdock.m-from-done .nl-rd-go { animation: nl-m-pop var(--motion-morph) var(--motion-ease-enter) both; animation-delay: var(--m-t, 0ms); }
  .nl-rdock.rec { animation: nl-flow var(--motion-flow) ease-in-out infinite alternate; }
  @keyframes nl-flow { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }
  :root.nl-amp .cue-eq i { animation: none; transition: transform var(--motion-amp) linear; transform: scaleY(calc(.3 + .7 * var(--nl-amp1, 0))); }
  :root.nl-amp .cue-eq i:nth-child(2) { transform: scaleY(calc(.3 + .7 * var(--nl-amp2, 0))); }
  :root.nl-amp .cue-eq i:nth-child(3) { transform: scaleY(calc(.3 + .7 * var(--nl-amp3, 0))); }
  :root.nl-amp .nl-speak:not(.still) i { animation: none; transition: transform var(--motion-amp) linear;
    transform: scaleY(calc(.25 + .75 * var(--nl-amp1, 0) * (.5 + var(--d)))); }
  :root.nl-amp .nl-pt-stage.talk .nl-pt-halo { animation: none; transition: transform var(--motion-amp) linear, opacity var(--motion-amp) linear;
    transform: scale(calc(1 + .14 * var(--nl-amp1, 0))); opacity: calc(.45 + .55 * var(--nl-amp1, 0)); }
  :root.nl-amp .nl-pt-stage.talk .nl-pt-r { border-width: calc(1.5px + 2.5px * var(--nl-amp2, 0)); }
  :root.nl-amp .cue-play .cue-d { transition: box-shadow var(--motion-amp) linear;
    box-shadow: 0 0 0 calc(3px + 7px * var(--nl-amp1, 0)) var(--tint-cue-halo); }
  :root.nl-amp .dock5:has(.k-play)::before { opacity: calc(.25 + .75 * var(--nl-amp1, 0)); transition: opacity var(--motion-amp) linear; }
  :root.nl-amp .dock5 .tp5-big { transition: box-shadow var(--motion-amp) linear;
    box-shadow: var(--shadow-card-sm), 0 0 0 calc(8px * var(--nl-amp1, 0)) var(--tint-amp-glow); }
  :root.nl-mic .nl-pt-stage.rec .nl-pt-halo { animation: none; transition: transform var(--motion-amp) linear;
    transform: scale(calc(1 + .16 * var(--nl-mic, 0))); }
  :root.nl-mic .nl-rdock.rec::before { opacity: calc(.2 + .8 * var(--nl-mic, 0)); transition: opacity var(--motion-amp) linear; }
  :root.nl-mic .nl-rd-stop { animation: none; transition: box-shadow var(--motion-amp) linear;
    box-shadow: 0 0 0 calc(3px + 14px * var(--nl-mic, 0)) var(--tint-pt-rec-3); }
}
.nl-rec-lvl { display: flex; align-items: center; gap: 3px; height: 28px; }
.nl-rec-lvl i { width: 4px; height: calc(4px + var(--k, .1) * 24px); border-radius: var(--r-pill); background: var(--fail); display: block; transition: height var(--motion-fast) linear; }
.nl-rec.done { align-items: stretch; text-align: start; }
.nl-rec.done > .kicker { text-align: center; }
.nl-rec-acts { display: flex; gap: 10px; width: 100%; justify-content: center; }
.nl-rec-acts .btn { flex: 1 1 auto; width: auto; justify-content: center; }
.nl-rec-acts .icon-del { flex: 0 0 auto; min-width: 88px; }
@media (max-width: 560px) { .nl-rec-acts .icon-del { min-width: 56px; padding-inline: 0; } }
.nl-rec.off .nl-rec-acts { flex-wrap: wrap; }
/* An open sheet covers the task: the fixed bar under the glass would read as
   part of the sheet. */
.nl-bar:has(~ .pk-scrim) { visibility: hidden; }
.nl-rec.off { align-items: center; }
.nl-rec.off .state-ic { margin: 0; }
.nl-rec .btn-block { width: 100%; }
/* Block screens: "Onderdeel N" before, "Einde onderdeel N" after. Silent. */
.nl-blockscreen { max-width: 640px; margin: 24px auto 0; padding: 32px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.nl-blockscreen h1 { margin: 0; }
.nl-blockscreen .kicker { margin: 0; }
.nl-bs-text { font-size: 17px; line-height: 1.6; max-width: 480px; margin: 0; }
.nl-tasks4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; width: 100%; max-width: 420px; margin-top: 8px; }
.nl-tasks4 > * { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: var(--a11y-tap-target-min); padding: 10px 6px; border-radius: var(--r-input-sm); border: 1.5px solid var(--line-strong); background: var(--paper-card); color: var(--ink); font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.nl-tasks4 > button { cursor: pointer; font: inherit; font-family: var(--font-display); font-weight: 800; }
.nl-tasks4 small { font-family: var(--font-body); font-weight: 600; font-size: 11.5px; color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.nl-tasks4 .done { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
.nl-tasks4 .done small { color: var(--tint-on-dark); }
.nl-tasks4 .ic { width: 16px; height: 16px; }
@media (max-width: 560px) { .nl-blockscreen { padding: 24px 18px; } }

/* ─ Samples 3 · 2 · 1 and the self-check (N8, N9) ─ */
.nl-sample { padding: 16px 18px; border-radius: var(--r-card-md); display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 4px 14px; }
.nl-sample > :not(.nl-sample-sc) { grid-column: 2; min-width: 0; }
.nl-sample-sc { grid-row: span 3; width: 44px; height: 44px; border-radius: var(--r-input-sm); display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 800; font-size: 22px; background: var(--pass-bg); color: var(--pass-text); }
.nl-sample.s3 .nl-sample-sc { background: var(--pass); color: var(--paper-card); }
.nl-sample.s1 { background: var(--fail-bg); border: 1px solid var(--tint-no-line); box-shadow: none; }
.nl-sample.s1 .nl-sample-sc { background: var(--paper-card); color: var(--fail-ink); border: 1.5px solid var(--fail-border); }
.nl-sample-h b { font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.nl-sample.s1 .nl-sample-h b { color: var(--fail-ink); }
.nl-sample-x { margin: 0; font-size: 15.5px; line-height: 1.55; font-weight: 700; }
/* A folded sample (the 2 and the 1): a row with its badge and title; open, the answer
   and the note below it. */
.nl-sample.fold { display: block; padding: 10px 14px 10px 10px; }
.nl-sample.fold > summary { display: flex; align-items: center; gap: 14px; min-height: var(--a11y-tap-target-min); cursor: pointer; list-style: none; }
.nl-sample.fold > summary::-webkit-details-marker { display: none; }
.nl-sample.fold > summary .nl-sample-sc { grid-row: auto; flex: 0 0 auto; }
.nl-sample.fold > summary .nl-sample-h { flex: 1; min-width: 0; }
.nl-sample.fold > summary .ic { width: 18px; height: 18px; color: var(--ink-secondary); transition: transform var(--motion-base) var(--motion-ease); }
.nl-sample.fold[open] > summary .ic { transform: rotate(180deg); }
.nl-sample.fold > :not(summary) { margin: 8px 0 4px 58px; }
@media (prefers-reduced-motion: no-preference) {
  .nl-sample.fold[open] > :not(summary) { animation: ak-slide var(--motion-slow) var(--motion-ease-enter) both; }
}
.nl-sample-n { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-secondary); }
.nl-sample.s1 .nl-sample-n { color: var(--ink-warm); }
.nl-more { margin-top: 4px; }
.nl-more summary { cursor: pointer; font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); min-height: 32px; display: inline-flex; align-items: center; }
.nl-fsample { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 2px 12px; margin: 0; font-size: 14.5px; line-height: 1.45; }
.nl-fsample dt { font-weight: 800; color: var(--ink-secondary); }
.nl-fsample dd { margin: 0; font-weight: 700; overflow-wrap: anywhere; }
.nl-fs-choice { margin-top: 8px; font-size: 14.5px; }
.nl-fs-choice p { margin: 0 0 4px; font-weight: 800; }
.nl-fs-opt { display: flex; align-items: center; gap: 8px; min-height: 28px; font-weight: 700; }
.nl-fs-ans { margin: 8px 0 0; padding-inline-start: 18px; font-size: 14.5px; line-height: 1.5; font-weight: 700; }
.nl-fs-ans b { display: block; font-weight: 800; color: var(--ink-secondary); }
.nl-mine { padding: 16px 18px; border-radius: var(--r-card-md); }
.nl-mine .kicker { margin: 0 0 10px; }
.nl-checks { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; }
.nl-checks li + li { border-top: 1px solid var(--line); }
.nl-check { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 11px 0; min-height: var(--a11y-tap-target-min); border: 0; background: none; cursor: pointer; text-align: start; font: inherit; font-size: 15px; line-height: 1.45; color: var(--ink); }
.nl-box { width: 24px; height: 24px; flex: 0 0 auto; border-radius: var(--nl-r-box); border: 2px solid var(--line-strong); background: var(--paper-card); display: inline-flex; align-items: center; justify-content: center; color: var(--paper-card); margin-top: 1px; }
.nl-box .ic { width: 15px; height: 15px; stroke-width: 3; }
.nl-box.on { background: var(--ink); border-color: var(--ink); }
.nl-self { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.nl-self button { min-height: 56px; border-radius: var(--r-input); cursor: pointer; border: 1.5px solid var(--line-strong); background: var(--paper-card); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; font-family: var(--font-display); font-weight: 800; font-size: 20px; color: var(--ink); }
.nl-self button small { font-family: var(--font-body); font-weight: 600; font-size: 11.5px; color: var(--ink-secondary); }
.nl-self button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper-card); }
.nl-self button[aria-pressed="true"] small { color: var(--tint-on-dark); }
.nl-checkcard .btn-dark:disabled { opacity: .45; cursor: default; }
/* Model feedback: only with marking on, labelled indicative. */
.nl-model { padding: 20px; border: 1.5px solid var(--pass-border); }
.nl-model.idle { border-style: dashed; }
.nl-model-h { display: flex; align-items: center; gap: 10px; }
.nl-model-h .lrow-t { flex: 1; min-width: 0; }
.nl-transcript { margin: 10px 0 0; padding: 12px 14px; border-radius: var(--r-input); background: var(--paper-warm); font-size: 15px; line-height: 1.55; font-weight: 700; white-space: pre-line; overflow-wrap: anywhere; }
.nl-transcript.mine { font-weight: 600; margin: 0; }
.nl-transcript mark { background: var(--trap); border-radius: var(--nl-r-box); padding: 0 2px; color: inherit; }
.nl-axes.one { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: center; margin-top: 12px; }
.nl-axes.one > div { padding: 10px 14px; border-radius: var(--r-input-sm); background: var(--paper-card); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 2px; }
.nl-axes b { font-family: var(--font-display); font-weight: 800; font-size: 24px; line-height: 1.1; }
.nl-axes b small { font-size: 13px; color: var(--ink-secondary); }
.nl-axes span { font-size: 12px; color: var(--ink-secondary); }
.nl-mk-fb { margin: 0; font-size: 14.5px; line-height: 1.5; }
.nl-mk-flag { display: flex; gap: 8px; align-items: flex-start; }
.nl-mk-flag .ic { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 2px; }
.nl-skel { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.nl-skel i { display: block; height: 12px; border-radius: var(--r-pill); background: var(--track); }
.nl-skel i:nth-child(2) { width: 86%; }
.nl-skel i:nth-child(3) { width: 62%; }
@media (prefers-reduced-motion: no-preference) {
  .nl-skel i { animation: pk-blink var(--motion-blink) ease-in-out infinite alternate; }
}

/* ─ Schrijven (N9) ─ */
.nl-wr { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 24px; align-items: start; }
@media (min-width: 901px) { .nl-wr > :first-child { position: sticky; top: 16px; } }
@media (max-width: 900px) { .nl-wr { grid-template-columns: minmax(0, 1fr); gap: 16px; } }
.nl-wtask .kicker { margin: 0; }
.nl-wsit { font-size: 16px; font-weight: 700; }
.nl-denk { margin-top: 10px; }
.nl-points { margin: 10px 0 0; padding-inline-start: 20px; display: flex; flex-direction: column; gap: 6px; font-size: 15.5px; line-height: 1.5; font-weight: 700; }
.nl-points.hints { list-style: none; padding: 0; }
.nl-points.hints li { position: relative; padding-inline-start: 18px; }
.nl-points.hints li::before { content: ''; position: absolute; inset-inline-start: 2px; top: .6em; width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--pass); }
.nl-winstr { margin-top: 12px; display: flex; flex-direction: column; gap: 2px; font-family: var(--font-display); font-weight: 800; font-size: 14.5px; color: var(--ink-secondary); }
.nl-paper { background: var(--paper-card); border: 1.5px solid var(--line-strong); border-radius: var(--r-input); overflow: hidden; }
.nl-paper-row { display: grid; grid-template-columns: 110px minmax(0, 1fr); align-items: center; gap: 12px; padding: 12px 18px; border-bottom: 1px solid var(--line); font-size: 15px; }
.nl-paper-row span:first-child { font-family: var(--font-display); font-weight: 800; color: var(--ink-secondary); }
.nl-paper-row span + span { font-weight: 700; overflow-wrap: anywhere; }
.nl-print { margin: 0; padding: 14px 18px 0; font-size: 16px; font-weight: 700; color: var(--ink-warm); }
.nl-print.end { padding: 0 18px; }
.nl-print.last { padding: 4px 18px 18px; }
.nl-write {
  display: block; width: calc(100% - 20px); margin: 8px 10px; min-height: 200px; padding: 10px 8px; resize: vertical;
  border: 0; border-radius: var(--r-input-sm); background: var(--paper-card); outline: 1.5px dashed var(--line-strong); outline-offset: 0;
  font: inherit; font-size: 16px; font-weight: 600; line-height: 1.65; color: var(--ink);
}
.nl-write.tall { min-height: 260px; }
.nl-write:focus, .nl-write:not(:placeholder-shown) { outline: 2px solid var(--accent); }
.nl-write:not(:focus):not(:placeholder-shown) { outline: 1.5px solid var(--line-strong); }
.nl-write::placeholder { color: var(--ink-tertiary); }
.nl-wfoot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; flex-wrap: wrap; }
.nl-wcount { font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.nl-wfoot .btn-dark:disabled { opacity: .45; cursor: default; }
.nl-form { padding: 18px 18px 22px; }
.nl-form h3 { font-family: var(--font-display); font-weight: 800; font-size: 18px; margin: 0 0 12px; }
.nl-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
.nl-fields label { display: flex; flex-direction: column; gap: 5px; font-family: var(--font-display); font-weight: 800; font-size: 13.5px; color: var(--ink-secondary); min-width: 0; }
.nl-fields input { min-height: 46px; padding: 0 12px; border-radius: var(--r-input-sm); border: 1.5px solid var(--line-strong); background: var(--paper-card); font: inherit; font-family: var(--font-body); font-weight: 700; font-size: 16px; color: var(--ink); min-width: 0; }
.nl-fields input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
.nl-fields .wide { grid-column: 1 / -1; }
.nl-choice { margin-top: 18px; }
.nl-choice p { margin: 0 0 6px; font-weight: 800; font-size: 15.5px; }
.nl-choice-o { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 0 4px; border: 0; background: none; cursor: pointer; text-align: start; font: inherit; font-size: 16px; font-weight: 700; color: var(--ink); }
.nl-cross { width: 26px; height: 26px; border-radius: var(--nl-r-box); border: 2px solid var(--ink-secondary); background: var(--paper-card); display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; color: var(--ink); }
.nl-cross .ic { width: 18px; height: 18px; stroke-width: 3; }
.nl-cross.sm { width: 20px; height: 20px; border-width: 1.5px; border-radius: calc(var(--nl-r-box) / 2); }
.nl-cross.sm .ic { width: 14px; height: 14px; }
.nl-open { margin-top: 18px; display: flex; flex-direction: column; gap: 14px; }
.nl-open label { display: flex; flex-direction: column; gap: 6px; font-weight: 800; font-size: 15.5px; }
.nl-open textarea { min-height: 72px; padding: 10px 12px; border-radius: var(--r-input-sm); border: 1.5px solid var(--line-strong); background: var(--paper-card); font: inherit; font-weight: 700; font-size: 16px; line-height: 1.5; color: var(--ink); resize: vertical; }
.nl-open textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
.nl-mineform { padding: 12px 14px; border-radius: var(--r-input); background: var(--paper-warm); }
@media (max-width: 560px) {
  .nl-fields { grid-template-columns: minmax(0, 1fr); }
  .nl-paper-row { grid-template-columns: 92px minmax(0, 1fr); padding: 12px 14px; }
  .nl-wfoot .nl-row { width: 100%; }
  .nl-wfoot .nl-row .btn { flex: 1 1 auto; justify-content: center; }
}

/* ─ Part result (N10·spreken, schrijven) ─ */
.nl-whatnext .kicker { margin: 0; }
.nl-count3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.nl-count3 div { padding: 12px; border-radius: var(--r-input); background: var(--paper-card); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 2px; }
.nl-count3 b { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 1; }
.nl-count3 span { font-size: 12.5px; color: var(--ink-secondary); }
.nl-count3 .s1 b { color: var(--fail-ink); }
.nl-count3 .s3 b { color: var(--pass-text); }
.nl-prow-h .nl-dots { margin-inline-start: auto; }
.nl-dots i.s0 { background: var(--track); box-shadow: inset 0 0 0 1.5px var(--line-strong); }

/* ─── Dutch players — MC (design/handoff-v4-nl N4–N7, N10, N11; web/ui/nl/) ───
   The DUO question frame, the reading split, the players, picture options and
   the part result. The bar, the players and the photo frames serve every Dutch
   task screen and are declared once, with the speaking and writing block
   above (the same rules, the same custom properties --nl-bar-h, --nl-r-box,
   --nl-r-photo, --nl-photo-ratio); what follows adds what the multiple-choice
   parts need and scopes what differs. ─────────── */
:root {
}
.nl-stage { padding-bottom: calc(var(--nl-bar-h) + 56px); }
.nl-mode { background: var(--pass-bg); color: var(--pass-text); border: 0; box-shadow: none; }
.nl-mode.exam { background: var(--ink); color: var(--paper-card); }
@media (min-width: 901px) { .prova-head .nl-mode { order: 3; } }
@media (max-width: 560px) { .prova-head .nl-mode { display: none; } }
.ph-clock .ic { width: 14px; height: 14px; }
.prova-head .ph-clock.warm { background: var(--accent-ink); border-color: var(--accent-ink); color: var(--paper-card); }

/* The bar: Previous · bookmark · counter (opens the overview) · Next, fixed to
   the bottom on every width, as on DUO's screen and in thumb reach (N11). */
.nl-bar {
  position: fixed; z-index: 40; inset-inline: 0; bottom: 18px; margin-inline: auto;
  width: min(var(--web-max), calc(100% - 48px)); min-height: var(--nl-bar-h);
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 12px;
  padding: 8px; border-radius: var(--r-pill);
  background: var(--glass-light); -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
  border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow), var(--shadow-card);
}
.nl-bar .btn { min-height: 48px; }
.nl-bar .nl-prev { justify-self: start; }
.nl-bar .nl-next { justify-self: end; min-width: 180px; justify-content: center; }
.nl-bar .btn .ic { width: 18px; height: 18px; }
.nl-mid { display: flex; align-items: center; gap: 6px; }
.nl-count {
  display: inline-flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 18px; border-radius: var(--r-pill); cursor: pointer;
  border: 1.5px solid var(--line-strong); background: var(--paper-card); color: var(--ink);
  font-family: var(--font-display); font-weight: 800; font-size: 17px; font-variant-numeric: tabular-nums;
}
.nl-count small { color: var(--ink-secondary); font-size: 15px; }
.nl-count .ic { width: 18px; height: 18px; color: var(--ink-secondary); }
.nl-count[aria-expanded="true"] { background: var(--ink); color: var(--paper-card); border-color: var(--ink); }
.nl-count[aria-expanded="true"] small, .nl-count[aria-expanded="true"] .ic { color: var(--tint-on-dark); }
.nl-flag {
  width: 48px; height: 48px; border-radius: var(--r-pill); border: 1.5px solid var(--line-strong); background: var(--paper-card);
  display: inline-flex; align-items: center; justify-content: center; color: var(--ink-secondary); cursor: pointer;
}
.nl-flag .ic { width: 20px; height: 20px; }
.nl-flag[aria-pressed="true"] { background: var(--warm-bg); border-color: var(--accent); color: var(--accent-ink); }
.nl-flag[aria-pressed="true"] .ic path { fill: currentColor; }
@media (max-width: 560px) {
  .nl-bar { width: calc(100% - 24px); bottom: max(12px, calc(env(safe-area-inset-bottom) + 4px)); gap: 6px; padding: 6px;
    grid-template-columns: auto auto minmax(0, 1fr); }
  .nl-bar .nl-prev { width: 52px; min-width: 52px; padding: 0; justify-content: center; }
  .nl-bar .nl-prev span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .nl-bar .nl-next { min-width: 0; width: 100%; }
  .nl-count { padding: 0 12px; font-size: 16px; }
  .nl-count .ic { display: none; }
  .nl-flag { width: 44px; height: 44px; }
}

/* Overview: the grid of numbers in four states; a panel over the bar on a wide
   screen, a sheet from the bottom on a phone. */
.nl-ov-scrim { position: fixed; inset: 0; z-index: 38; background: var(--tint-scrim); }
.nl-ov {
  position: fixed; z-index: 39; bottom: calc(var(--nl-bar-h) + 34px); inset-inline: 0; margin-inline: auto;
  width: min(560px, calc(100% - 48px)); max-height: calc(100vh - var(--nl-bar-h) - 60px); overflow: auto; padding: 20px;
  border-radius: var(--r-card); background: var(--paper-card);
  border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow), var(--shadow-card);
}
.nl-ov h2 { font-family: var(--font-display); font-weight: 800; font-size: 20px; margin: 0; }
.nl-ov .all-grid.mc { grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 6px; }
.nl-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 14px; font-size: 13px; color: var(--ink-secondary); }
.nl-legend span { display: inline-flex; align-items: center; gap: 7px; }
.nl-legend i { width: 18px; height: 18px; border-radius: var(--nl-r-box); border: 1.5px solid var(--line-strong); background: var(--paper-card); display: inline-block; position: relative; overflow: hidden; }
.nl-legend i.done { background: var(--ink); border-color: var(--ink); }
.nl-legend i.right { background: var(--pass-bg); border-color: var(--pass); }
.nl-legend i.wrong { background: var(--fail-bg); border-color: var(--fail); }
.nl-legend i.cur { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-legend i.flag::after { content: ''; position: absolute; inset-block-start: 0; inset-inline-end: 0; width: 9px; height: 9px; background: linear-gradient(225deg, var(--accent) 50%, transparent 50%); }
.nl-ov-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.nl-ov-foot .note-sm { margin: 0; }
@media (max-width: 560px) {
  .nl-ov { bottom: 0; width: 100%; max-height: 88vh; border-end-start-radius: 0; border-end-end-radius: 0;
    padding: 12px 16px calc(var(--nl-bar-h) + 40px); }
  .nl-ov::before { content: ''; display: block; width: 40px; height: 5px; border-radius: var(--r-pill); background: var(--line-strong); margin: 0 auto 12px; }
  .nl-ov .all-grid.mc { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
  .nl-ov-foot { flex-direction: column; align-items: stretch; }
}

/* The question: its number, situation lines, the stem, its player, options. */
.nl-q { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.nl-q .opts, .nl-q .nl-popts { margin-top: 0; }
.nl-qnum { margin: 0; }
.nl-sit { margin: 0; font-size: 16px; line-height: 1.55; color: var(--ink-warm); }
.nl-sit span { display: block; }
.nl-qline { display: flex; align-items: flex-start; gap: 12px; }
.nl-qline .q-stem { margin: 0; flex: 1; }
/* DUO underlines the one word to notice (`**niet**`): thick, in accent. */
.nl-em { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
/* An option with its own player: side by side on a wide screen; on a phone the
   play button sits inside the option's box, so the text keeps its width (N11). */
.nl-optrow { display: flex; align-items: center; gap: 10px; position: relative; }
.nl-optrow > .opt { flex: 1; min-width: 0; }
.opt-tag { font-family: var(--font-display); font-weight: 800; font-size: 12px; flex: 0 0 auto; }
.opt.right .opt-tag { color: var(--pass-text); }
.opt.wrong .opt-tag { color: var(--fail-ink); }
@media (max-width: 560px) {
  .nl-optrow > .opt { padding-inline-end: 62px; }
  /* Centred by auto margins, not a transform: the entrance motion animates transform. */
  .nl-optrow > .nl-mini { position: absolute; inset-inline-end: 8px; inset-block: 0; margin-block: auto; }
}
/* Picture options: A–D, each one to three photos in equal frames. */
.nl-popts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.nl-popts.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.opt.pic { flex-direction: column; align-items: stretch; gap: 10px; padding: 10px; }
.opt.pic .nl-ph { display: flex; align-items: center; gap: 10px; padding: 2px 4px; }
.opt.pic .nl-ph .opt-key { width: auto; font-size: 15px; }
.opt.pic .nl-ph .opt-radio, .opt.pic .nl-ph .opt-tag { margin-inline-start: auto; }
.nl-popts.one { grid-template-columns: minmax(0, 1fr); gap: 10px; }
.nl-popts.one .opt.pic { flex-direction: row; align-items: center; gap: 14px; padding-inline-start: 14px; }
.nl-popts.one .opt.pic .nl-ph { flex-direction: column; gap: 10px; padding: 0; }
.nl-popts.one .opt.pic .nl-ph .opt-radio, .nl-popts.one .opt.pic .nl-ph .opt-tag { margin: 0; }
.nl-popts.one .opt.pic .nl-pics { flex: 1; grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Square frames on a three-slot grid, so the photos line up across the rows (N8·s6). */
.nl-popts.one .nl-pics img { aspect-ratio: 1; }
@media (max-width: 560px) {
  .nl-popts, .nl-popts.n3 { grid-template-columns: minmax(0, 1fr); }
  .nl-popts.n3 .opt.pic { flex-direction: row; align-items: center; }
  .nl-popts.n3 .opt.pic .nl-pics { width: 132px; flex: 0 0 auto; }
  .nl-popts.n3 .opt.pic .nl-ph { flex: 1; }
}
.nl-pics { display: grid; grid-template-columns: repeat(var(--n, 1), minmax(0, 1fr)); gap: 8px; }
.nl-pics figure { margin: 0; position: relative; }
.nl-pics img { display: block; width: 100%; aspect-ratio: var(--nl-photo-ratio); object-fit: cover; border-radius: var(--nl-r-photo); background: var(--track); }
.nl-pics.tight { gap: 4px; }
.nl-pics.tight img { border-radius: var(--nl-r-box); }
.nl-photo { margin: 0; }
.nl-photo-btn { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; border-radius: var(--r-card-md); }
.nl-photo img { display: block; width: 100%; aspect-ratio: var(--nl-photo-ratio); object-fit: cover; border-radius: var(--r-card-md); background: var(--track); }

/* Practice feedback: the verdict and the explanation (dir="auto", so an
   explanation in Arabic or Urdu mirrors). */
.nl-why { padding: 18px 20px; }
/* The verdict takes focus after a choice (frame.js) for screen readers; the
   shared :focus-visible rule draws a ring only when the keyboard put it there. */
.nl-why:focus:not(:focus-visible) { outline: none; }
.nl-why .why { font-size: 15.5px; line-height: 1.6; margin: 8px 0 0; }
.nl-why .kicker { margin-bottom: 0; }
.nl-verdict { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 800; font-size: 20px; }
.nl-verdict .ic { width: 22px; height: 22px; padding: 4px; border-radius: var(--r-pill); box-sizing: content-box; }
.nl-verdict.no .ic { background: var(--fail-bg); color: var(--fail-ink); }
.nl-verdict.ok .ic { background: var(--pass-bg); color: var(--pass-text); }

/* Reading (N5): the split, the framed text, the phone switch and peek. */
.nl-split { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 28px; align-items: start; }
/* The question column stays in view while the text scrolls with the page (N8·w1). */
@media (min-width: 901px) { .nl-split > .nl-q { position: sticky; top: 16px; } }
.nl-read { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.nl-intro { margin: 0; font-size: 16.5px; line-height: 1.5; font-weight: 700; }
/* DUO's instruction, one quiet line above the part's first text (decision 42). */
.nl-instr { margin: 0; font-size: 13.5px; line-height: 1.45; font-weight: 700; color: var(--ink-secondary); }
.nl-read .nl-rule, .nl-frag .nl-rule { border: 0; border-top: 1.5px solid var(--line-strong); margin: 2px 0 0; width: 100%; }
.nl-text {
  background: var(--paper-card); border: 1.5px solid var(--line-strong); border-radius: var(--r-input);
  padding: 22px 24px;
  font-size: 16px; line-height: 1.6; color: var(--ink); box-shadow: inset 0 -12px 16px -16px var(--tint-toast-shadow);
}
.nl-text > * { margin: 0; }
.nl-text > * + * { margin-top: 8px; }
.nl-text h3 { font-family: var(--font-display); font-weight: 800; font-size: 21px; line-height: 1.25; }
.nl-text > h3 + * { margin-top: 12px; }
/* A bold-only line is a subheading in the bank's letters: space above it. */
.nl-text > p:has(> b:only-child) { margin-top: 16px; }
.nl-text b { font-weight: 800; }
.nl-text ul { margin: 6px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 5px; }
.nl-text li { position: relative; padding-inline-start: 18px; }
.nl-text li::before { content: ''; position: absolute; inset-inline-start: 3px; top: .66em; width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--ink); }
/* A table flows with the text; wider than its frame, it scrolls sideways inside
   it with the first column held, a fade at the edge and one line under it. */
.nl-tbl { position: relative; margin-top: 10px; }
.nl-tablewrap { overflow-x: auto; }
.nl-text .nl-tablewrap th[scope="row"], .nl-text .nl-tablewrap thead th:first-child { position: sticky; inset-inline-start: 0; z-index: 1;
  box-shadow: inset -1px 0 0 var(--line-strong); }
.nl-text .nl-tablewrap th[scope="row"] { background: var(--paper-card); font-family: var(--font-body); font-weight: 700; font-size: inherit; }
.nl-tbl.scrolls .nl-tablewrap::after { content: ""; position: absolute; inset-block: 0; inset-inline-end: 0; width: 28px; pointer-events: none;
  background: linear-gradient(to left, var(--paper-card), transparent); }
.nl-tbl-hint { display: none; align-items: center; gap: 6px; margin: 6px 0 0; font-size: 12.5px; font-weight: 700; color: var(--ink-secondary); }
.nl-tbl-hint .ic { width: 14px; height: 14px; }
.nl-tbl.scrolls .nl-tbl-hint { display: flex; }
.nl-text table { width: 100%; border-collapse: collapse; font-size: 15px; }
.nl-text th, .nl-text td { text-align: start; padding: 8px 10px; border: 1px solid var(--line-strong); vertical-align: top; }
.nl-text th { background: var(--paper-warm); font-family: var(--font-display); font-weight: 800; font-size: 14.5px; }
.nl-mailhead { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 2px 12px; padding-bottom: 12px; border-bottom: 1px solid var(--line-strong); }
.nl-mailhead dt { font-weight: 700; color: var(--ink-secondary); font-size: 14px; }
.nl-mailhead dd { margin: 0; }
.nl-switch, .nl-peek { display: none; }
@media (max-width: 900px) {
  .nl-split { grid-template-columns: minmax(0, 1fr); }
  .nl-text { max-height: none; }
}
@media (max-width: 560px) {
  .nl-switch {
    display: flex; gap: 4px; position: sticky; top: 8px; z-index: 30; margin: 0 0 6px; padding: 4px; border-radius: var(--r-pill);
    background: var(--glass-light); -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
    border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow);
  }
  .nl-switch button {
    flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--a11y-tap-target-min);
    border: 0; border-radius: var(--r-pill); background: none; color: var(--ink-warm); cursor: pointer;
    font-family: var(--font-display); font-weight: 800; font-size: 15px;
  }
  .nl-switch button[aria-selected="true"] { background: var(--ink); color: var(--paper-card); }
  .nl-switch button .ic { width: 16px; height: 16px; }
  .nl-switch .badge { font-style: normal; min-width: 22px; height: 22px; padding: 0 6px; border-radius: var(--r-pill); background: var(--accent); color: var(--paper-card); font-size: 12px; display: inline-flex; align-items: center; justify-content: center; }
  [data-pane="text"] > .nl-q { display: none; }
  [data-pane="q"] > .nl-read { display: none; }
  .nl-text { padding: 16px 14px; }
  .nl-text table { font-size: 13.5px; }
  .nl-text th, .nl-text td { padding: 7px 6px; }
  [data-pane="text"] > .nl-peek {
    display: flex; align-items: center; gap: 12px; position: fixed; z-index: 39;
    inset-inline: 12px; bottom: calc(var(--nl-bar-h) + 30px); padding: 12px 14px; border-radius: var(--r-card-md);
    background: linear-gradient(170deg, var(--panel-from), var(--panel-to)); color: var(--paper-card);
    border: 1px solid var(--glass-dark-border); box-shadow: var(--shadow-panel); text-align: start; cursor: pointer; font: inherit;
  }
  [data-pane="text"] { padding-bottom: 76px; }
  .nl-peek-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .nl-peek-t small { font-family: var(--font-display); font-weight: 800; font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--panel-accent); }
  .nl-peek-t b { font-family: var(--font-display); font-weight: 800; font-size: 15px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .nl-peek .ic { width: 18px; height: 18px; flex: 0 0 auto; }
}

/* Players (N6, N7, N8): play/pause, back and forward, again, a track to seek.
   `.dark` is the fragment's, `.row` the question's compact one. */
.nl-player { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 12px 16px; padding: 16px 18px; border-radius: var(--r-card-md); }
.nl-player:not(.row) .nl-pp { width: 56px; height: 56px; }
.nl-player:not(.row) .nl-pp .ic { width: 24px; height: 24px; }
.nl-pl-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.nl-pl-top b { font-family: var(--font-display); font-weight: 800; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nl-pl-top span { font-size: 13px; color: var(--ink-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A track the person can seek on (role slider): a thin bar inside a taller
   target; --p is the position. */
.nl-track[role="slider"] { height: 16px; cursor: pointer; background: none; }
.nl-track[role="slider"]::before { content: ''; position: absolute; inset-inline: 0; top: 5px; height: 6px; border-radius: var(--r-pill); background: var(--track); }
.nl-track[role="slider"] i { top: 5px; bottom: auto; height: 6px; width: var(--p, 0%); }
.nl-track[role="slider"] b { top: 0; inset-inline-start: var(--p, 0%); transform: none; }
.nl-track[role="slider"]:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.nl-player.dark { background: var(--glass-dark); border: 1px solid var(--glass-dark-border); box-shadow: var(--glass-dark-shadow); color: var(--paper-card); }
.nl-player.dark .nl-pp { background: var(--paper-card); color: var(--ink); width: 64px; height: 64px; }
.nl-player.dark .nl-pl-top span { color: var(--tint-on-dark); }
.nl-player.dark .nl-track[role="slider"]::before { background: var(--panel-ring); }
.nl-player.dark .nl-track i { background: var(--teal-glow); }
.nl-player.dark .nl-track b { box-shadow: 0 0 0 2px var(--teal-glow); }
.nl-player.playing .nl-pp { background: var(--accent); color: var(--paper-card); }
.nl-player.row {
  grid-template-columns: auto minmax(0, 1fr); padding: 8px 10px 8px 8px; gap: 10px; border-radius: var(--r-card-md);
  background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow);
}
.nl-player.row .nl-pp { width: 44px; height: 44px; }
.nl-player.row .nl-pp .ic { width: 18px; height: 18px; }
/* On the recorder's dark dock: no card of its own, a white play disc. */
.nl-player.row.dark { flex: 1; min-width: 0; padding: 0; background: none; border: 0; box-shadow: none; color: var(--paper-card); }
.nl-player.row.dark .nl-pp { width: 48px; height: 48px; background: var(--paper-card); color: var(--ink); box-shadow: var(--shadow-card-sm); }
.nl-player.row.dark.playing .nl-pp { background: var(--accent); color: var(--paper-card); }
/* An option's own play button, with a ring for progress. */
/* The block header: which questions, this block's volume, the noisy room. */
.nl-bhead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.nl-bhead .kicker { margin: 0; }
.nl-vol { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 14px; border-radius: var(--r-pill); background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow); }
.nl-vol .ic { width: 18px; height: 18px; color: var(--ink-secondary); flex: 0 0 auto; }
.nl-range { -webkit-appearance: none; appearance: none; width: 110px; height: 44px; margin: 0; background: none; cursor: pointer; }
.nl-range::-webkit-slider-runnable-track { height: 6px; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--ink) var(--p, 80%), var(--track) var(--p, 80%)); }
.nl-range::-moz-range-track { height: 6px; border-radius: var(--r-pill); background: var(--track); }
.nl-range::-moz-range-progress { height: 6px; border-radius: var(--r-pill); background: var(--ink); }
.nl-range::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -7px; border-radius: var(--r-pill); background: var(--paper-card); box-shadow: 0 0 0 2px var(--ink), var(--shadow-card-sm); }
.nl-range::-moz-range-thumb { width: 18px; height: 18px; border: 0; border-radius: var(--r-pill); background: var(--paper-card); box-shadow: 0 0 0 2px var(--ink); }
.nl-range:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
[dir="rtl"] .nl-range::-webkit-slider-runnable-track { background: linear-gradient(270deg, var(--ink) var(--p, 80%), var(--track) var(--p, 80%)); }
.nl-noise { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding-block: 0; padding-inline: 14px 6px; border-radius: var(--r-pill); background: var(--glass-pill); border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow); font-family: var(--font-display); font-weight: 800; font-size: 13.5px; }
.nl-noise .ic { width: 18px; height: 18px; color: var(--ink-secondary); }
.nl-noise.on .ic { color: var(--pass-text); }
.nl-frag .nl-scene { justify-content: flex-start; flex-wrap: nowrap; gap: 10px; }
/* The fragment card (dark glass): situation, scene note, guided rail, players. */
.nl-frag { padding: 22px; display: flex; flex-direction: column; gap: 14px; }
.nl-frag .kicker { color: var(--panel-kicker); margin: 0; }
.nl-frag .nl-intro { color: var(--paper-card); font-size: 18px; }
.nl-frag .nl-player { padding: 0; background: none; border: 0; box-shadow: none; }
.nl-frag .nl-player.row { background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); box-shadow: none; padding: 8px 10px 8px 8px; }
.nl-frag .nl-player.row .nl-pp { background: var(--paper-card); color: var(--ink); }
.nl-frag .nl-player.row.playing .nl-pp { background: var(--accent); color: var(--paper-card); }
.nl-frag .nl-player.row .nl-sk, .nl-frag .nl-player.row .nl-pl-top span { color: var(--tint-on-dark); }
.nl-frag .nl-player .nl-pl-top b { color: var(--paper-card); }
.nl-frag .nl-player.row .nl-track[role="slider"]::before { background: var(--panel-ring); }
.nl-frag .nl-player.row .nl-track i { background: var(--teal-glow); }
.nl-frag .nl-player.row .nl-track b { box-shadow: 0 0 0 2px var(--teal-glow); }
.nl-frag .nl-rule { border-color: var(--tint-on-dark-line); }
.nl-frag .row-between { gap: 12px; }
.nl-gbtn { background: var(--tint-on-dark-fill); color: var(--paper-card); border: 1px solid var(--tint-on-dark-line); box-shadow: none; gap: 6px; }
.nl-gbtn .ic { width: 14px; height: 14px; }
.nl-frag .row-between > .kicker { flex: 1 1 auto; min-width: 0; }
.nl-frag .row-between > .nl-gbtn { flex: 0 0 auto; width: auto; min-height: var(--a11y-tap-target-min); padding-inline: 16px; font-size: 14px; }
.nl-guide { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.nl-guide li { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--tint-on-dark); padding: 6px 10px; border-radius: var(--r-pill); border: 1px solid var(--tint-on-dark-line); }
.nl-guide li.done { color: var(--teal-glow); border-color: transparent; }
.nl-guide li.done .ic { width: 13px; height: 13px; }
.nl-guide li.now { background: var(--paper-card); color: var(--ink); border-color: var(--paper-card); }
.nl-guide li.sep { color: var(--tint-on-dark); font-size: 12px; padding: 0; border: 0; }
@media (max-width: 560px) {
  .nl-bhead { gap: 8px; margin-bottom: 14px; }
  .nl-bhead .nl-gap { display: none; }
  .nl-bhead .kicker { flex: 1 1 100%; }
  /* One row on a phone: the volume takes the width the noisy room leaves. */
  .nl-vol { flex: 1 1 0; min-width: 0; padding: 0 10px; gap: 6px; }
  .nl-vol .ic:last-child { display: none; }
  .nl-noise { flex: 0 0 auto; padding-inline: 10px 4px; gap: 6px; }
  .nl-range { flex: 1; width: auto; min-width: 72px; }
}
@media (min-width: 561px) { .nl-bhead .nl-vol { margin-inline-start: auto; } .nl-bhead .nl-gap { display: none; } }

/* KNM (N7): the photo beside the question on a wide screen, above it on a phone. */
.nl-knm { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; align-items: start; }
@media (min-width: 901px) {
  .nl-split.lu { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
  .nl-knm.pics { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
}
@media (max-width: 900px) { .nl-knm { grid-template-columns: minmax(0, 1fr); gap: 16px; } .nl-split { gap: 18px; } }

/* The part result (N10): chance band, the questions and their answers. */
.nl-band-bar.knm > span { flex: var(--n) 1 0; }
.nl-qlist { display: flex; flex-direction: column; }
.nl-qrow { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto 20px; align-items: center; gap: 12px; min-height: 52px; padding: 8px 0; color: inherit; text-decoration: none; }
.nl-qrow + .nl-qrow { border-top: 1px solid var(--line); }
.nl-qrow > i { width: 30px; height: 30px; border-radius: var(--r-pill); display: flex; align-items: center; justify-content: center; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 13px; }
.nl-qrow.ok > i { background: var(--pass-bg); color: var(--pass-text); }
.nl-qrow.no > i { background: var(--fail-bg); color: var(--fail-ink); }
.nl-qrow.skip > i { background: var(--track); color: var(--ink-secondary); }
.nl-qrow-t { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.nl-qrow-t b { font-weight: 700; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nl-qrow-t small { font-size: 12.5px; color: var(--ink-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nl-qrow .opt-tag { font-size: 12.5px; }
.nl-qrow.ok .opt-tag { color: var(--pass-text); }
.nl-qrow.no .opt-tag, .nl-qrow.skip .opt-tag { color: var(--fail-ink); }
.nl-qrow .ic { width: 16px; height: 16px; color: var(--ink-secondary); }
.nl-filter { margin: 0; max-width: none; }
.nl-filter button {
  flex: 1; min-height: var(--a11y-tap-target-min); padding: 0 14px; border: 0; border-radius: 12px; background: none; cursor: pointer; white-space: nowrap;
  font-family: var(--font-display); font-weight: 800; font-size: 14.5px; color: var(--ink-warm);
}
.nl-filter button[aria-pressed="true"] { background: var(--ink); color: var(--paper-card); }
.nl-filter button:disabled { opacity: .5; cursor: default; }
.nl-whatnext { display: flex; flex-direction: column; gap: 12px; }
.nl-whatnext .tb-text { margin: 0; }
.nl-whatnext .link-quiet { align-self: center; }
.nl-result .row-between { gap: 12px; flex-wrap: wrap; }

/* ---- Listening lane (design v5 N6, LISTENING.md; kit.js cueDot, lane, fragSlab, transport) ----
   Every file of a block is a cue dot on one vertical line, and one dark transport drives
   the file the cursor is on. The line between two heard dots turns teal. */
.lane { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.lane-i { --dy: 0px; position: relative; display: grid; grid-template-columns: var(--sp-lane) minmax(0, 1fr); column-gap: 4px; }
.lane-i::before, .lane-i::after { content: ""; position: absolute; left: calc(var(--sp-lane) / 2 - 1px); width: 2px; background: var(--line-strong); }
.lane-i::before { top: 0; height: calc(var(--dy) + 8px); }
.lane-i::after { top: calc(var(--dy) + 36px); bottom: 0; }
.lane-i.first::before, .lane-i.last::after { display: none; }
.lane-i.up-on::before, .lane-i.dn-on::after { background: var(--tint-lane-on); }
.lane-c { position: relative; }
.lane-c > .cue { position: absolute; left: 0; top: var(--dy); z-index: 1; }
.lane-b { min-width: 0; padding-bottom: 10px; }
.lane-k { display: flex; align-items: center; gap: 8px; min-height: var(--a11y-tap-target-min); }
.lane-k > span:first-child { font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-secondary); }
.lane-kt { font-size: 12.5px; color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.lane-q { margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 22px; letter-spacing: -.02em; line-height: 1.18; color: var(--ink); text-wrap: balance; }
.lane-sit { margin: 0; font-size: 15.5px; line-height: 1.45; font-weight: 600; color: var(--ink); }

.cue { width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min); padding: 0; border: 0; background: none;
  display: flex; align-items: center; justify-content: center; border-radius: var(--r-pill); cursor: pointer; }
.cue[aria-disabled="true"] { cursor: default; }
.cue-d { width: var(--sp-cue); height: var(--sp-cue); box-sizing: border-box; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--paper-card); border: 2px solid var(--ink-faint); color: var(--ink-tertiary); }
.cue-d .ic { width: 11px; height: 11px; }
.cue-next .cue-d { border-color: var(--pass-text); color: var(--pass-text); }
.cue-read .cue-d { border-color: var(--pass-text); color: var(--pass-text); box-shadow: 0 0 0 5px var(--tint-cue-halo-read); }
.cue-play .cue-d { background: var(--ink); border-color: var(--ink); color: var(--paper-card); box-shadow: 0 0 0 5px var(--tint-cue-halo); }
.cue-paused .cue-d { background: var(--ink); border-color: var(--ink); color: var(--paper-card); box-shadow: 0 0 0 5px var(--tint-cue-halo-soft); }
.cue-heard .cue-d { background: var(--pass-bg); border: 1.5px solid var(--tint-cue-heard-rim); color: var(--pass-text); }
.cue-heard .cue-d .ic, .cue-fail .cue-d .ic { width: 13px; height: 13px; }
.cue-load .cue-d { background: var(--glass-nav); border: 2px dashed var(--ink-faint); color: var(--ink-faint); }
.cue-load .cue-d .ic { width: 14px; height: 14px; }
.cue-fail .cue-d { background: var(--fail-bg); border: 1.5px solid var(--fail-border); color: var(--fail-ink); }

/* The playing bars: three, each on its own period, standing still with reduced motion. */
.cue-eq { display: flex; gap: 2.5px; align-items: flex-end; height: 13px; }
.cue-eq i { display: block; width: 3px; border-radius: var(--r-pill); background: currentColor; transform-origin: bottom; }
.cue-eq i:nth-child(1) { height: 9px; }
.cue-eq i:nth-child(2) { height: 13px; }
.cue-eq i:nth-child(3) { height: 7px; }
@media (prefers-reduced-motion: no-preference) {
  .cue-eq i { animation: nl-speak var(--motion-eq) ease-in-out infinite alternate; }
  .cue-eq i:nth-child(2) { animation-duration: var(--motion-eq-fast); animation-delay: .12s; }
  .cue-eq i:nth-child(3) { animation-duration: var(--motion-eq-slow); animation-delay: .24s; }
}

.frag { background: var(--glass-pill); -webkit-backdrop-filter: var(--glass-pill-blur); backdrop-filter: var(--glass-pill-blur);
  border: 1px solid var(--glass-pill-border); box-shadow: var(--glass-pill-shadow); border-radius: var(--r-field); padding: 11px 14px; }
.frag.on { box-shadow: 0 0 0 2px var(--ink), var(--shadow-card-sm); }
.frag-h { display: flex; align-items: center; gap: 8px; min-height: 22px; }
.frag-h b { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink); }
.frag-t { font-size: 12.5px; color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.frag-sp { flex: 1; }
.frag-v { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 700; color: var(--pass-text); text-align: end; }
.frag-v .ic { width: 15px; height: 15px; flex: 0 0 auto; }
.frag-bar { display: block; height: 4px; margin-top: 9px; border-radius: var(--r-pill); background: var(--track); overflow: hidden; }
.frag-bar i { display: block; height: 100%; width: var(--p); border-radius: var(--r-pill); background: var(--pass); }

/* The dark panel's own two colours, not see-through glass: the transport rides
   over the options while the page scrolls, and text must not show through it. */
.dock5 { background: linear-gradient(155deg, var(--panel-from), var(--panel-to));
  border: 1px solid var(--glass-dark-border); box-shadow: var(--glass-dark-shadow); border-radius: var(--r-dock);
  padding: 10px 10px 10px 16px; color: var(--paper-card); }
.tp5-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.tp5-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: var(--r-pill); white-space: nowrap;
  font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--panel-strong);
  background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); }
.tp5-chip .ic { width: 12px; height: 12px; }
.tp5-row { display: flex; align-items: center; gap: 6px; }
.tp5-line { margin: -2px 0 8px; font-size: 13px; line-height: 1.4; color: var(--panel-body); }
/* A 32 px pill inside a 44 px tap target, as on the phone. */
.tp5-go { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 5px; min-height: var(--a11y-tap-target-min); padding: 0 11px; border-radius: var(--r-pill); cursor: pointer;
  font-family: var(--font-display); font-weight: 800; font-size: 12.5px; color: var(--ink); background: transparent; border: 0; }
.tp5-go::before { content: ""; position: absolute; inset-inline: 0; inset-block: 6px; z-index: -1; border-radius: var(--r-pill); background: var(--paper-card); }
.tp5-go .ic { width: 13px; height: 13px; }
.tp5-chip.g { color: var(--teal-glow); }
.tp5-info { flex: 1; min-width: 0; }
.tp5-top { display: flex; align-items: baseline; gap: 6px; }
.tp5-k { font-family: var(--font-display); font-weight: 800; font-size: 11px; letter-spacing: .09em; text-transform: uppercase; color: var(--panel-kicker); white-space: nowrap; }
.tp5-k.k-play, .tp5-k.k-read { color: var(--teal-glow); }
.tp5-k.k-fail { color: var(--on-dark-no); }
.tp5-time { margin-inline-start: auto; font-size: 12px; color: var(--panel-sub); white-space: nowrap; font-variant-numeric: tabular-nums; }
.tp5-title { margin-top: 1px; font-family: var(--font-display); font-weight: 800; font-size: 15px; line-height: 1.25; color: var(--paper-card);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tp5-bar { display: flex; height: 3px; margin-top: 7px; border-radius: var(--r-pill); background: var(--panel-ring); overflow: hidden; }
.tp5-bar i { display: block; width: var(--p); border-radius: var(--r-pill); background: var(--teal-glow); }
.tp5-bar.read { justify-content: flex-end; }
.tp5-bar.fail i { background: var(--on-dark-no); }
.tp5-b { position: relative; width: var(--a11y-tap-target-min); height: var(--a11y-tap-target-min); flex: 0 0 auto; padding: 0;
  display: flex; align-items: center; justify-content: center; border-radius: var(--r-pill); cursor: pointer;
  background: var(--tint-on-dark-fill); border: 1px solid var(--tint-on-dark-line); color: var(--paper-card); }
.tp5-b .ic { width: 20px; height: 20px; }
.tp5-b:disabled { opacity: .38; cursor: default; }
.tp5-big { width: 54px; height: 54px; flex: 0 0 auto; padding: 0; border: 0; border-radius: var(--r-pill); cursor: pointer;
  display: flex; align-items: center; justify-content: center; background: var(--paper-card); color: var(--ink); box-shadow: var(--shadow-card-sm); }
.tp5-big .ic { width: 22px; height: 22px; }
.tp5-big:disabled { opacity: .38; cursor: default; }
.tp5-big.is-play { cursor: default; }
.kit-lane { max-width: 420px; }
.kit-docks { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 14px; align-items: start; }
.kit-docks .kit-cell { align-items: stretch; }

/* Luisteren and KNM on the lane (design v5 N6, lane.js). Phone: one column,
   the lane and under it the transport, held just above the question bar while
   the page scrolls. Web: two glass cards, Listen and Answer, the transport
   under Listen; the lane runs through both in play order. */
.nl-l5 { display: grid; grid-template-columns: minmax(0, 1fr); max-width: 640px; margin-inline: auto; }
.nl-l5-listen, .nl-l5-answer { min-width: 0; }
.nl-l5-k { display: none; }
.nl-l5-tp { position: sticky; bottom: calc(18px + var(--nl-bar-h) + 10px); z-index: 30; margin-top: 12px; }
.nl-l5 .nl-why { margin-top: 12px; }
.nl-l5 .lane .opt { width: 100%; }
.nl-l5 .lane .q-stem { margin: 0; }
.nl-l5 .lane .nl-sit { margin: 0 0 6px; }
.nl-l5.knm .nl-photo { margin-bottom: 14px; }
/* KNM's photo: a strip about 150 high (design v5 N10), so the question and its options are on the first screen. */
.nl-l5.knm .nl-photo img { aspect-ratio: auto; height: 150px; object-fit: cover; }
@media (min-width: 1000px) { .nl-l5.knm .nl-photo img { height: auto; aspect-ratio: var(--nl-photo-ratio); } }
.nl-l5.knm .nl-popts { margin-top: 4px; }
@media (min-width: 1000px) {
  .nl-l5 { max-width: none; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto 1fr; column-gap: 28px; align-items: start; }
  .nl-l5-listen, .nl-l5-answer { background: var(--glass-light); -webkit-backdrop-filter: var(--glass-light-blur); backdrop-filter: var(--glass-light-blur);
    border: 1px solid var(--glass-light-border); box-shadow: var(--glass-light-shadow); border-radius: var(--r-card); padding: 20px 22px 12px; }
  .nl-l5-k { display: block; margin: 0 0 4px; }
  .nl-l5-listen { grid-column: 1; grid-row: 1; }
  .nl-l5-answer { grid-column: 2; grid-row: 1 / span 2; }
  .nl-l5-tp { grid-column: 1; grid-row: 2; position: static; margin-top: 14px; }
  .nl-l5.knm:not(:has(.nl-l5-listen)) { grid-template-columns: minmax(0, 1fr); max-width: 760px; margin-inline: auto; }
  .nl-l5.knm:not(:has(.nl-l5-listen)) .nl-l5-answer, .nl-l5.knm:not(:has(.nl-l5-listen)) .nl-l5-tp { grid-column: 1; grid-row: auto; }
  .nl-l5.knm .nl-l5-listen { padding: 12px; }
  .nl-l5.knm .nl-photo { margin: 0; }
}

/* The sound sheet (design v5 N6): the block's volume and the noisy room, opened
   from the speaker in the task header; the speaker gets a teal ring while the
   noisy room is on. */
.nl-sndbtn.on > span { box-shadow: 0 0 0 2px var(--pass); }
.nl-snd { max-width: 440px; }
.nl-snd .nl-snd-vol { display: flex; width: 100%; box-sizing: border-box; margin-top: 8px; }
.nl-snd .nl-snd-vol .nl-range { flex: 1; width: auto; }
.nl-snd-row { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.nl-snd-t { flex: 1; min-width: 0; display: flex; gap: 10px; align-items: flex-start; }
.nl-snd-t .ic { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 2px; color: var(--pass-text); }
.nl-snd-t b { display: block; font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink); }
.nl-snd-t small { display: block; font-size: 13px; line-height: 1.4; color: var(--ink-secondary); }

/* The question frame of design v5 N7 (decision 41). One chosen-answer look for
   both exams: a white row with an ink rim and a filled ink radio, no check, no
   colour: before the verdict an answer is only "yours". */
.opt.on { background: var(--paper-card); border: 2px solid var(--ink); padding: 15px; color: var(--ink); box-shadow: var(--shadow-card-sm); }
.opt.on .opt-key { color: var(--ink); }
.opt.on .opt-radio { width: 22px; height: 22px; background: var(--ink); box-shadow: none; }
.opt.on .opt-radio svg { display: none; }
.opt.on .opt-radio::after { content: ""; width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--paper-card); }
.on-dark .opt.on { border-color: var(--paper-card); }
/* Dutch rows: an empty ring before a choice; after the verdict Correct, Your
   answer, the dashed Correct answer, and the rest dim. */
.nl-stage .opt .opt-radio { width: 22px; height: 22px; box-shadow: inset 0 0 0 2px var(--ink-faint); }
.nl-stage .opt.on .opt-radio { box-shadow: none; }
.nl-stage .opt.right .opt-radio { box-shadow: none; background: var(--pass-text); }
.nl-stage .opt.wrong .opt-radio { box-shadow: none; background: var(--fail-ink); }
.nl-stage .opt.right .opt-radio svg, .nl-stage .opt.wrong .opt-radio svg { display: none; }
.nl-stage .opt.right .opt-radio::after, .nl-stage .opt.wrong .opt-radio::after { content: ""; width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--paper-card); }
.nl-stage .opt.key { background: var(--pass-bg); border: 1.5px dashed var(--tint-key-rim); box-shadow: none; color: var(--ink); }
.nl-stage .opt.key .opt-key, .nl-stage .opt.key .opt-tag { color: var(--pass-text); }
.nl-stage .opt.dim { background: var(--tint-row-dim); border: 1px solid var(--line); box-shadow: none; color: var(--ink-secondary); }
.nl-stage .opt.dim .opt-radio { box-shadow: inset 0 0 0 2px var(--line); }
/* Next is ink; the one orange is Hand in on the last question. */
.nl-bar .nl-next.btn-dark { background: var(--ink); color: var(--paper-card); }
/* The Dutch overview's cells (N7·s4): answered warm with a dot, current an ink ring. */
.nl-ov .all-grid.nl5 button { min-height: 52px; border-radius: var(--r-input-sm); }
.nl-ov .all-grid.nl5 button.done { background: var(--lip); border-color: var(--cell-answered-rim); color: var(--ink); }
.nl-ov .all-grid.nl5 button.done::before { content: ""; position: absolute; inset-inline: 0; bottom: 7px; width: 5px; height: 5px; margin-inline: auto; border-radius: var(--r-pill); background: var(--ink-secondary); }
.nl-ov .all-grid.nl5 button.cur { border: 2px solid var(--ink); color: var(--ink); outline: none; }
.nl-ov .all-grid.nl5 button.cur.done { color: var(--ink); border-color: var(--ink); outline: none; }
/* KNM's theme screen (decision 42): DUO's quiet line before a theme's questions. */
.nl-theme { max-width: 640px; margin: 24px auto 0; padding: 32px 28px; text-align: center; display: flex; flex-direction: column; align-items: center; }
.nl-theme-h { margin: 8px 0 12px; }
/* Hand in with open questions: their numbers, each a jump. */
.nl-askchips { display: flex; flex-wrap: wrap; gap: 8px; }
.nl-askchip { min-width: var(--a11y-tap-target-min); min-height: var(--a11y-tap-target-min); padding: 0 12px; border-radius: var(--r-pill); cursor: pointer;
  font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink); background: var(--paper-card); border: 1px solid var(--line-strong); }
.nl-ov .nl-legend i.done { background: var(--lip); border-color: var(--cell-answered-rim); }
.nl-ov .nl-legend i.cur { outline: none; border: 2px solid var(--ink); }
.nl-askmore { align-self: center; font-size: 13.5px; color: var(--ink-secondary); }

/* ─ State changes that move (kit.js akScan, design decision 43) ─
   One animation when an element's state changes within a screen; the class
   goes when it ends. Reduced Motion: kit.js never sets it. */
@media (prefers-reduced-motion: no-preference) {
  .cue.ak .cue-d { animation: ak-pop var(--motion-slow) var(--motion-ease-enter); }
  .opt.ak { animation: ak-press var(--motion-slow) var(--motion-ease-enter); }
  .opt.ak .opt-tag, .opt.ak .opt-radio { animation: ak-pop var(--motion-slow) var(--motion-ease-enter); }
  .tp5-info.ak .tp5-k, .tp5-info.ak .tp5-title { animation: ak-slide var(--motion-slow) var(--motion-ease-enter) both; }
  .tp5-info.ak .tp5-title { animation-delay: var(--motion-stagger); }
  .tp5-big.ak, .nl-bar .nl-next.ak { animation: ak-pop var(--motion-slow) var(--motion-ease-enter); }
  .nl-why.ak { animation: ak-rise var(--motion-enter) var(--motion-ease-enter) both; }
  .nl-pt-stage.ak .nl-pt-face { animation: ak-breathe var(--motion-slow) var(--motion-ease-enter); }
  .nl-rd-row.ak { animation: ak-slide var(--motion-slow) var(--motion-ease-enter) both; }
  @keyframes ak-pop { 0% { transform: scale(.82); } 60% { transform: scale(1.08); } 100% { transform: none; } }
  @keyframes ak-press { 0% { transform: scale(var(--motion-press-scale-card)); } 100% { transform: none; } }
  @keyframes ak-slide { from { opacity: 0; transform: translateY(var(--motion-enter-shift)); } to { opacity: 1; transform: none; } }
  @keyframes ak-rise { from { opacity: 0; transform: translateY(var(--motion-enter-shift)) scale(.985); } to { opacity: 1; transform: none; } }
  @keyframes ak-breathe { 0% { transform: scale(1); } 45% { transform: scale(1.035); } 100% { transform: none; } }
}
@media (prefers-reduced-motion: no-preference) {
  .nl-zoomed { animation: pk-fade var(--motion-base) var(--motion-ease) both; }
  .nl-zoomed img { animation: ak-rise var(--motion-slow) var(--motion-ease-enter) both; }
}

/* Schrijven while typing on a phone (design v5 N12·s2): the task folds to its first
   line with a "Task" button (tapping it moves the focus off the field, so the task
   opens again), and the bottom bar steps aside for the keyboard. */
.nl-wtask-open { display: none; }
@media (max-width: 560px) {
  .nl-wr:has(.nl-compose :focus, .nl-form :focus) .nl-wtask-b { display: none; }
  .nl-wr:has(.nl-compose :focus, .nl-form :focus) .nl-wtask { padding-block: 12px; display: flex; align-items: center; gap: 10px; }
  .nl-wr:has(.nl-compose :focus, .nl-form :focus) .nl-wtask .kicker { flex: 1; min-width: 0; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .nl-wr:has(.nl-compose :focus, .nl-form :focus) .nl-wtask-open {
    display: inline-flex; align-items: center; gap: 6px; min-height: var(--a11y-tap-target-min); padding: 0 14px; border-radius: var(--r-pill);
    border: 1.5px solid var(--line-strong); background: var(--paper-card); color: var(--ink); cursor: pointer;
    font-family: var(--font-display); font-weight: 800; font-size: 14px; }
  .nl-wtask-open .ic { width: 16px; height: 16px; }
  main:has(.nl-wr :is(textarea, input):focus) ~ .nl-bar { transform: translateY(calc(100% + 40px)); }
}
@media (max-width: 560px) and (prefers-reduced-motion: no-preference) {
  .nl-bar { transition: transform var(--motion-base) var(--motion-ease); }
}

/* DUO's own sentence for the band, quoted in Dutch (N13·s1). */
.nl-duo { margin: 14px 0 0; padding-inline-start: 12px; border-inline-start: 3px solid var(--pass); }
.nl-duo p { margin: 0; font-size: 15.5px; line-height: 1.5; font-weight: 700; }
.nl-duo cite { display: block; margin-top: 4px; font-style: normal; font-size: 12.5px; color: var(--ink-secondary); }

/* Luisteren review: what was said (N14·s4), folded under the explanation. */
.nl-script { margin-top: 14px; padding: 6px 18px; }
.nl-script > summary { display: flex; align-items: center; gap: 10px; min-height: var(--a11y-tap-target-min); cursor: pointer; list-style: none;
  font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.nl-script > summary::-webkit-details-marker { display: none; }
.nl-script > summary span { flex: 1; }
.nl-script > summary .ic { width: 18px; height: 18px; color: var(--ink-secondary); }
.nl-script[open] > summary .ic:last-child { transform: rotate(180deg); }
.nl-script-l { margin: 4px 0 12px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.nl-script-l li { display: flex; flex-direction: column; gap: 1px; font-size: 15px; line-height: 1.5; }
.nl-script-l b { font-size: 12.5px; color: var(--ink-secondary); }

/* The entry sheet of a practice exam (design v5 N15). */
.nl-entry { text-align: start; }
.nl-entry h2 { margin: 2px 0 14px; }
.nl-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--track); }
.nl-seg button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--a11y-tap-target-min); border: 0; border-radius: var(--r-pill);
  background: none; color: var(--ink-secondary); cursor: pointer; font-family: var(--font-display); font-weight: 800; font-size: 15px; }
.nl-seg button .ic { width: 16px; height: 16px; }
.nl-seg button[aria-checked="true"] { background: var(--paper-card); color: var(--ink); box-shadow: var(--shadow-card-sm); }
.nl-entry-what { margin: 12px 0 6px; font-size: 14.5px; line-height: 1.5; color: var(--ink-secondary); }
.nl-entry .nl-snd-row { margin-top: 10px; }
.nl-entry-acts { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.nl-entry-acts .link-quiet { align-self: center; }
.nl-entry-run, .nl-entry-warn { margin: 0; font-size: 14px; font-weight: 700; color: var(--ink); }
.nl-entry-warn { color: var(--accent-ink); }
button.nl-mlink { gap: 6px; cursor: pointer; }
.nl-mlink .ic { width: 14px; height: 14px; }
@media (prefers-reduced-motion: no-preference) {
  .nl-seg button { transition: background var(--motion-base) var(--motion-ease), color var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) var(--motion-ease); }
}

/* The resume card's second action, quiet on the dark card (N16·s3). */
.task-card .link-quiet.on-dark { align-self: center; margin-top: 10px; color: var(--tint-on-dark); }
/* The words that answer the question (answer_spans): pass-bg with a teal underline (N14·s4). */
mark.nl-ans { background: var(--pass-bg); color: var(--ink); padding: 0 2px;
  text-decoration: underline; text-decoration-color: var(--pass); text-decoration-thickness: 2px; text-underline-offset: 3px; }
/* Review: the table row that holds the answer (answer_spans), the held column too. */
.nl-text .nl-tablewrap tr.nl-ans-row > * { background: var(--pass-bg); box-shadow: inset 0 -2px 0 var(--pass); }

/* ─ N3 part detail (design v5 N3·s3–s5) ─ */
.nl-prow-h { color: inherit; text-decoration: none; border-radius: var(--r-input-sm); min-height: 44px; }
.nl-prow-h > .ic:last-child { width: 18px; height: 18px; color: var(--ink-tertiary); flex: none; }
.nl-pd { max-width: 680px; margin-inline: auto; }
.nl-pd-top { display: flex; align-items: center; gap: 12px; }
.nl-pd-back { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink); }
.nl-pd h1 { margin-top: 18px; }
.nl-pd-body { display: flex; flex-direction: column; gap: 16px; margin-top: 18px; }
.nl-pd-h, .nl-pd-sh { font-family: var(--font-display); font-weight: 800; color: var(--ink); margin: 0; }
.nl-pd-h { font-size: 17px; }
.nl-pd-sh { font-size: 22px; line-height: 1.2; }
.nl-pd-st { display: flex; align-items: center; gap: 18px; }
.nl-pd-st .tanks { flex: none; width: 68px; }
.nl-pd-st .meta { margin-top: 4px; }
/* The tube alone: its word and name are the card's heading. Not passed: the short
   ink on the tube's edge only (N3·s5), never a red card. */
.nl-pd-st .tk-num, .nl-pd-st .tk-name, .nl-pd-st .tk-sub { display: none; }
.nl-pd-st.failed .tk-tube { border-color: var(--fail); }
.nl-pd-st.failed .tk-mic { color: var(--fail); }
.nl-pd-best { margin: 6px 0 0; color: var(--ink); }

.nl-ot-word { font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.nl-ot-word.c0 { color: var(--fail); }
.nl-ot-word.c1, .nl-ot-word.c2, .nl-ot-word.c3 { color: var(--pass-text); }
.nl-ot { position: relative; height: 180px; margin-top: 14px; border-radius: var(--r-card-sm); overflow: hidden; background: var(--track); }
.nl-ot > span { position: absolute; inset-inline: 0; inset-block-end: var(--lo); height: calc(var(--hi) - var(--lo)); opacity: .5; }
.nl-ot > span.c0 { background: var(--chance-none); }
.nl-ot > span.c1 { background: var(--chance-small); }
.nl-ot > span.c2 { background: var(--chance-fair); }
.nl-ot > span.c3 { background: var(--chance-large); }
.nl-ot > em { position: absolute; inset-inline-end: 12px; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--ink-secondary); }
.nl-ot > em.top { inset-block-start: 8px; }
.nl-ot > em.bot { inset-block-end: 8px; }
.nl-ot-line { position: absolute; inset-inline: 0; inset-block-end: var(--y); border-top: 2px dashed var(--ink-tertiary); }
.nl-ot-line b { position: absolute; inset-inline-end: 12px; inset-block-end: 4px; font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--ink-secondary); }
.nl-ot-pin {
  position: absolute; inset-inline-start: var(--x); inset-block-end: var(--y); transform: translate(-50%, 50%);
  width: 34px; height: 34px; border-radius: var(--r-pill); background: var(--ink); color: var(--paper-card);
  display: grid; place-items: center; box-shadow: 0 0 0 3px var(--paper-card), var(--shadow-card-sm); font-style: normal;
}
[dir="rtl"] .nl-ot-pin { transform: translate(50%, 50%); }
.nl-ot-pin b { font-family: var(--font-display); font-weight: 800; font-size: 13px; line-height: 1; }
.nl-ot-d { margin-top: 8px; color: var(--ink-secondary); font-size: 14px; }

.nl-pd-tip { display: flex; gap: 12px; align-items: flex-start; padding: 16px 18px; border-radius: var(--r-card-sm);
  background: var(--pass-bg); box-shadow: inset 0 0 0 1px var(--pass); color: var(--ink); }
.nl-pd-tip-ic { flex: none; color: var(--pass-text); margin-top: 2px; }
.nl-pd-tip-ic .ic { width: 20px; height: 20px; }
.nl-pd-tip p { margin: 0; }
.nl-pd-tip-k { font-family: var(--font-display); font-weight: 800; font-size: 15px; margin-bottom: 4px !important; }
.nl-pd-plan { margin: 0; padding-inline-start: 20px; display: grid; gap: 4px; }

.nl-pd-grid { display: flex; gap: 10px; margin-top: 14px; }
.nl-pd-blk { flex: var(--n) 1 0; min-width: 0; }
.nl-pd-bl { display: block; font-family: var(--font-display); font-weight: 800; font-size: 12px; color: var(--ink-secondary); margin-bottom: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nl-pd-cells { display: flex; gap: 4px; }
.nl-pd-cells i, .nl-pd-legend i { display: block; flex: 1 1 0; height: 24px; border-radius: var(--r-input-sm); background: var(--track); }
.nl-pd-cells i.s3, .nl-pd-legend i.s3 { background: var(--pass-text); }
.nl-pd-cells i.s2, .nl-pd-legend i.s2 { background: var(--pass); }
.nl-pd-cells i.s1, .nl-pd-legend i.s1 { background: var(--fail); opacity: .75; }
.nl-pd-cells i.s0, .nl-pd-legend i.s0 { background: var(--paper-card); box-shadow: inset 0 0 0 1.5px var(--fail); }
.nl-pd-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 12px 0 0; font-size: 14px; color: var(--ink-secondary); }
.nl-pd-legend span { display: inline-flex; align-items: center; gap: 5px; }
.nl-pd-legend i { flex: none; width: 11px; height: 11px; }

.nl-pd-arow { color: inherit; text-decoration: none; }
.nl-pd-arow .lrow-t small { display: block; }
.nl-pd-arow > .ic { width: 18px; height: 18px; color: var(--ink-tertiary); flex: none; }
.nl-pd-duo { display: flex; align-items: center; gap: 14px; padding: 16px 18px; color: inherit; text-decoration: none; }
.nl-pd-duo .lrow-t b { display: block; font-family: var(--font-display); font-weight: 800; }
.nl-pd-duo .lrow-t small { display: block; color: var(--ink-secondary); font-size: 14px; }
.nl-pd-duo > .ic:last-child { width: 18px; height: 18px; color: var(--ink-tertiary); margin-inline-start: auto; flex: none; }
@media (prefers-reduced-motion: no-preference) {
  .nl-ot-pin { animation: nl-ot-in var(--motion-slow) var(--motion-ease-enter) both; animation-delay: calc(var(--i) * var(--motion-stagger)); }
  @keyframes nl-ot-in { from { opacity: 0; scale: .4; } to { opacity: 1; scale: 1; } }
}

/* N2·s3: a practice exam left midway takes over its part's card. */
.pcard3.run { color: var(--paper-card); }
.pcard3.run .pc-t b { color: var(--paper-card); }
.pcard3.run .pc-t span { color: var(--tint-on-dark); }
.pcard3.run .lrow-ic { color: var(--on-dark-ok); box-shadow: inset 0 0 0 1px var(--tint-on-dark); }
.pc-run-r { margin-inline-start: auto; text-align: end; display: grid; gap: 2px; }
.pc-run-r b { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.pc-run-r b.c0 { color: var(--on-dark-no); }
.pc-run-r b.c1, .pc-run-r b.c2, .pc-run-r b.c3 { color: var(--on-dark-ok); }
.pc-run-r small { font-size: 14px; color: var(--tint-on-dark); }
.pcard3.run .btn { margin-top: 16px; }

/* N1·s4 result due, N1·s9 offline, N1·s11 preview marker. */
.nl-due-acts { display: flex; gap: 10px; margin-top: 16px; }
.nl-due-acts .btn-primary { flex: 1 1 auto; }
.btn-dark-quiet { background: transparent; color: var(--paper-card); box-shadow: inset 0 0 0 1.5px var(--tint-on-dark); }
.t-then { margin-top: 14px; }
.nl-then .nl-pd-h { margin-top: 6px; font-size: 20px; }
.nl-preview { display: flex; align-items: center; gap: 12px; padding: 12px 16px; margin-bottom: 16px; font-size: 15px; color: var(--ink); }
.nl-preview .pill-dark { background: var(--ink); color: var(--paper-card); flex: none; }
.nl-off { margin-bottom: 16px; }

/* N4 Exams at DUO (design v5 N4·s1): one card of rows, the how-to on glass. */
.nl-blist { padding: 4px 20px; }
.nl-brow { display: flex; align-items: center; gap: 14px; padding: 10px 0; min-height: 44px; }
.nl-brow + .nl-brow { border-top: 1px solid var(--line); }
.nl-bdot { flex: none; width: 10px; height: 10px; border-radius: var(--r-pill); background: transparent; }
.nl-brow.booked .nl-bdot { background: var(--pass); }
.nl-brow.waiting .nl-bdot { background: var(--line-strong); }
.nl-brow.failed .nl-bdot { background: var(--fail); }
.nl-brow.passed .nl-bdot { background: var(--pass-text); }
.nl-brow-t { flex: 1 1 auto; min-width: 0; display: grid; gap: 3px; }
.nl-brow-t b { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink); }
.nl-brow-t small { font-size: 14.5px; color: var(--ink-secondary); }
.nl-brow-r { flex: none; display: grid; justify-items: end; gap: 0; text-align: end; }
.nl-bword { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--ink); }
.nl-brow.waiting .nl-bword { color: var(--ink-secondary); }
.nl-brow.failed .nl-bword { color: var(--fail); }
.nl-brow.passed .nl-bword { color: var(--pass-text); }
.nl-blink { font-family: var(--font-display); font-weight: 800; font-size: 15px; color: var(--accent-ink, var(--accent)); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; min-height: 44px; }
.nl-blink .ic { width: 16px; height: 16px; }
.nl-howto2-l { margin: 10px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; color: var(--ink); font-size: 16px; line-height: 1.45; }
.nl-howto2-f { margin-top: 16px; gap: 12px; }

/* N5 result entry: DUO's word big, English under it; N5·s4 the retake plan. */
.nl-res-card .nl-pick { display: grid; gap: 12px; }
.nl-res-card .nl-pick button { display: flex; align-items: center; justify-content: space-between; gap: 12px; text-align: start; padding: 16px 18px; border-radius: var(--r-card-sm); }
.nl-res-card .nl-pick button > span { display: grid; gap: 2px; }
.nl-res-card .nl-pick button b { font-family: var(--font-display); font-weight: 800; font-size: 19px; }
.nl-res-card .nl-pick button small { font-size: 14.5px; color: var(--ink-secondary); }
.nl-res-card .nl-pick button > .ic { opacity: 0; width: 20px; height: 20px; }
.nl-res-card .nl-pick button[aria-checked="true"] { background: var(--ink); color: var(--paper-card); }
.nl-res-card .nl-pick button[aria-checked="true"] small { color: var(--tint-on-dark); }
.nl-res-card .nl-pick button[aria-checked="true"] > .ic { opacity: 1; }
.nl-rplan { list-style: none; margin: 10px 0 0; padding: 0; }
.nl-rplan li { display: flex; gap: 14px; align-items: center; padding: 12px 0; }
.nl-rplan li + li { border-top: 1px solid var(--line); }
.nl-rplan i { flex: none; width: 30px; height: 30px; border-radius: var(--r-pill); background: var(--ink); color: var(--paper-card); display: grid; place-items: center; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 14px; }
.nl-rplan span { display: grid; gap: 2px; }
.nl-rplan b { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink); }
.nl-rplan small { font-size: 14.5px; color: var(--ink-secondary); }
.nl-out .nl-res-card, .nl-out .nl-pd-tip { text-align: start; width: 100%; }

/* X1 All exams and X2 Settings → Exam (design v5): flag cards for looking. */
.x-card { display: block; text-decoration: none; color: inherit; padding: 20px 22px; }
.x-card.mine { box-shadow: inset 0 0 0 2px var(--ink), var(--shadow-card-sm); }
.x-card .exc-top b { font-family: var(--font-display); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink); }
.x-card-row { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.x-card-t { flex: 1 1 auto; min-width: 0; display: grid; gap: 6px; }
.x-card-h { font-family: var(--font-display); font-weight: 800; font-size: 22px; color: var(--ink); }
.x-card .exc-purpose { font-size: 15.5px; color: var(--ink); }
.x-yours { display: inline-flex; align-items: center; gap: 6px; flex: none; background: var(--ink); color: var(--paper-card); }
.x-yours .ic { width: 14px; height: 14px; }
.x-card-go { flex: none; color: var(--ink-secondary); }
.x-card-go .ic { width: 20px; height: 20px; }
.x-before { display: flex; align-items: center; gap: 12px; padding: 12px 20px; }
.x-before .x-card-t b { font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--ink); }
.x-before .x-card-t span { font-size: 14.5px; color: var(--ink-secondary); }
.x-set h1, .x-all h1 { margin-top: 18px; }
.x-set, .x-all { max-width: 680px; margin-inline: auto; }

/* S5 explanation languages per exam, S10 trap words (design v5). */
.lang-ex { display: inline-flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; margin-inline-start: auto; }
.lang-ex .pill { font-size: 12px; }
.x-trap .lrow-t { display: grid; gap: 6px; justify-items: start; }
.x-trap-l { color: var(--ink); font-size: 16px; font-family: var(--font-body); font-weight: 500; }

/* O1 the Dutch setup (design v5). */
.x-setup-top { display: flex; align-items: center; gap: 12px; }
.x-steps { flex: 1 1 auto; display: flex; gap: 6px; }
.x-steps i { flex: 1 1 0; height: 4px; border-radius: var(--r-pill); background: var(--track); }
.x-steps i.on { background: var(--pass); }
.x-skip { flex: none; min-height: 44px; min-width: 44px; background: none; border: 0; cursor: pointer; font-family: var(--font-display); font-weight: 800; }
.x-pick { display: flex; align-items: center; gap: 12px; width: 100%; padding: 16px 20px; text-align: start; border: 0; cursor: pointer; color: var(--ink); }
.x-pick-t { flex: 1 1 auto; display: grid; gap: 2px; }
.x-pick-t b { font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.x-pick-t small { font-size: 14px; color: var(--ink-secondary); }
.x-box { flex: none; width: 26px; height: 26px; border-radius: var(--r-input-sm); box-shadow: inset 0 0 0 1.5px var(--line-strong); display: grid; place-items: center; }
.x-box .ic { width: 16px; height: 16px; }
.x-pick.on { background: var(--ink); color: var(--paper-card); }
.x-pick.on small { color: var(--tint-on-dark); }
.x-pick.on .x-box { background: var(--paper-card); color: var(--ink); box-shadow: none; }
.x-book b { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--ink); }
.x-seg { margin-top: 12px; }
.x-plan .lrow-k { flex: none; width: 76px; font-family: var(--font-display); font-weight: 800; font-size: 13px; color: var(--ink-secondary); }
.les-lane { width: 100%; max-width: 360px; margin-inline: auto; pointer-events: none; }

/* M3–M5 the model card (design v5). */
.nl-model { padding: 18px 20px; }
.nl-model.warm { background: var(--fail-bg); box-shadow: inset 0 0 0 1px var(--fail-border, var(--line)); }
.nl-model-h { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.nl-model-h .lrow-t { flex: 1 1 auto; font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--ink); }
.nl-mk-ic { color: var(--pass-text); display: inline-flex; }
.nl-mk-ic .ic { width: 18px; height: 18px; }
.nl-model.warm .nl-mk-ic { color: var(--fail); }
.nl-mk-chip { display: inline-flex; align-items: center; gap: 5px; flex: none; }
.nl-mk-chip .ic { width: 13px; height: 13px; }
.nl-mk-bar { display: block; height: 6px; border-radius: var(--r-pill); background: var(--track); overflow: hidden; margin: 10px 0 8px; }
.nl-mk-bar i { display: block; height: 100%; width: 40%; border-radius: var(--r-pill); background: var(--pass); }
@media (prefers-reduced-motion: no-preference) {
  .nl-mk-bar i { animation: nl-mk-run 1.6s var(--motion-ease) infinite; }
  @keyframes nl-mk-run { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
}
.nl-mk-score { display: flex; align-items: baseline; gap: 8px; margin: 4px 0 0; color: var(--ink-secondary); font-size: 15px; }
.nl-mk-score b { font-family: var(--font-display); font-weight: 800; font-size: 34px; color: var(--ink); line-height: 1; }
.nl-mk-diff { margin-top: 14px; padding: 14px 16px; border-radius: var(--r-card-sm); background: var(--pass-bg); box-shadow: inset 0 0 0 1px var(--pass); }
.nl-mk-diff p { display: flex; gap: 10px; margin: 0; color: var(--ink); font-size: 15px; }
.nl-mk-diff p .ic { flex: none; width: 18px; height: 18px; color: var(--pass-text); margin-top: 2px; }
.nl-mk-diff .nl-row { display: flex; gap: 10px; margin-top: 12px; }
.nl-mk-diff .nl-row .btn { flex: 1 1 0; }
.nl-transcript { margin: 6px 0 0; padding: 12px 14px; border-radius: var(--r-input); background: var(--paper-card); box-shadow: inset 0 0 0 1px var(--line); color: var(--ink); font-size: 16px; line-height: 1.55; }
mark.nl-mk-q { background: var(--warm-bg); color: inherit; box-shadow: inset 0 -2px 0 var(--accent); }
.nl-mk-fix { list-style: none; margin: 6px 0 0; padding: 0; }
.nl-mk-fix li { display: flex; gap: 12px; padding: 8px 0; color: var(--ink); font-size: 15.5px; }
.nl-mk-fix li + li { border-top: 1px solid var(--line); }
.nl-mk-fix i { flex: none; width: 24px; height: 24px; border-radius: var(--r-pill); background: var(--accent-ink); color: var(--paper-card); display: grid; place-items: center; font-style: normal; font-family: var(--font-display); font-weight: 800; font-size: 13px; }
.nl-savebar { display: grid; }

/* L3 Dutch pricing with no price yet (design v5). */
.nl-l3 .lrow-ic.ok { color: var(--pass-text); background: transparent; }
.nl-l3-own, .nl-l3-info { display: flex; gap: 10px; padding: 14px 16px; border-radius: var(--r-card-sm); background: var(--pass-bg); box-shadow: inset 0 0 0 1px var(--pass); color: var(--ink); font-size: 15.5px; line-height: 1.45; }
.nl-l3-own .ic, .nl-l3-info .ic { flex: none; width: 18px; height: 18px; color: var(--pass-text); margin-top: 2px; }
.nl-l3 .lrow-t { font-family: var(--font-body); font-weight: 500; font-size: 16px; }


/* N2·s5: the mock list's place while the bank loads, two quiet bars, no motion. */
.nl-mocks-skel { display: grid; gap: 8px; padding: 14px 0 4px; }
.nl-mocks-skel i { display: block; height: 14px; border-radius: var(--r-pill); background: var(--line); }
.nl-mocks-skel i + i { width: 60%; }

/* ---- run ring (design v5 S9·s1, Max 2026-10-01) -----------------------------
   The run's window around the day count, the flame at the top; today burns down
   while it is open. */
.run-ring { position: relative; width: 176px; height: 176px; margin: 4px auto 0; }
.run-ring svg { display: block; overflow: visible; }
.run-ring .rr-track { fill: none; stroke: var(--line); stroke-width: 11; opacity: .55; stroke-dasharray: 2 6; }
.run-ring .rr-seg { fill: none; stroke-width: 11; stroke-linecap: round; stroke: var(--line-strong); }
.run-ring .rr-seg.done { stroke: url(#rr-water); }
.run-ring .rr-seg.freeze { stroke: var(--pass-border); }
.run-ring .rr-seg.missed, .run-ring .rr-seg.none { stroke: var(--line); }
.run-ring .rr-seg.today { stroke: var(--accent); }
.run-ring .rr-flame { position: absolute; inset-inline: 0; top: -2px; width: 42px; height: 42px; margin-inline: auto;
  display: grid; place-items: center; border-radius: var(--r-pill); background: var(--paper-card);
  box-shadow: var(--glass-light-shadow); color: var(--accent-ink); }
.run-ring .rr-flame .ic { width: 22px; height: 22px; transform-origin: 50% 90%; }
.run-ring .rr-n { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.run-ring .rr-n b { font-family: var(--font-display); font-weight: 800; font-size: 56px; line-height: 1; color: var(--ink); letter-spacing: -.02em; }
.run-ring .rr-n small { margin-top: 4px; font-family: var(--font-display); font-weight: 800; font-size: 12.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-secondary); }
.run-hero { display: flex; flex-direction: column; align-items: center; text-align: center; }
.run-hero .display { margin-top: 18px; }
.run-hero .lede { margin-top: 6px; }
@media (prefers-reduced-motion: no-preference) {
  @keyframes pk-burn {
    0%, 100% { opacity: 1; stroke-dashoffset: 0; }
    50% { opacity: .38; stroke-dashoffset: calc(var(--len) * .45); }
  }
  .run-ring .rr-seg { stroke-dasharray: calc(var(--len) * 1px) calc(var(--len) * 1px); stroke-dashoffset: calc(var(--len) * 1px);
    animation: pk-draw var(--motion-draw) var(--motion-ease-enter) both;
    animation-delay: calc(var(--motion-pop-delay) + var(--i) * var(--motion-stagger)); }
  .run-ring .rr-seg.today { stroke-dasharray: var(--len) var(--len);
    animation: pk-draw var(--motion-draw) var(--motion-ease-enter) both, pk-burn var(--motion-pulse) ease-in-out infinite;
    animation-delay: calc(var(--motion-pop-delay) + var(--i) * var(--motion-stagger)), calc(var(--motion-pop-delay) + var(--i) * var(--motion-stagger) + var(--motion-draw)); }
  .run-ring .rr-flame { animation: pk-pop var(--motion-pop) var(--motion-ease-sheet) both; animation-delay: var(--motion-pop-delay); }
  .run-ring .rr-flame .ic { animation: pk-flame var(--motion-flame) ease-in-out infinite; }
  .run-ring .rr-n b { animation: pk-pop var(--motion-pop) var(--motion-ease-sheet) both; animation-delay: calc(var(--motion-pop-delay) + var(--motion-draw)); }
}

/* Exams at DUO: "How to book" folds to its kicker, so the rows fit one screen (decision 46). */
.nl-howto2 summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; cursor: pointer; min-height: 44px; }
.nl-howto2 summary::-webkit-details-marker { display: none; }
.nl-howto2 summary .kicker { margin: 0; }
.nl-howto2 summary .ic { width: 18px; height: 18px; color: var(--ink-secondary); transition: transform var(--motion-base) var(--motion-ease); }
.nl-howto2[open] summary .ic { transform: rotate(180deg); }
.nl-howto2:not([open]) { padding-block: 10px; }

/* Five tubes on a narrow Today stand a little shorter, so tonight's task and its Start
   sit on the first screen with them (Max 2026-10-01: one screen where it can be). */
@media (max-width: 560px) { .t-stand .tanks.n5 { --h: 128px; } }

/* ---- N2 Practice (design v5 N2·s1): one row per part, at most one button ---------- */
.pr5 { display: grid; gap: 12px; }
@media (min-width: 900px) { .pr5 { grid-template-columns: 1fr 1fr; align-items: start; } }
.pc5 { padding: 16px 18px; display: grid; gap: 12px; }
.pc5-d summary { list-style: none; cursor: pointer; }
.pc5-d summary::-webkit-details-marker { display: none; }
.pc5-top { display: flex; align-items: center; gap: 14px; min-height: 44px; }
.pc5-t { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.pc5-t b { font-family: var(--font-display); font-weight: 800; font-size: 18px; color: var(--ink); }
.pc5-t span { font-size: 14.5px; color: var(--ink-secondary); }
.pc5-r { flex: none; display: grid; justify-items: end; gap: 1px; text-align: end; }
.pc5-r b { font-family: var(--font-display); font-weight: 800; font-size: 16px; color: var(--ink); }
.pc5-r b.ok { color: var(--pass-text); }
.pc5-r b.c0 { color: var(--fail); }
.pc5-r b.c2, .pc5-r b.c3 { color: var(--pass-text); }
.pc5-r small { font-size: 13.5px; color: var(--ink-secondary); }
.pc5.dglass .pc5-t b, .pc5.dglass .pc5-r small { color: var(--paper-card); }
.pc5.dglass .pc5-t span { color: var(--panel-body); }
.pc5.dglass .pc5-r b.c0 { color: var(--on-dark-no); }
.pc5.dglass .pc5-r b.c2, .pc5.dglass .pc5-r b.c3 { color: var(--on-dark-ok); }
.pc5.dglass .lrow-ic { background: var(--tint-on-dark-fill); color: var(--paper-card); }
.pc5.done { opacity: .82; }
.pc5 .nl-mocks { margin: 10px 0 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.pc5.dglass .nl-mocks { border-color: var(--glass-dark-border); }
.pc5-d[open] .pc5-top { padding-bottom: 4px; }

/* Design v5 N1·s1, the Dutch Today on a narrow screen: tonight's task under the heading,
   then the tubes, the one DUO row, the week and the trap word. */
@media (max-width: 900px) {
  .nl-today .t-head, .nl-today .t-status { order: 1; } .nl-today .t-task { order: 2; } .nl-today .t-stand { order: 3; }
  .nl-today .t-side { order: 4; } .nl-today .t-week { order: 5; } .nl-today .t-trap { order: 6; }
}
/* Tonight's part: a small accent dot under its tube, and its rim in accent. */
.tk-tgt { display: block; width: 6px; height: 6px; margin: 6px auto -2px; border-radius: var(--r-pill); background: var(--accent); }
.tk.tgt .tk-tube { box-shadow: inset 0 0 0 2px var(--accent); }
.tanks .tk.self .tk-num.worded.tone-warm { color: var(--fail-ink); }
.tanks .tk.self:has(.tk-num.tone-warm) .tk-tube { border-color: var(--fail-border); }

/* ---- N3 Progress (design v5 N3·s1): one short card per part ---------------------- */
.pg5 { gap: 12px; }
.pg5-c { display: block; color: inherit; text-decoration: none; }
.pg5-h { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.pg5-n { font-family: var(--font-display); font-weight: 800; font-size: 18px; color: var(--ink); }
.pg5-w { font-family: var(--font-display); font-weight: 800; font-size: 16px; }
.pg5-w.ok, .pg5-w.c2, .pg5-w.c3 { color: var(--pass-text); }
.pg5-w.c0 { color: var(--fail-ink); }
.pg5-w.c1 { color: var(--ink); }
.pg5-h .meta { margin-inline-start: auto; }
.pg5-c .nl-band { margin-top: 14px; }
.pg5-c.done .note-sm { margin-top: 8px; }
.nl-band-tick { position: absolute; top: -4px; bottom: -4px; inset-inline-start: var(--at); width: 2px; margin-inline-start: -1px; background: var(--ink-secondary); opacity: .55; border-radius: var(--r-pill); }

/* Tubes that open their part (Progress): no link underline, the tube is the target. */
.tk-link { text-decoration: none; color: inherit; }

/* Phone width follows the phone artboards, as the iOS app does: Italian Practice is B02
   (one group of rows; the W06 cards, recent, the mock card and the words are wider-screen
   furniture: the mode switch leads to the mock, History and Mistakes hold the rest), and
   Italian Today is B01 (head, tanks, tonight's task: the week lives on Progress, the trap
   in Mistakes, the days in the kicker, the mock in Practice). The Dutch Today keeps its one
   DUO row and drops the week and the trap word the same way (decision 46). */
@media (min-width: 561px) { .pr-rows { display: none; } }
@media (max-width: 560px) {
  .pr-wide, .practice-v3 .pr-head .lede { display: none; }
  .today :is(.t-week, .t-trap), .today:not(.nl-today) .t-side { display: none; }
}
/* A status row on Today (run at risk, expired session, a result back): on a
   phone the lede steps aside and the tanks get shorter, so tonight's Start stays on the
   first screen. The tanks already say what the lede says. */
@media (max-width: 560px) {
  .today .today-grid:has(.t-status) .t-head .lede { display: none; }
  .today:not(.nl-today) .today-grid:has(.t-status) .t-stand .tanks { --h: 112px; }
}
/* A short phone (375 × 667 and the like), as the iOS app's compact height: shorter tanks,
   tighter task card, one status row, so the evening task stays above the tab bar. */
@media (max-width: 560px) and (max-height: 720px) {
  .today .t-stand .tanks, .today .t-stand .tanks.n5 { --h: 104px; }
  .today:not(.nl-today) .t-status > :nth-child(n+2) { display: none; }
  .today.nl-today .t-stand .tanks.n5 { --h: 104px; }
  .today .task-card { padding: 16px; }
  .today .t-head .lede { margin-top: 8px; }
}
/* Dutch Today on a phone (decision 46): the mode line and the DUO row's note step aside
   (the entry sheet names the mode, the row's title is the action), the five tubes shorten. */
@media (max-width: 560px) {
  .nl-today .t-task .tc-mode, .nl-today .duo-row .ic-t span { display: none; }
  .nl-today .t-stand .tanks.n5 { --h: 112px; }
}
/* Italian Progress on a phone is B03, as in the app (decision 46): the title, the tanks, three
   count rows, the week, the next mock and History. The W07 trend lines, mock runs and words
   stay on wider screens. */
@media (max-width: 560px) {
  .progress-v3 :is(.trend-card, .duo-16) { display: none; }
  .progress-v3 .tanks.sz-xl { --h: 132px; }
}
/* The usage-data card (track.js): above the tab bar, never over a task screen. Yes and
   No are the same weight; the cross is a no, and the text says so. */
.pk-consent {
  position: fixed; z-index: 50; left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom)); width: min(460px, calc(100% - 24px));
  padding: 18px 20px 16px; border-radius: var(--r-panel);
}
.pk-consent-h { display: block; font-family: var(--font-display); font-weight: 800; font-size: 16px;
  color: var(--ink); padding-inline-end: 36px; text-wrap: balance; }
.pk-consent-p { margin: 8px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-secondary); text-wrap: pretty; }
.pk-consent-p a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.pk-consent-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.pk-consent-b { min-height: 44px; justify-content: center; }
.pk-consent-x {
  position: absolute; top: 8px; inset-inline-end: 8px; width: 44px; height: 44px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-secondary); font-size: 22px; line-height: 1; cursor: pointer;
}
.pk-consent-x:focus-visible { outline: 2px solid var(--ink); outline-offset: -4px; }
/* "Did this help?" and "Report a problem" under an explanation (K.feedback). */
.fb-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: 14px;
  padding-top: 12px; border-top: 1px solid var(--line); }
.fb-q { font-size: 13.5px; color: var(--ink-secondary); margin-inline-end: auto; }
/* Short answers side by side at every width: the phone rule that widens .btn to the
   row is for long labels; "Yes", "No" and a reason fit as pills that wrap. */
.fb-row .btn { width: auto; flex: 0 0 auto; min-height: 40px; padding: 8px 16px; font-size: 14px; }
.fb-done { font-size: 13.5px; color: var(--ink-secondary); }
.fb-report { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 8px; }
.fb-report .fb-q { flex-basis: 100%; }
.fb-link { border: 0; background: none; padding: 6px 0; min-height: 36px; font: inherit; font-size: 13.5px;
  color: var(--ink-secondary); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
