/* organic.css — the Organic / bamboo-green design system for the onboarding flow.
   Tokens + components extracted verbatim from design_system/design-system.html;
   wizard-specific additions appended at the end. Single shared stylesheet — no
   per-screen CSS. Themed via html[data-theme]. */

        /* ============================================================
           DESIGN TOKENS — light / dark, green "bamboo" brand
           ============================================================ */
        :root {
            /* brand ramp (constant across themes) */
            --brand-900: #1f3311;
            --brand-700: #3f6b23;
            --brand-600: #5a8a3a;   /* primary */
            --brand-500: #6b9e46;
            --brand-400: #8bb36a;
            --brand-200: #c4d9ad;

            /* priority signal colors */
            --sig-red:    #d9534f;
            --sig-amber:  #e0a53a;
            --sig-orange: #dd8036;
            --sig-green:  #5a8a3a;

            /* semantic — light theme defaults */
            --bg:        #f5f9f0;
            --bg-2:      #ecf3e2;
            --surface:   #ffffff;
            --surface-2: #f3f8ec;
            --ink:       #23361a;
            --ink-soft:  #4c5d3e;
            --line:      rgba(90,138,58,0.18);
            --line-soft: rgba(90,138,58,0.10);
            --tint:      rgba(90,138,58,0.08);
            --tint-2:    rgba(90,138,58,0.14);
            --shadow:    0 12px 40px rgba(63,107,35,0.10);
            --shadow-lg: 0 24px 64px rgba(63,107,35,0.16);
            --on-brand:  #ffffff;

            /* organic radii scale */
            --r-blob-1: 30px 60px 30px 60px;
            --r-blob-2: 60px 30px 60px 30px;
            --r-blob-3: 40px 60px 40px 60px;
            --r-pill:   50px;
            --r-sm:     18px;
            --r-md:     28px;

            /* the three pre-writing diagnostic layers (Writing block) */
            --lay-gen:  #5a8a3a;  --lay-gen-fill:  rgba(90,138,58,.16);
            --lay-spec: #2f6f8f;  --lay-spec-fill: rgba(47,111,143,.16);
            --lay-inst: #b5731f;  --lay-inst-fill: rgba(181,115,31,.18);

            /* type-scale factors — 1 on mobile; raised for desktop in the media
               query after the theme blocks below */
            --fs-scale-title: 1;
            --fs-scale-body: 1;
            --fs-scale-ui: 1;
        }

        html[data-theme="dark"] {
            --bg:        #131a0e;
            --bg-2:      #1a2313;
            --surface:   #1e2916;
            --surface-2: #26331b;
            --ink:       #e8f0dd;
            --ink-soft:  #a9bd94;
            --line:      rgba(139,179,106,0.22);
            --line-soft: rgba(139,179,106,0.12);
            --tint:      rgba(139,179,106,0.10);
            --tint-2:    rgba(139,179,106,0.18);
            --shadow:    0 12px 40px rgba(0,0,0,0.45);
            --shadow-lg: 0 24px 64px rgba(0,0,0,0.55);
            --brand-600: #7fb04e;
            --on-brand:  #12200a;

            /* pre-writing layer palette — dark variants (translucent fills re-themed) */
            --lay-gen:  #8bb36a;  --lay-gen-fill:  rgba(139,179,106,.20);
            --lay-spec: #6fb0cf;  --lay-spec-fill: rgba(111,176,207,.20);
            --lay-inst: #dda155;  --lay-inst-fill: rgba(221,161,85,.22);
        }

        /* Desktop-only type bump — THREE tiers (titles ×1.16, body copy ×1.27,
           smallest/micro-UI fonts ×1.15). Mobile (≤760px, the stylesheet's own
           largest breakpoint) keeps every original size exactly. Tune the three
           factors here; title/body/ui-tier rules multiply themselves via calc().
           Emojis/pictographs, icon glyphs in fixed circles, diagram words
           (.ra-sweep .w) and blurred .fuzz stay plain px and never scale. */
        @media (min-width: 761px) {
            :root { --fs-scale-title: 1.16; --fs-scale-body: 1.27; --fs-scale-ui: 1.15; }
        }

        body {
            font-family: 'Nunito', system-ui, sans-serif;
            background: var(--bg);
            color: var(--ink);
            line-height: 1.6;
            min-height: 100vh;
            overflow-x: hidden;
            transition: background .4s ease, color .4s ease;
        }

        /* ---------- organic background blobs ---------- */
        .organic-bg { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
        .blob { position: absolute; opacity: .12; animation: sway 9s ease-in-out infinite; }
        .blob:nth-child(2) { animation-delay: -3s; }
        .blob:nth-child(3) { animation-delay: -6s; }
        @keyframes sway {
            0%,100% { transform: rotate(-6deg) scale(1); }
            50%     { transform: rotate(6deg) scale(1.06); }
        }

        /* overflow-x:hidden clips document scrollWidth to the viewport. Without it, any
           wide-content stage nested a few levels deep (e.g. read_ahead's .ra-stage, whose
           own overflow-x:auto only clips its own paint) still leaks its scroll extent up
           through .card's position:relative into document.documentElement.scrollWidth —
           a real horizontal scrollbar never appears, but any width probe (viewport-fit
           checks, screenshot tooling) sees a page ~250px wider than the layout. */
        .wrap { position: relative; z-index: 1; max-width: 1180px; margin: 0 auto; padding: 28px 24px 80px; overflow-x: hidden; }

        /* ============================================================
           HEADER / NAV
           ============================================================ */
        .topbar {
            display: flex; align-items: center; justify-content: space-between; gap: 20px;
            flex-wrap: wrap;
            padding: 15px 32px; margin-bottom: 40px;
            border-radius: var(--r-pill);
            background: linear-gradient(135deg, var(--tint), var(--tint-2));
            border: 1px solid var(--line-soft);
        }
        .brand { display: flex; align-items: center; gap: 14px; }
        .brand-mark {
            width: 80px; height: 70px; flex-shrink: 0;
            border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
            background: linear-gradient(135deg, var(--brand-400), var(--brand-200));
            display: flex; align-items: center; justify-content: center;
            font-size: 26px; color: var(--on-brand);
            animation: breathe 4s ease-in-out infinite;
            overflow: hidden;
        }
        .brand-mark img { width: 100%; height: 100%; object-fit: cover; display: block; }
        @keyframes breathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
        .brand h1 { font-family: 'Fraunces', serif; font-size: calc(22px * var(--fs-scale-ui)); font-weight: 600; letter-spacing: -.01em; }
        .brand span { display: block; font-size: calc(12px * var(--fs-scale-ui)); font-weight: 600; color: var(--ink-soft); letter-spacing: .04em; }

        .nav { display: flex; gap: 8px; flex-wrap: wrap; }
        .nav button {
            padding: 11px 20px; font: inherit; font-size: calc(14px * var(--fs-scale-ui)); font-weight: 700;
            color: var(--ink-soft); background: transparent;
            border: 2px solid transparent; border-radius: 22px 40px 22px 40px;
            cursor: pointer; transition: all .25s ease;
        }
        .nav button:hover { color: var(--ink); background: var(--tint); }
        .nav button.active { color: var(--brand-600); background: var(--tint-2); border-color: var(--line); }

        .theme-toggle {
            display: flex; align-items: center; gap: 8px;
            padding: 8px 8px 8px 16px; border-radius: var(--r-pill);
            background: var(--surface); border: 1px solid var(--line);
        }
        .theme-toggle span { font-size: calc(13px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft); }
        .switch {
            width: 52px; height: 30px; border-radius: 30px; border: none; cursor: pointer;
            background: var(--brand-200); position: relative; transition: background .3s ease;
        }
        html[data-theme="dark"] .switch { background: var(--brand-700); }
        .switch::after {
            content: '☀'; position: absolute; top: 3px; left: 3px;
            width: 24px; height: 24px; border-radius: 50%;
            background: var(--surface); display: grid; place-items: center; font-size: calc(13px * var(--fs-scale-ui));
            transition: transform .3s cubic-bezier(.4,1.4,.5,1);
        }
        html[data-theme="dark"] .switch::after { content: '☾'; transform: translateX(22px); }

        /* ============================================================
           SECTIONS
           ============================================================ */
        .section { display: none; animation: grow .5s ease; }
        .section.active { display: block; }
        @keyframes grow { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

        .section-lead { max-width: 640px; margin-bottom: 34px; }
        .section-lead .kicker {
            font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
            color: var(--brand-600); margin-bottom: 10px;
        }
        .section-lead h2 { font-family: 'Fraunces', serif; font-size: calc(40px * var(--fs-scale-title)); font-weight: 600; line-height: 1.1; margin-bottom: 12px; letter-spacing: -.02em; }
        .section-lead p { font-size: calc(17px * var(--fs-scale-body)); color: var(--ink-soft); }

        .group-title {
            display: flex; align-items: center; gap: 12px;
            font-size: calc(13px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
            color: var(--ink-soft); margin: 42px 0 20px;
        }
        .group-title::after { content: ''; flex: 1; height: 2px; border-radius: 2px; background: var(--line-soft); }

        /* ---------- generic card ---------- */
        .card {
            background: var(--surface); border: 1px solid var(--line-soft);
            border-radius: var(--r-blob-1); padding: 32px;
            box-shadow: var(--shadow); position: relative;
        }
        .card.alt { border-radius: var(--r-blob-2); }
        .card::before {
            content: ''; position: absolute; top: -40%; right: -30%;
            width: 70%; height: 90%;
            background: radial-gradient(ellipse at center, var(--tint) 0%, transparent 70%);
            pointer-events: none;
        }
        .card > * { position: relative; }

        /* ============================================================
           FOUNDATIONS
           ============================================================ */
        .swatch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px; }
        .swatch { border-radius: var(--r-md); overflow: hidden; border: 1px solid var(--line-soft); background: var(--surface); }
        .swatch .chip { height: 70px; }
        .swatch .meta { padding: 12px 14px; }
        .swatch .meta b { display: block; font-size: calc(13px * var(--fs-scale-ui)); }
        .swatch .meta code { font-size: calc(11px * var(--fs-scale-ui)); color: var(--ink-soft); }

        .type-row { display: flex; align-items: baseline; gap: 20px; padding: 14px 0; border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
        .type-row:last-child { border: none; }
        .type-row .lbl { font-size: calc(12px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft); width: 110px; }
        .type-d { font-family: 'Fraunces', serif; font-size: calc(44px * var(--fs-scale-title)); font-weight: 600; letter-spacing: -.02em; }
        .type-h { font-family: 'Fraunces', serif; font-size: calc(28px * var(--fs-scale-title)); font-weight: 600; }
        .type-b { font-size: calc(17px * var(--fs-scale-body)); }
        .type-c { font-size: calc(13px * var(--fs-scale-ui)); color: var(--ink-soft); }

        /* buttons */
        .btn {
            padding: 15px 32px; font: inherit; font-size: calc(15px * var(--fs-scale-ui)); font-weight: 800;
            border: none; border-radius: var(--r-blob-1); cursor: pointer;
            transition: transform .25s ease, box-shadow .25s ease, background .25s ease;
        }
        .btn-primary {
            color: var(--on-brand);
            background: linear-gradient(135deg, var(--brand-600), var(--brand-400));
            box-shadow: 0 10px 26px rgba(90,138,58,.30);
        }
        .btn-primary:hover { transform: translateY(-3px); box-shadow: 0 16px 36px rgba(90,138,58,.42); }
        .btn-ghost { color: var(--brand-600); background: var(--tint); }
        .btn-ghost:hover { background: var(--tint-2); transform: translateY(-2px); }
        .btn-outline { color: var(--ink); background: transparent; border: 2px solid var(--line); }
        .btn-outline:hover { border-color: var(--brand-600); color: var(--brand-600); }
        /* Disabled had NO visual treatment at all, on any variant. Every drill sets
           `disabled = true` on its in-flight control (the reaction drill's Stop & score, the
           layer-split Grade button, Word-Trap's play, the failure card's Retry/Skip) and the
           button went on reading as fully live — same fill, same lift on hover, same pointer
           — so the only thing telling the user their click had registered was a status line
           elsewhere on the page. The hover overrides are the load-bearing half: without them
           a dead button still rises to meet the cursor, which is what made it read as
           clickable. Kept as one rule on `.btn` so every variant inherits it. */
        .btn:disabled {
            cursor: default; opacity: .55; filter: saturate(.55);
            box-shadow: none; transform: none;
        }
        .btn:disabled:hover { transform: none; box-shadow: none; }
        .btn-ghost:disabled:hover { background: var(--tint); }
        .btn-outline:disabled:hover { border-color: var(--line); color: var(--ink); }
        .btn-sm { padding: 10px 20px; font-size: calc(13px * var(--fs-scale-ui)); border-radius: 16px 26px 16px 26px; }

        /* tags / badges */
        .tag {
            display: inline-flex; align-items: center; gap: 6px;
            padding: 6px 14px; font-size: calc(12px * var(--fs-scale-ui)); font-weight: 700;
            background: var(--tint-2); color: var(--brand-600); border-radius: 20px;
        }
        .tag.solid { background: linear-gradient(135deg, var(--brand-600), var(--brand-400)); color: var(--on-brand); }
        .tag.red    { background: rgba(217,83,79,.15);  color: var(--sig-red); }
        .tag.amber  { background: rgba(224,165,58,.18);  color: var(--sig-amber); }
        .tag.orange { background: rgba(221,128,54,.16);  color: var(--sig-orange); }

        /* inputs */
        .field { display: block; }
        .field label { display: block; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 700; margin-bottom: 8px; color: var(--ink-soft); }
        .input, .textarea {
            width: 100%; padding: 16px 20px; font: inherit; font-size: calc(16px * var(--fs-scale-body));
            color: var(--ink); background: var(--surface-2);
            border: 2px solid var(--line); border-radius: var(--r-md);
            transition: border-color .25s ease, box-shadow .25s ease;
        }
        .textarea { border-radius: var(--r-blob-3); resize: vertical; min-height: 120px; }
        .input:focus, .textarea:focus {
            outline: none; border-color: var(--brand-600);
            box-shadow: 0 0 0 4px var(--tint);
        }
        .input::placeholder, .textarea::placeholder { color: var(--ink-soft); opacity: .7; }

        .demo-rows { display: grid; gap: 26px; }
        .btn-row { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }

        /* ============================================================
           ONBOARDING BLOCKS
           ============================================================ */
        /* Screen 0's three-step poll rail. Pills are pending by default, `.step-active`
           while the step is the one waiting on the user, `.step-done` once answered — the
           connector between two pills fills in as the step it leaves behind is completed.
           The state classes carry the `step-` prefix deliberately: bare `.done` and
           `.active` are taken elsewhere in this sheet (the recap fact rows, `.nav button`,
           `.section`), and an unprefixed `.done` here inherited the recap row's card
           padding/background/shadow and rendered the answered pills as white cards. */
        .step-rail { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 26px; }
        .step { display: flex; align-items: center; gap: 10px; opacity: .45; transition: opacity .3s ease; }
        .step + .step::before {
            content: ""; width: 26px; height: 2px; background: var(--line);
            border-radius: 2px; transition: background .3s ease;
        }
        .step.step-done + .step::before, .step.step-active + .step::before { background: var(--brand-600); }
        .step.step-active, .step.step-done { opacity: 1; }
        /* an answered step the user can return to — the only clickable pill */
        .step.clickable { cursor: pointer; }
        .step.clickable:hover .step-num { border-color: var(--brand-600); background: var(--tint-2); }
        .step.clickable:hover .step-label { color: var(--brand-600); }
        .step .step-num {
            width: 30px; height: 30px; flex-shrink: 0;
            border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
            display: grid; place-items: center;
            font-size: calc(13px * var(--fs-scale-ui)); font-weight: 800;
            color: var(--ink-soft); background: var(--surface-2);
            border: 2px solid var(--line); transition: all .3s ease;
        }
        .step.step-active .step-num {
            color: var(--on-brand); border-color: transparent;
            background: linear-gradient(135deg, var(--brand-600), var(--brand-400));
        }
        .step.step-done .step-num { color: var(--brand-600); border-color: var(--brand-600); background: var(--tint); }
        .step .step-label {
            font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800;
            letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
        }
        .step.step-active .step-label { color: var(--brand-600); }

        /* The mounted step. Exactly one `.step-body` lives here at a time; the min-height
           keeps the tall fork and the compact option lists on a common floor so a swap
           can't collapse the page under the user's cursor mid-click. */
        /* The floor is the tallest step (the fork, ~426px at desktop) so a swap to a
           shorter option list can't collapse the page under the user's cursor mid-click.
           Below 761px the fork stacks to one column and towers over the option steps, so
           the responsive block drops the floor rather than leaving dead space there. */
        .step-stage { position: relative; min-height: 430px; }
        /* Screen 0 stacks rail + question + step body + skip button, where the reading
           screens the lead's spacing was tuned for have nothing below their card — so it
           tightens the lead a little. The skip button still lands just below the fold on a
           900px viewport (the fork card alone is ~426px); that is accepted rather than
           compressing the shared type scale to chase it, since skipping is the minority
           path and every step's own answers sit above the fold. */
        .step-rail ~ .screen-lead { margin-bottom: 18px; }
        .step-body {
            opacity: 0;
            transition: opacity .18s ease, transform .18s ease;
        }
        .step-body.from-right { transform: translateX(26px); }
        .step-body.from-left  { transform: translateX(-26px); }
        .step-body.in { opacity: 1; transform: none; }
        /* the outgoing half of a swap — it leaves the way the new step is arriving from */
        .step-body.out { opacity: 0; }
        .step-body.out.to-left  { transform: translateX(-26px); }
        .step-body.out.to-right { transform: translateX(26px); }

        /* skips the whole poll, from whichever step the user is on */
        .start-next { display: flex; justify-content: center; margin-top: 26px; }

        /* NOTE: Screen 0 used to slide each block in below the last via a `.start-reveal`
           0fr→1fr grid row. That is GONE — it is a stepper now, one step mounted at a
           time (see .step-stage above). The 0fr-floor lesson those rules taught still
           applies wherever a grid row collapses: a 0fr track floors at its item's PADDING
           box, so the collapsing item must carry no padding/border/margin and the padded
           card nests inside it. `.anim-unfold` in the paywall block relies on it. */

        /* left-aligned, not centred: in the stepper the option card shares its left edge
           with the step rail and the question above it. (It was centred back when it
           floated below the fork card in the old reveal layout.) */
        
        .hook-list { display: grid; gap: 12px; max-width: 600px; margin: auto;}
        .hook {
            display: flex; align-items: center; gap: 18px;
            padding: 12px 22px; cursor: pointer;
            background: var(--surface-2); border: 2px solid var(--line-soft);
            border-radius: 22px 42px 22px 42px; transition: all .25s ease;
        }
        .hook:hover { border-color: var(--brand-600); transform: translateX(8px); background: var(--tint); }
        /* an answered poll option — it stays picked while the step below it opens, so
           the user can see what they chose without scrolling back up */
        .hook.selected { border-color: var(--brand-600); background: var(--tint); }
        .hook.selected .go { opacity: 1; }
        .hook .num {
            width: 40px; height: 40px; flex-shrink: 0; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
            background: linear-gradient(135deg, var(--brand-600), var(--brand-400));
            color: var(--on-brand); display: grid; place-items: center; font-weight: 800;
        }
        .hook .txt { font-size: calc(16px * var(--fs-scale-body)); font-weight: 600; }
        .hook .go { margin-left: auto; color: var(--brand-600); font-size: 22px; opacity: .5; transition: opacity .25s; }
        .hook:hover .go { opacity: 1; }

        /* GT/AC fork */
        .fork { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
        .fork-card {
            padding: 34px 30px; cursor: pointer; text-align: left;
            background: var(--surface); border: 2px solid var(--line);
            border-radius: var(--r-blob-3); transition: all .3s ease;
        }
        .fork-card:hover, .fork-card.selected {
            border-color: var(--brand-600); transform: translateY(-6px);
            box-shadow: var(--shadow-lg);
        }
        .fork-card .peak { font-size: 34px; display: block; }
        .fork-card .peak img { width: 150px; height: 150px; object-fit: contain; display: block; }
        .fork-card h4 { font-family: 'Fraunces', serif; font-size: calc(27px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 6px; margin-left: 20px; margin-top: 0;}
        .fork-card p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); margin-left: 20px; }
        .fork-card .selected-flag { margin-top: 16px; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 800; color: var(--brand-600); opacity: 0; transition: opacity .25s; }
        .fork-card.selected .selected-flag { opacity: 1; margin-left: 20px; }

        /* myth-buster */
        .myth { border-radius: var(--r-blob-2); }
        .myth .myth-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
        .myth .bust-icon {
            width: 52px; height: 52px; border-radius: 50%;
            background: rgba(217,83,79,.15); color: var(--sig-red);
            display: grid; place-items: center; font-size: 24px; flex-shrink: 0;
        }
        .myth h4 { font-family: 'Fraunces', serif; font-size: calc(21px * var(--fs-scale-title)); font-weight: 600; }
        .myth-compare { display: grid; grid-template-columns: 1fr auto 1fr; gap: 18px; align-items: center; margin-bottom: 20px; }
        .myth-side { padding: 18px 20px; border-radius: var(--r-md); }
        .myth-side.false { background: rgba(217,83,79,.10); border: 1px dashed rgba(217,83,79,.4); }
        .myth-side.true  { background: var(--tint); border: 1px solid var(--line); }
        .myth-side .cap { font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 8px; }
        .myth-side.false .cap { color: var(--sig-red); }
        .myth-side.true  .cap { color: var(--brand-600); }
        .myth-side p { font-size: calc(15px * var(--fs-scale-body)); font-weight: 600; }
        /* head + demo sub-parts (Speaking screens 1 & 4 use the myth-compare with a
           Fraunces "head" line and an italic worked "demo" quote) */
        .myth-side .head { font-family: 'Fraunces', serif; font-size: calc(16px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 6px; }
        .myth-side .demo { margin-top: 10px; font-family: 'Fraunces', serif; font-size: calc(14.5px * var(--fs-scale-body)); font-style: italic; line-height: 1.55; color: var(--ink); }
        .myth-arrow { display: grid; place-items: center; font-size: 24px; color: var(--ink-soft); }
        .myth-proof { font-size: calc(15px * var(--fs-scale-body)); color: var(--ink-soft); border-top: 1px solid var(--line-soft); padding-top: 18px; }
        .myth-proof b { color: var(--brand-600); }

        /* checkbox confirm */
        .confirm {
            display: flex; align-items: center; gap: 14px; margin-top: 22px;
            padding: 16px 22px; border-radius: var(--r-pill);
            background: var(--surface-2); border: 1px solid var(--line); cursor: pointer;
            user-select: none; transition: all .25s ease;
        }
        .confirm:hover { border-color: var(--brand-600); }
        .confirm.on { background: var(--tint-2); border-color: var(--brand-600); }
        .confirm .box {
            width: 28px; height: 28px; flex-shrink: 0; border-radius: 9px;
            border: 2px solid var(--line); background: var(--surface);
            display: grid; place-items: center; color: var(--on-brand); font-weight: 900; font-size: calc(16px * var(--fs-scale-ui));
            transition: all .2s ease;
        }
        .confirm.on .box { background: var(--brand-600); border-color: var(--brand-600); }
        .confirm .box i { opacity: 0; transform: scale(.4); transition: all .2s cubic-bezier(.4,1.6,.5,1); font-style: normal; }
        .confirm.on .box i { opacity: 1; transform: scale(1); }
        .confirm span { font-weight: 700; }

        /* paywall */
        .paywall { border-radius: var(--r-blob-1); text-align: center; padding: 44px 40px; }
        .paywall .lock { font-size: 40px; margin-bottom: 10px; }
        .paywall .lock img { width: 112px; height: 112px; object-fit: contain; display: block; margin: 0 auto; }
        .paywall h3 { font-family: 'Fraunces', serif; font-size: calc(28px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 8px; }
        .paywall > p { font-size: calc(16px * var(--fs-scale-body)); color: var(--ink-soft); max-width: 460px; margin: 0 auto 28px; }
        .plans { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; max-width: 620px; margin: 0 auto; text-align: left; }
        .plan { padding: 26px 24px; border-radius: var(--r-blob-3); border: 2px solid var(--line); background: var(--surface); position: relative; }
        .plan.featured { border-color: var(--brand-600); box-shadow: var(--shadow); }
        /* "Best value" is a factual claim (Coaching bundles the Handbook), not a per-screen
           emphasis choice — it always sits on .plan-coach, independent of .featured. */
        .plan.plan-coach::after {
            content: 'Best value'; position: absolute; top: -12px; right: 22px;
            padding: 4px 14px; font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; border-radius: 20px;
            background: var(--brand-600); color: var(--on-brand);
        }
        .plan h5 { font-size: calc(15px * var(--fs-scale-ui)); font-weight: 800; margin-bottom: 4px; }
        .plan .price { font-family: 'Fraunces', serif; font-size: calc(32px * var(--fs-scale-title)); font-weight: 600; color: var(--brand-600); margin-bottom: 4px; }
        .plan .price small { font-size: calc(14px * var(--fs-scale-ui)); color: var(--ink-soft); font-family: 'Nunito'; font-weight: 600; }
        .plan ul { list-style: none; margin: 14px 0 20px; display: grid; gap: 8px; }
        .plan li { font-size: calc(13px * var(--fs-scale-ui)); color: var(--ink-soft); padding-left: 22px; position: relative; }
        .plan li::before { content: '🌱'; position: absolute; left: 0; font-size: 12px; }
        .plan .btn { width: 100%; }

        /* ============================================================
           DEMO DRILLS
           ============================================================ */
        .drill-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
        .drill { border-radius: var(--r-blob-3); display: flex; flex-direction: column; }
        .drill .drill-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
        .drill .skill { display: flex; align-items: center; gap: 10px; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--brand-600); }
        .drill .skill .dot { width: 30px; height: 30px; border-radius: 50%; background: var(--tint-2); display: grid; place-items: center; font-size: 15px; }
        .drill .variant { font-size: calc(11px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft); }
        .drill h4 { font-family: 'Fraunces', serif; font-size: calc(20px * var(--fs-scale-title)); font-weight: 600; margin: 8px 0 4px; }
        .drill .prompt { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); margin-bottom: 18px; }
        .drill .drill-body { flex: 1; }

        /* listening: audio + text answer */
        .audio-bar {
            display: flex; align-items: center; gap: 14px; padding: 14px 18px;
            border-radius: var(--r-pill); background: var(--surface-2); border: 1px solid var(--line); margin-bottom: 14px;
        }
        .play {
            width: 42px; height: 42px; flex-shrink: 0; border-radius: 50%; border: none; cursor: pointer;
            background: linear-gradient(135deg, var(--brand-600), var(--brand-400)); color: var(--on-brand);
            font-size: 15px; display: grid; place-items: center;
        }
        .wavebars { display: flex; align-items: center; gap: 3px; height: 24px; flex: 1; }
        .wavebars i { width: 3px; background: var(--brand-400); border-radius: 2px; animation: wv 1.1s ease-in-out infinite; }
        .wavebars i:nth-child(2n) { animation-delay: -.4s; } .wavebars i:nth-child(3n) { animation-delay: -.7s; }
        @keyframes wv { 0%,100% { height: 6px; } 50% { height: 22px; } }

        /* choice options (reading / speaking) */
        .choices { display: grid; gap: 10px; }
        .choice {
            display: flex; align-items: center; gap: 12px; padding: 14px 18px; cursor: pointer;
            border-radius: 16px 26px 16px 26px; background: var(--surface-2);
            border: 2px solid var(--line-soft); transition: all .2s ease; font-size: calc(15px * var(--fs-scale-body));
        }
        .choice:hover { border-color: var(--brand-400); }
        .choice .mk { width: 22px; height: 22px; flex-shrink: 0; border-radius: 7px; border: 2px solid var(--line); }
        .choice.correct { border-color: var(--sig-green); background: var(--tint); }
        .choice.correct .mk { background: var(--sig-green); border-color: var(--sig-green); }
        .choice.wrong { border-color: var(--sig-red); background: rgba(217,83,79,.08); }
        .choice.wrong .mk { background: var(--sig-red); border-color: var(--sig-red); }

        /* writing: highlighted-word essay */
        .essay { font-size: calc(15px * var(--fs-scale-body)); line-height: 1.9; padding: 16px 18px; background: var(--surface-2); border-radius: var(--r-md); border: 1px solid var(--line-soft); }
        .w-simple { border-bottom: 2px solid var(--brand-200); }
        .w-gold { background: rgba(224,165,58,.22); border-radius: 6px; padding: 1px 5px; font-weight: 700; }
        .upgrade { display: flex; align-items: center; gap: 12px; margin-top: 14px; font-size: calc(15px * var(--fs-scale-body)); }
        .upgrade .from { color: var(--ink-soft); text-decoration: line-through; }
        .upgrade .to { font-weight: 800; color: var(--sig-amber); }

        /* speaking: waveform + two answers */
        .spk-answer { padding: 14px 16px; border-radius: var(--r-md); margin-bottom: 10px; border: 2px solid var(--line-soft); background: var(--surface-2); cursor: pointer; transition: all .2s; }
        .spk-answer:hover { border-color: var(--brand-400); }
        .spk-answer .lab { font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 6px; }
        .spk-answer.bad  .lab { color: var(--sig-red); }
        .spk-answer.good .lab { color: var(--brand-600); }
        .spk-answer p { font-size: calc(14px * var(--fs-scale-body)); }

        .drill-verdict {
            margin-top: 16px; padding: 14px 18px; border-radius: var(--r-md);
            font-size: calc(14px * var(--fs-scale-body)); font-weight: 700; display: none; align-items: center; gap: 10px;
        }
        .drill-verdict.show { display: flex; animation: grow .3s ease; }
        .drill-verdict.pass { background: var(--tint-2); color: var(--brand-600); }
        .drill-verdict.fail { background: rgba(217,83,79,.12); color: var(--sig-red); }

        /* ============================================================
           DIAGNOSTIC REPORT CARD
           ============================================================ */
        .report { border-radius: var(--r-blob-1); }
        .report-head { display: flex; align-items: center; gap: 20px; padding-bottom: 24px; margin-bottom: 24px; border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
        .band-ring {
            width: 92px; height: 92px; flex-shrink: 0; border-radius: 50%;
            display: grid; place-items: center; position: relative;
            background: conic-gradient(var(--brand-600) 0 62%, var(--line-soft) 62% 100%);
        }
        .band-ring::before { content: ''; position: absolute; inset: 8px; border-radius: 50%; background: var(--surface); }
        .band-ring b { position: relative; font-family: 'Fraunces', serif; font-size: calc(26px * var(--fs-scale-title)); color: var(--brand-600); }
        .report-head .rh-txt h3 { font-family: 'Fraunces', serif; font-size: calc(24px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 4px; }
        .report-head .rh-txt p { font-size: calc(15px * var(--fs-scale-body)); color: var(--ink-soft); }

        .priorities { display: grid; gap: 14px; }
        .prio {
            display: flex; gap: 16px; padding: 18px 20px; border-radius: var(--r-md);
            background: var(--surface-2); border-left: 5px solid var(--line); align-items: flex-start;
        }
        .prio.p1 { border-left-color: var(--sig-red); }
        .prio.p2 { border-left-color: var(--sig-amber); }
        .prio.p3 { border-left-color: var(--sig-orange); }
        .prio.p4 { border-left-color: var(--sig-green); }
        .prio .lvl { font-size: 20px; flex-shrink: 0; line-height: 1.4; }
        .prio .pc h5 { font-size: calc(15px * var(--fs-scale-body)); font-weight: 800; margin-bottom: 4px; }
        .prio .pc p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); }
        .prio.muted { opacity: .5; }

        /* diagnostic reaction (positive) */
        .reaction {
            display: flex; align-items: center; gap: 18px; margin-top: 24px;
            padding: 22px 26px; border-radius: var(--r-blob-2);
            background: linear-gradient(135deg, var(--tint), var(--tint-2));
            border: 1px solid var(--line);
        }
        .reaction .emoji { font-size: 40px; animation: breathe 3s ease-in-out infinite; }
        .reaction .rx-txt h4 { font-family: 'Fraunces', serif; font-size: calc(19px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 4px; color: var(--brand-700); }
        .reaction .rx-txt p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); }

        html[data-theme="dark"] .reaction .rx-txt h4 { color: var(--brand-400); }

        /* ============================================================
           POPUP (word / detail)
           ============================================================ */
        .overlay { position: fixed; inset: 0; background: rgba(31,51,17,.5); backdrop-filter: blur(6px); z-index: 90; display: none; }
        .overlay.on { display: block; }
        .popup {
            position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%) scale(.92);
            width: 92%; max-width: 500px; z-index: 91; opacity: 0; pointer-events: none;
            background: var(--surface); border-radius: var(--r-blob-1); box-shadow: var(--shadow-lg);
            transition: opacity .3s ease, transform .3s cubic-bezier(.3,1.3,.5,1); overflow: hidden;
        }
        .popup.on { opacity: 1; pointer-events: auto; transform: translate(-50%,-50%) scale(1); }
        .popup-head { padding: 30px 32px; background: linear-gradient(135deg, var(--tint), var(--tint-2)); border-bottom: 1px solid var(--line); }
        .popup-head .cap { font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--brand-600); margin-bottom: 6px; }
        .popup-head h3 { font-family: 'Fraunces', serif; font-size: calc(26px * var(--fs-scale-title)); font-weight: 600; }
        .popup-body { padding: 28px 32px; }
        .popup-body p { font-size: calc(15px * var(--fs-scale-body)); margin-bottom: 14px; }
        .popup-body .ex { padding: 16px 18px; border-radius: var(--r-md); background: var(--surface-2); font-size: calc(14px * var(--fs-scale-body)); border: 1px solid var(--line-soft); }
        .popup-close { position: absolute; top: 22px; right: 22px; width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--line); background: transparent; color: var(--ink-soft); font-size: 20px; cursor: pointer; transition: all .25s; }
        .popup-close:hover { background: var(--brand-600); color: var(--on-brand); border-color: var(--brand-600); transform: rotate(90deg); }
        .popup-foot { padding: 0 32px 30px; display: flex; gap: 12px; }
        .popup-foot .btn { flex: 1; }

        /* responsive */
        @media (max-width: 760px) {
            .fork, .plans, .drill-grid, .myth-compare { grid-template-columns: 1fr; }
            .myth-compare .myth-arrow { transform: rotate(90deg); justify-self: center; }
            .section-lead h2 { font-size: 32px; }
            /* the fork stacks to one column here, so it towers over the option steps —
               holding the desktop floor would leave dead space under steps 2 and 3.
               Below this width the steps simply take their natural heights. */
            .step-stage { min-height: 0; }
        }

/* ============================================================
   WIZARD ADDITIONS — classes used by the onboarding screens
   that the design-system showcase did not need. Kept here so
   organic.css stays the single stylesheet for the flow.
   ============================================================ */

/* Universal border-box reset — present in design-system.html but dropped when the
   tokens/components were extracted here. Without it, borders + padding are ADDED to
   width, so a plain .card (1px border) and the .result-panel (1px + 6px accent border)
   compute different outer widths and don't align. Restore it so every card/panel in a
   screen shares one width. */
*, *::before, *::after { box-sizing: border-box; }

/* A screen is a single vertical stack: one consistent gap between every card/panel/
   button, so spacing never depends on ad-hoc per-element margins. */
.wizard-back { margin-bottom: 16px; }
.screen { animation: grow .5s ease; display: flex; flex-direction: column; gap: 18px; }
/* the lead has its own larger bottom margin; drop the stack gap under it to avoid doubling */
.screen > .screen-lead { margin-bottom: 0; }
/* a reveal wrapper (#wt-out / #pc-out / read-ahead's in-card reveal) is the same
   single vertical stack, so panel · recap · next button share the screen's rhythm.
   Collapses while empty so it adds no phantom gap before the user answers. */
.reveal-out { display: flex; flex-direction: column; gap: 18px; }
.reveal-out:empty { display: none; }
.screen-lead { margin: 8px 0 28px; }
.screen-lead .kicker {
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
    color: var(--brand-600); margin-bottom: 10px;
}
.screen-lead h2 { font-family: 'Fraunces', serif; font-size: calc(34px * var(--fs-scale-title)); font-weight: 600; line-height: 1.12; margin-bottom: 10px; letter-spacing: -.02em; }
.screen-lead p { font-size: calc(17px * var(--fs-scale-body)); color: var(--ink-soft);   margin: 20px 120px 21px 0px;}
.screen-lead p.prompt {
    margin-top: 14px; font-size: calc(24px * var(--fs-scale-title)); font-weight: 700;
    color: var(--brand-600); letter-spacing: -.01em;
}
.muted { color: var(--ink-soft); }
.good { color: var(--brand-600); }
.bad  { color: var(--sig-red); }

/* stacked step cards inside a screen */
.stack { display: grid; gap: 18px; }

/* read-ahead: the 3 tappable questions sit in a centred, comfortably-wide reading column,
   separate from the header/timer and "Check answers" button (which stay left-aligned). */
.ra-q-list { max-width: 720px; margin: 50px auto; }
.ra-q { font-size: 1.3rem; }

/* read-ahead: tappable keyword spans + countdown timer */
.kw {
    display: inline-block; padding: 2px 6px; margin: 1px 0; border-radius: 8px;
    cursor: pointer; transition: background .15s ease, color .15s ease;
}
.kw:hover { background: var(--tint); }
.kw.on { background: var(--brand-600); color: var(--on-brand); font-weight: 700; }
/* after scoring, spans lock (no more toggling) */
.kw.locked { cursor: default; }
.kw.locked:hover { background: transparent; }
.kw.on.locked:hover { background: var(--brand-600); }
/* transparent reveal: ground-truth keyword = green underline; wrong pick = red strikethrough.
   Uses box-shadow / line-through so it composes on top of the .on selection background. */
.kw.gt {
    text-decoration: underline; text-decoration-color: var(--sig-green);
    text-decoration-thickness: 3px; text-underline-offset: 3px;
}
.kw.on.gt { text-decoration-color: var(--on-brand); } /* keep the underline visible on the green pill */
.kw.miss-pick {
    text-decoration: line-through; text-decoration-color: var(--sig-red);
    text-decoration-thickness: 3px; color: var(--sig-red);
}

/* ------------------------------------------------------------------
   read-ahead intro: the "highlighter sweep" worked example.

   A marker pen strokes left-to-right across a demo question. Each keyword fills with
   its ROLE colour and its role label flips up in the pen's wake; fillers stay dim.
   The four roles are the lesson (question word / subject / action / catch) — they live
   ONLY in this intro. The drill's own reveal below stays green-underline / red-strike,
   one undifferentiated "keyword" category (see .kw.gt / .kw.miss-pick above).

   Display-only: runs once on render, no replay control, never gates the CTA.
   ------------------------------------------------------------------ */

/* role palette — hue-separated but kept in the DS's muted, natural register.
   `question` deliberately reuses the brand green: it is the one role every question has.
   Each role carries a matching `-fill`: the translucent stripe the sweep paints behind
   the word. Both must be themed — a light-theme fill under dark-theme text is invisible. */
:root {
    --role-q:    #5a8a3a;  /* question word — the answer type */
    --role-subj: #2f6f8f;  /* subject       — what it's about */
    --role-act:  #b5731f;  /* action        — what happens    */
    --role-trap: #b03a5b;  /* catch         — the distractor filter */
    --role-q-fill:    rgba(90, 138, 58, .16);
    --role-subj-fill: rgba(47, 111, 143, .16);
    --role-act-fill:  rgba(181, 115, 31, .18);
    --role-trap-fill: rgba(176, 58, 91, .16);
}
html[data-theme="dark"] {
    --role-q:    #8bb36a;
    --role-subj: #6fb0cf;
    --role-act:  #dda155;
    --role-trap: #dd7a97;
    --role-q-fill:    rgba(139, 179, 106, .20);
    --role-subj-fill: rgba(111, 176, 207, .20);
    --role-act-fill:  rgba(221, 161, 85, .22);
    --role-trap-fill: rgba(221, 122, 151, .20);
}

/* the inset stage a demo sits on, inside a strategy card (.stage is the generic
   alias — the Reading screens' diagrams share the exact same treatment) */
.ra-stage, .stage {
    background: var(--surface-2); border: 1px solid var(--line-soft);
    border-radius: var(--r-md); padding: 34px 28px 26px; margin: 22px 0 6px;
    overflow-x: auto;
}
/* the sentence: one row of chunks, centred, never wrapped (the stage scrolls instead) */
.ra-sweep {
    display: flex; align-items: flex-end; justify-content: center; gap: 2px;
    flex-wrap: nowrap; width: max-content; margin: 0 auto;
}
.ra-sweep .chunk { display: flex; flex-direction: column; align-items: center; padding: 0 5px; }
.ra-sweep .words { display: flex; gap: 2px; }

/* the role label above a keyword chunk — flips up as the pen passes.
   Filler chunks keep an invisible label so the sentence never reflows mid-sweep. */
.ra-sweep .lbl {
    font-size: calc(10px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
    margin-bottom: 6px; white-space: nowrap;
    opacity: 0; transform: translateY(6px);
    transition: opacity .3s ease, transform .3s ease;
}
.ra-sweep .chunk.plain .lbl { visibility: hidden; }
.ra-sweep .chunk.lit .lbl { opacity: 1; transform: translateY(0); }

.ra-sweep .w { font-size: 21px; padding: 2px 5px; white-space: nowrap; }
.ra-sweep .w.filler { color: var(--ink-soft); opacity: .38; }

/* THE SWEEP: a role-tinted stripe wipes across each keyword, left to right. Grown from
   0% to 100% background width so it reads as a marker stroke, not a fade. Per-word
   transition-delays are assigned in read_ahead.js (they encode the pen's travel). */
.ra-sweep .w.key {
    font-weight: 800; border-radius: 6px;
    background-repeat: no-repeat; background-position: 0 100%; background-size: 0% 100%;
    transition: background-size .34s cubic-bezier(.65, 0, .35, 1);
}
.ra-sweep.run .w.key { background-size: 100% 100%; }

.ra-sweep .w.role-question { color: var(--role-q);    background-image: linear-gradient(var(--role-q-fill),    var(--role-q-fill)); }
.ra-sweep .w.role-subject  { color: var(--role-subj); background-image: linear-gradient(var(--role-subj-fill), var(--role-subj-fill)); }
.ra-sweep .w.role-action   { color: var(--role-act);  background-image: linear-gradient(var(--role-act-fill),  var(--role-act-fill)); }
.ra-sweep .w.role-catch    { color: var(--role-trap); background-image: linear-gradient(var(--role-trap-fill), var(--role-trap-fill)); }
.ra-sweep .lbl.role-question { color: var(--role-q); }
.ra-sweep .lbl.role-subject  { color: var(--role-subj); }
.ra-sweep .lbl.role-action   { color: var(--role-act); }
.ra-sweep .lbl.role-catch    { color: var(--role-trap); }

/* the four-role key, under the sentence */
.ra-roles {
    display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: center;
    margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line-soft);
    font-size: calc(12.5px * var(--fs-scale-ui)); color: var(--ink-soft);
}
.ra-roles .ri { display: inline-flex; align-items: center; gap: 7px; }
.ra-roles .dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.ra-roles b { font-weight: 800; }

/* a user who asked not to be animated gets the finished diagram, instantly */
@media (prefers-reduced-motion: reduce) {
    .ra-sweep .w.key, .ra-sweep .lbl { transition: none; }
}
@media (max-width: 720px) {
    .ra-stage { padding: 28px 14px 22px; }
    .ra-sweep .w { font-size: 18px; }
}

/* read-ahead intro: the task as 3 numbered mini-steps */
.mini-steps { list-style: none; padding: 0; margin: 14px 0 2px; display: grid; gap: 10px; counter-reset: step; }
.mini-steps li { display: flex; align-items: center; gap: 10px; font-size: calc(15px * var(--fs-scale-body)); color: var(--ink-soft); counter-increment: step; }
.mini-steps li::before {
    content: counter(step); flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center; font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800;
    background: var(--tint-2); color: var(--brand-600);
}

/* read-ahead drill: question number, so result "Why" rows (Q1/Q2/Q3) can point back */
.ra-qnum { font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; color: var(--brand-600); margin-right: 6px; }

/* read-ahead reveal: colour legend with live samples of the three kw states */
.kw-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    font-size: calc(13px * var(--fs-scale-ui));
    color: var(--ink-soft);
    margin: 45px auto;
    width: fit-content;
    background-color: whitesmoke;
    border-radius: 10px;
}

.kw-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 15px 20px;
}

.kw-legend .kw {
    cursor: default;
    padding: 1px 5px;
    font-size: calc(13px * var(--fs-scale-ui));
}

/* predict-context reveal: the spoken transcript replayed with giveaway words lit up
   in their original sentence context, instead of a detached "giveaway words:" list.
   .hit works on both pass and fail — on fail it shows what should have been caught. */
.transcript-replay {
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: var(--r-sm);
    padding: 18px 20px; font-family: 'Fraunces', serif; font-size: calc(17px * var(--fs-scale-body)); line-height: 1.65; color: var(--ink);
}
.transcript-replay .hit {
    background: var(--tint-2); color: var(--brand-700); font-weight: 700; border-radius: 5px;
    padding: 1px 4px; box-shadow: inset 0 -2px 0 var(--sig-green);
}
html[data-theme="dark"] .transcript-replay .hit { color: var(--brand-400); }
.answer-chip {
    display: inline-flex; align-items: center; gap: 8px; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 800;
    color: var(--brand-700); background: var(--tint); border-radius: 20px; padding: 6px 14px; width: fit-content;
}
html[data-theme="dark"] .answer-chip { color: var(--brand-400); }

/* predict-context: a 3rd ("partial") state for choices + verdicts (amber) */
.choice.partial { border-color: var(--sig-amber); background: rgba(224,165,58,.10); }
.choice.partial .mk { background: var(--sig-amber); border-color: var(--sig-amber); }
.drill-verdict.warn { background: rgba(224,165,58,.14); color: var(--sig-amber); }
/* drill choices are buttons laid out like DS .choice rows (predict-context, exact-word-trap).
   color:inherit matters: a disabled <button> otherwise falls back to the UA's GrayText,
   which is illegible on the dark theme's surfaces. */
.choice.as-btn { width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer; }
.choice[disabled] { cursor: default; }

/* two independent signal badges (Speed | Accuracy) */
.badge-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
.signal-badge {
    display: flex; flex-direction: column; gap: 2px;
    padding: 10px 18px; border-radius: 16px 26px 16px 26px; border: 2px solid var(--line);
    background: var(--surface-2);
}
.signal-badge.ok { border-color: var(--sig-green); background: var(--tint); }
.signal-badge.no { border-color: var(--sig-red); background: rgba(217,83,79,.10); }
.signal-badge .sb-label {
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
}
.signal-badge .sb-value { font-weight: 800; font-size: calc(15px * var(--fs-scale-ui)); }
.signal-badge.ok .sb-value { color: var(--brand-600); }
.signal-badge.no .sb-value { color: var(--sig-red); }
/* optional third line: the badge's own explanation, in the same neutral tone regardless
   of ok/no state (kept out of .sb-value's pass/fail colouring on purpose). */
.signal-badge .sb-note { font-size: calc(14px * var(--fs-scale-body)); font-weight: 400; color: var(--ink-soft); line-height: 1.5; }

/* read-ahead: badges stack one per row (not side-by-side) now that each carries a note */
#ra-drill .badge-row { display: block; }
#ra-drill .signal-badge { margin: 8px 0; width: fit-content;}
.timer { font-family: 'Fraunces', serif; font-weight: 600; color: var(--sig-red); }

/* verdict/reaction spacing when injected mid-screen */
.drill-verdict.inline { margin-top: 18px; display: flex; }

/* enforced-UI shake for the word-limit violation */
@keyframes shake {
    0%,100% { transform: translateX(0); }
    20%,60% { transform: translateX(-7px); }
    40%,80% { transform: translateX(7px); }
}
.shake { animation: shake .4s ease; border-color: var(--sig-red) !important; }

/* wavebars need explicit heights per bar when animated */
.audio-bar.playing .wavebars i { animation-play-state: running; }
.wavebars i { animation-play-state: paused; }

/* Spinner for async loads. Sized in `em`, NOT px: it always sits inline beside a label (a
   status line on two drills, a button label on the third), and at a fixed 14px with a 2px
   ring it read as a thin sliver next to 16px body text — too small to register as the "we
   are working" signal on the screens where the wait runs several seconds. em also means it
   tracks the desktop type scale for free (the scale is applied to the parent it inherits
   from) and needs no per-call-site size override.
   The track is mixed FROM --brand-600 rather than using --line, which was too pale to close
   the circle: with only the arc visible the thing read as a stray dot, not a ring. Mixing
   from a themed token also keeps the track correct in dark mode with no override. */
.spinner {
    display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -.22em;
    border: .155em solid color-mix(in srgb, var(--brand-600) 26%, transparent);
    border-top-color: var(--brand-600);
    border-radius: 50%; animation: spin .7s linear infinite;
}
/* Inside a button the brand arc is INVISIBLE: .btn-primary's fill is literally
   linear-gradient(var(--brand-600), var(--brand-400)), so the arc is the same green as the
   surface behind it (the layer-split drill's "The examiner is reading your answer…" button
   has been spinning an unseeable ring). In a button the ring tracks the LABEL colour, which
   is right for both variants — white on the filled primary, brand green on the ghost. */
.btn .spinner {
    border-color: color-mix(in srgb, currentColor 32%, transparent);
    border-top-color: currentColor;
}
/* Reduced motion: keep the spin (it is the only signal that the wait is still alive) but
   slow it well below the rate that reads as a flicker. */
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 1.9s; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================
   RESULT PANEL — the single "here's how you did" container that
   every drill reveal lives inside. Fixes two problems the loose
   sibling-stack reveals had: (1) too pale / merges into the page,
   (2) verdict + evidence + coaching read as disconnected blocks.
   One bordered surface, a bold colored accent bar (green pass /
   red fail / amber partial), and clear internal hierarchy:
   .rp-verdict (header) · .rp-body (evidence) · .rp-coach (footer).
   ============================================================ */
.result-panel {
    overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 6px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow);
    animation: grow .35s ease;
}
.result-panel.pass { border-left-color: var(--sig-green); }
.result-panel.fail { border-left-color: var(--sig-red); }
.result-panel.warn { border-left-color: var(--sig-amber); }

/* header row — the verdict, given real weight via a tinted fill */
.rp-verdict {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 18px 24px; font-size: calc(15px * var(--fs-scale-body)); line-height: 1.5;
    border-bottom: 1px solid var(--line-soft);
}
.rp-verdict .rp-icon {
    flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center; font-weight: 900; font-size: calc(15px * var(--fs-scale-ui));
    color: var(--on-brand);
}
.result-panel.pass .rp-verdict { background: var(--tint-2); }
.result-panel.fail .rp-verdict { background: rgba(217,83,79,.12); }
.result-panel.warn .rp-verdict { background: rgba(224,165,58,.14); }
.result-panel.pass .rp-icon { background: var(--sig-green); }
.result-panel.fail .rp-icon { background: var(--sig-red); }
.result-panel.warn .rp-icon { background: var(--sig-amber); }
.rp-verdict .rp-vtext b { font-weight: 800; }
.result-panel.pass .rp-verdict .rp-vtext b { color: var(--brand-700); }
.result-panel.fail .rp-verdict .rp-vtext b { color: var(--sig-red); }
.result-panel.warn .rp-verdict .rp-vtext b { color: var(--sig-amber); }
html[data-theme="dark"] .result-panel.pass .rp-verdict .rp-vtext b { color: var(--brand-400); }

/* body — the evidence (transcript, giveaways, badges, summary) */
.rp-body { padding: 20px 24px; display: grid; gap: 14px; }

/* per-question "Why" callouts (Read-Ahead) — a stack of green-chip rows so the evidence
   reads as deliberate coaching, not loose body text. Each row is a Q-chip + its question,
   reusing the intro sweep's own chunk/lbl/words markup (.ra-sweep) so the role colours AND
   the role labels ("Subject", "Action", …) look identical to the lesson above — just static
   (no stagger) and WRAPPING instead of scrolling, since real questions run longer than the
   demo. The shared roleLegend() above this stack still carries the colour → job mapping once. */
.rp-why { display: grid; gap: 10px; }
.rp-why .why-row {
    padding: 12px 16px; border-radius: var(--r-sm);
    background: var(--surface-2); border-left: 3px solid var(--sig-green);
}
.rp-why .why-head { display: flex; align-items: flex-start; gap: 10px; }
.rp-why .why-chip {
    flex-shrink: 0; margin-top: 1px; padding: 3px 10px; border-radius: 20px;
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    background: var(--tint-2); color: var(--brand-600);
}
/* override the intro stage's single-line, centred, horizontal-scroll layout: the why-row
   sweep wraps like a paragraph and starts flush left, with no stage box around it. */
.rp-why .why-q.ra-sweep {
    flex-wrap: wrap; justify-content: flex-start; width: auto; margin: 0; row-gap: 12px;
}
.rp-why .why-q .w { font-size: calc(14px * var(--fs-scale-body)); }
/* the shared role legend, reused here from .ra-roles (no top border/stage padding needed
   between the h4 and the first "Why" row) */
.rp-body > .ra-roles { margin-top: -4px; padding-top: 0; border-top: none; }
.rp-body > h4 {
    font-family: 'Fraunces', serif; font-size: calc(18px * var(--fs-scale-title)); font-weight: 600;
    margin-bottom: -4px;
}
.rp-body .badge-row { margin: 0; }

/* footer — the coaching note, visually distinct inside the same panel */
.rp-coach {
    display: flex; align-items: center; gap: 16px;
    padding: 18px 24px; margin: 0;
    background: linear-gradient(135deg, var(--tint), var(--tint-2));
    border-top: 1px solid var(--line-soft);
}
.rp-coach .emoji { font-size: 34px; flex-shrink: 0; animation: breathe 3s ease-in-out infinite; }
.rp-coach .rx-txt h4 { font-family: 'Fraunces', serif; font-size: calc(18px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 2px; color: var(--brand-700); }
.rp-coach .rx-txt p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); }
html[data-theme="dark"] .rp-coach .rx-txt h4 { color: var(--brand-400); }

/* ============================================================
   READING BLOCK — screens reading-time, reading-guideline,
   exact-word-trap (after the Listening drills).
   ============================================================ */

/* an amber advisory card (Reading tip 2: no answer-transfer time) */
.warn-card {
    display: flex; gap: 16px; align-items: flex-start;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-left: 6px solid var(--sig-amber); border-radius: var(--r-md);
    padding: 25px 35px; box-shadow: var(--shadow);
}

.warn-card h4 { font-family: 'Fraunces', serif; font-size: calc(18px * var(--fs-scale-title)); font-weight: 600; margin: 0; }
.warn-card p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.55; }
.warn-card b { font-weight: 800; color: var(--ink); }

/* ------------------------------------------------------------------
   reading-time: the 60-minute bar that re-budgets itself.
   Starts as three equal, undifferentiated slots (the 20/20/20 myth);
   adding .morphed to .rt-anim brings the new widths (set inline by JS
   so flex-grow animates without !important) and the green ramp, and
   crossfades the start-note for the move-note. Display-only: it runs
   once on render and never gates the CTA. Reduced motion lands on the
   morphed state instantly (the JS adds .morphed with no hold).
   ------------------------------------------------------------------ */
.rt-bar { display: flex; gap: 4px; height: 58px; }
.rt-seg {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    border-radius: 12px; line-height: 1.25; min-width: 0;
    background: var(--tint); border: 1.5px solid var(--line-soft); color: var(--ink-soft);
    transition: flex-grow 1s cubic-bezier(.65, 0, .35, 1),
                background .6s ease, color .6s ease, border-color .6s ease;
}
.rt-seg b { font-size: 15px; font-weight: 800; white-space: nowrap; }
.rt-seg span { font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 700; letter-spacing: .04em; opacity: .85; white-space: nowrap; }
/* the ramp darkens as the passages get harder; brand-200/400 + brand-900 text and the
   600→700 gradient + white text hold enough contrast in BOTH themes (the ramp colours
   are theme-constant; dark's --brand-600 #7fb04e→#3f6b23 under white still reads) */
.rt-anim.morphed .rt-s1 { background: var(--brand-200); border-color: transparent; color: var(--brand-900); }
.rt-anim.morphed .rt-s2 { background: var(--brand-400); border-color: transparent; color: var(--brand-900); }
.rt-anim.morphed .rt-s3 { background: linear-gradient(135deg, var(--brand-600), var(--brand-700)); border-color: transparent; color: #ffffff; }
/* the two captions share one grid cell and crossfade, so the morph never reflows */
.rt-notes { display: grid; margin-top: 16px; }
.rt-notes > p { grid-area: 1 / 1; text-align: center; font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); }
.rt-start-note { transition: opacity .35s ease; }
.rt-move-note { opacity: 0; transform: translateY(6px); transition: opacity .45s ease .25s, transform .45s ease .25s; }
.rt-move-note b { color: var(--brand-600); font-weight: 800; }
.rt-anim.morphed .rt-start-note { opacity: 0; }
.rt-anim.morphed .rt-move-note { opacity: 1; transform: none; }

/* ------------------------------------------------------------------
   reading-guideline: the skim in action. A question card beside a
   skeleton passage; a scan bar (.scanner) slides down the lines,
   skimmed lines dim (.passed), and the answer line lights up (.found)
   MID-paragraph — quietly disproving the first/last-sentence trick.
   Display-only, same contract as the reading-time morph.
   ------------------------------------------------------------------ */
.rg-wrap { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: start; }
.q-sticky {
    background: var(--surface); border: 1.5px solid var(--brand-400); border-radius: var(--r-sm);
    padding: 12px 16px; max-width: 210px; font-size: calc(13.5px * var(--fs-scale-body)); line-height: 1.45;
    box-shadow: 0 6px 18px rgba(90, 138, 58, .12);
}
html[data-theme="dark"] .q-sticky { box-shadow: 0 6px 18px rgba(0, 0, 0, .40); }
.q-sticky .q-tag {
    font-size: calc(10px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
    color: var(--brand-600); display: block; margin-bottom: 4px;
}
.rg-passage { display: flex; flex-direction: column; gap: 8px; position: relative; }
.pline {
    height: 12px; border-radius: 6px; background: var(--line-soft);
    transition: opacity .4s ease, background .4s ease;
    position: relative; overflow: hidden;
}
.pline.short { width: 62%; }
.pline.passed { opacity: .35; }
.pline.found {
    height: auto; min-height: 12px; background: var(--tint-2); opacity: 1;
    padding: 6px 12px; font-size: calc(13px * var(--fs-scale-body)); line-height: 1.5; color: var(--ink);
}
/* the answer sentence stays invisible until found — its skeleton line is only 12px tall */
.found-txt { opacity: 0; transition: opacity .5s ease .15s; }
.pline.found .found-txt.show { opacity: 1; }
.found-txt b { color: var(--brand-600); font-weight: 800; }
.scanner {
    position: absolute; left: -8px; right: -8px; height: 18px; border-radius: 9px;
    background: var(--tint-2); border: 1.5px solid var(--brand-400);
    transition: top .5s cubic-bezier(.65, 0, .35, 1), opacity .3s ease;
    opacity: 0; pointer-events: none;
}
.scanner.on { opacity: 1; }
.rg-cap { margin-top: 16px; font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); text-align: center; min-height: 1.7em; }
.rg-cap b { color: var(--ink); font-weight: 800; }

/* the two red trap callouts under the guideline demo. .trap-reveal is a collapsed wrapper:
   it starts at 0 height (grid-template-rows 0fr, child clipped via min-height:0 + overflow)
   so the trap section takes no scroll space and the "Got it" button sits flush under the
   theory card — no dead gap that reads as "end of page". armTrapReveal() in
   reading_guideline.js adds .in-view once that button scrolls into view: the wrapper unfolds
   and the cards fade/rise in, card 2 lagging behind card 1 (transition-delay) so they appear
   one after another. The JS then auto-scrolls the button back into frame. */
.trap-reveal {
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows .5s ease;
}
.trap-reveal > .trap-grid { overflow: hidden; min-height: 0; }
.trap-reveal.in-view { grid-template-rows: 1fr; }

.trap-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.trap-card {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-left: 6px solid var(--sig-red); border-radius: var(--r-md);
    padding: 20px 22px; box-shadow: var(--shadow);
}
/* the hidden-until-revealed state is scoped to the reveal wrapper — .trap-card is reused by
   other screens (writing Task 1, vocab-myth) that render it plainly with no wrapper. */
.trap-reveal .trap-card {
    opacity: 0; transform: translateY(18px);
    transition: opacity .5s ease, transform .5s ease;
}
.trap-reveal.in-view .trap-card { opacity: 1; transform: translateY(0); }
.trap-reveal.in-view .trap-card:nth-child(2) { transition-delay: .35s; }
@media (prefers-reduced-motion: reduce) {
    .trap-reveal { grid-template-rows: 1fr; transition: none; }
    .trap-reveal .trap-card { opacity: 1; transform: none; transition: none; }
}
.trap-card .trap-tag {
    display: inline-block; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em;
    text-transform: uppercase; color: var(--sig-red); background: rgba(217, 83, 79, .12);
    padding: 3px 10px; border-radius: 20px; margin-bottom: 10px;
}
.trap-card h4 { font-family: 'Fraunces', serif; font-size: calc(17px * var(--fs-scale-title)); font-weight: 600; margin-bottom: 6px; }
.trap-card p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.55; }
.trap-card .trap-fix { margin-top: 10px; font-size: calc(13.5px * var(--fs-scale-body)); color: var(--ink); }
.trap-card .trap-fix b { color: var(--brand-600); font-weight: 800; }
.next-tease { font-size: calc(13px * var(--fs-scale-body)); color: var(--ink-soft); font-style: italic; }

/* ------------------------------------------------------------------
   exact-word-trap: round header + the marked-passage reveal. The
   reveal re-renders the whole mini-passage as evidence: bait words
   (the question's own words, planted in the decoy) struck in red,
   the answering sentence's paraphrases lit in green. .hit/.bait are
   scoped under .passage-replay — .transcript-replay owns its own .hit.
   ------------------------------------------------------------------ */
.round-tag {
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
    color: var(--brand-600); margin-bottom: 8px;
}
.the-q { font-family: 'Fraunces', serif; font-size: calc(19px * var(--fs-scale-title)); font-weight: 600; line-height: 1.4; margin-bottom: 16px; }
.passage-replay {
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: var(--r-sm);
    padding: 6px 0; font-family: 'Fraunces', serif; font-size: calc(16px * var(--fs-scale-body)); line-height: 1.65; color: var(--ink);
}
.pr-sent { padding: 8px 20px; border-left: 4px solid transparent; }
.pr-sent.is-answer { border-left-color: var(--sig-green); background: var(--tint); }
.pr-sent.is-decoy  { border-left-color: var(--sig-red); }
.pr-sent .s-tag {
    display: inline-block; font-family: 'Nunito', system-ui, sans-serif;
    font-size: calc(10px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    padding: 2px 9px; border-radius: 20px; margin-right: 8px; vertical-align: 2px;
}
.pr-sent.is-answer .s-tag { background: var(--tint-2); color: var(--brand-700); }
.pr-sent.is-decoy  .s-tag { background: rgba(217, 83, 79, .12); color: var(--sig-red); }
html[data-theme="dark"] .pr-sent.is-answer .s-tag { color: var(--brand-400); }
.passage-replay .hit {
    background: var(--tint-2); color: var(--brand-700); font-weight: 700; border-radius: 5px;
    padding: 1px 4px; box-shadow: inset 0 -2px 0 var(--sig-green);
}
html[data-theme="dark"] .passage-replay .hit { color: var(--brand-400); }
.passage-replay .bait {
    color: var(--sig-red); font-weight: 700; border-radius: 5px; padding: 1px 4px;
    background: rgba(217, 83, 79, .10); box-shadow: inset 0 -2px 0 var(--sig-red);
}
.q-echo { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.6; }
.q-echo .qw { font-weight: 800; color: var(--ink); border-bottom: 2px dotted var(--sig-red); }
.replay-legend { display: flex; flex-wrap: wrap; gap: 8px 20px; font-size: calc(12.5px * var(--fs-scale-ui)); color: var(--ink-soft); }
.replay-legend .li { display: inline-flex; align-items: center; gap: 6px; }
.replay-legend .sw { width: 11px; height: 11px; border-radius: 4px; flex-shrink: 0; }
.replay-legend .sw.g { background: var(--sig-green); }
.replay-legend .sw.r { background: var(--sig-red); }

@media (prefers-reduced-motion: reduce) {
    .rt-seg, .rt-start-note, .rt-move-note, .scanner, .pline, .found-txt { transition: none !important; }
}
@media (max-width: 640px) {
    .rg-wrap { grid-template-columns: 1fr; }
    .trap-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   WRITING BLOCK — screens writing-vocab-myth, writing-task1,
   writing-structure, writing-prewriting, writing-layer-drill.
   Ported from design_system/writing-*.html (chosen variants).
   Reuses existing .card/.stage/.warn-card/.trap-card/.btn* verbatim.
   ============================================================ */

/* ---- shared: examiner pull-quote + motto strip (vocab-myth) ---- */
.exam-quote {
    position: relative; padding: 22px 26px 20px 30px;
    background: var(--surface-2); border-left: 5px solid var(--brand-400);
    border-radius: var(--r-sm); font-family: 'Fraunces', serif;
    font-size: calc(18px * var(--fs-scale-body)); line-height: 1.55; color: var(--ink);
}
.exam-quote em { color: var(--brand-700); font-style: italic; font-weight: 600; }
html[data-theme="dark"] .exam-quote em { color: var(--brand-400); }
.exam-quote .who {
    display: block; margin-top: 10px; font-family: 'Nunito', system-ui, sans-serif;
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
}
.motto {
    display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
    padding: 14px 20px; border-radius: var(--r-pill); text-align: center;
    background: linear-gradient(135deg, var(--tint), var(--tint-2)); border: 1px solid var(--line);
    font-family: 'Fraunces', serif; font-size: calc(19px * var(--fs-scale-title)); font-weight: 600;
}
.motto b { color: var(--brand-600); font-weight: 600; }

/* ---- vocab-myth: the sentence face-off (animated) ---- */
.faceoff { display: grid; gap: 16px; }
.fo-sent {
    position: relative; padding: 18px 20px 16px; border-radius: var(--r-sm);
    background: var(--surface); border: 1.5px solid var(--line-soft);
    font-family: 'Fraunces', serif; font-size: calc(16.5px * var(--fs-scale-body)); line-height: 1.7;
}
.fo-sent .fo-lbl {
    display: inline-block; font-family: 'Nunito', system-ui, sans-serif;
    font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
    padding: 3px 10px; border-radius: 20px; margin-bottom: 10px;
}
.fo-sent.fancy .fo-lbl { background: rgba(224, 165, 58, .18); color: var(--sig-amber); }
.fo-sent.plain .fo-lbl { background: var(--tint-2); color: var(--brand-600); }
.fo-sent .txt { display: block; }
.fo-sent .flex-word { background: rgba(224, 165, 58, .22); border-radius: 6px; padding: 1px 5px; font-weight: 700; }
.fo-sent .err { border-radius: 5px; padding: 1px 3px; transition: background .4s ease, color .4s ease, text-decoration-color .4s ease; }
.fo-sent.marked .err {
    color: var(--sig-red); background: rgba(217, 83, 79, .10);
    text-decoration: underline wavy var(--sig-red) 2px; text-underline-offset: 3px;
}
.fo-sent .band-chip {
    position: absolute; top: 14px; right: 16px; padding: 4px 12px; border-radius: 20px;
    font-family: 'Nunito', system-ui, sans-serif; font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800;
    opacity: 0; transform: scale(.7); transition: opacity .35s ease, transform .35s cubic-bezier(.4, 1.5, .5, 1);
}
.fo-sent.scored .band-chip { opacity: 1; transform: scale(1); }
.fo-sent.fancy .band-chip { background: rgba(217, 83, 79, .13); color: var(--sig-red); }
.fo-sent.plain .band-chip { background: var(--tint-2); color: var(--brand-600); }
.fo-sent.plain.scored { border-color: var(--brand-400); box-shadow: 0 6px 18px rgba(90, 138, 58, .12); }
.fo-sent .fo-note {
    display: block; margin-top: 8px; font-family: 'Nunito', system-ui, sans-serif;
    font-size: calc(12.5px * var(--fs-scale-body)); color: var(--ink-soft); opacity: 0; transition: opacity .4s ease;
}
.fo-sent.scored .fo-note { opacity: 1; }
.fo-cap { margin-top: 14px; font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); text-align: center; min-height: 1.7em; }
.fo-cap b { color: var(--ink); font-weight: 800; }

/* ---- task1: the GT/Academic track switcher (sliding pill) ---- */
.screen[data-track="gt"] .when-ac { display: none !important; }
.screen[data-track="ac"] .when-gt { display: none !important; }
.sw-seg { display: inline-flex; align-items: center; gap: 12px; }
.sw-seg .ts-lbl {
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
    color: var(--ink-soft); padding-left: 2px;
}
.sw-seg .seg {
    position: relative; display: inline-flex; padding: 5px;
    border: 1px solid var(--line); border-radius: var(--r-pill);
    background: var(--surface-2); box-shadow: var(--shadow);
}
.sw-seg .seg::before {
    content: ''; position: absolute; top: 5px; bottom: 5px; left: 5px; width: calc(50% - 5px);
    border-radius: var(--r-pill); background: var(--brand-600);
    box-shadow: 0 4px 12px rgba(90, 138, 58, .30);
    transition: transform .32s cubic-bezier(.4, 1.2, .4, 1);
}
.screen[data-track="ac"] .sw-seg .seg::before { transform: translateX(100%); }
.sw-seg .seg button {
    position: relative; z-index: 1; flex: 1 0 auto; min-width: 118px;
    font: inherit; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 700; padding: 8px 20px; border-radius: var(--r-pill);
    cursor: pointer; border: none; background: transparent; color: var(--ink-soft);
    transition: color .28s ease; text-align: center;
}
.screen[data-track="gt"] .sw-seg button.t-gt,
.screen[data-track="ac"] .sw-seg button.t-ac { color: var(--on-brand); }
@media (max-width: 600px) {
    .sw-seg { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
    .sw-seg .seg { width: 100%; } .sw-seg .seg button { flex: 1; min-width: 0; }
}

/* ---- task1 · GT: the tone table ---- */
.tone-grid {
    display: grid; grid-template-columns: auto 1fr 1fr; gap: 0;
    border: 1px solid var(--line-soft); border-radius: var(--r-sm); overflow: hidden; font-size: calc(13.5px * var(--fs-scale-body));
}
.tone-grid > div { padding: 10px 14px; border-bottom: 1px solid var(--line-soft); background: var(--surface); }
.tone-grid > div:nth-last-child(-n+3) { border-bottom: none; }
.tone-grid .tg-h { background: var(--surface-2); font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.tone-grid .tg-h.f { color: var(--brand-600); }
.tone-grid .tg-h.i { color: var(--sig-orange); }
.tone-grid .tg-lbl { background: var(--surface-2); font-size: calc(11.5px * var(--fs-scale-ui)); font-weight: 800; color: var(--ink-soft); }
.tone-grid .ex { font-family: 'Fraunces', serif; font-style: italic; }
@media (max-width: 600px) { .tone-grid { grid-template-columns: 1fr; } .tone-grid .tg-h.blank { display: none; } }

/* ---- task1 · AC: chart skeleton + two openings + paraphrase pairs ---- */
.chart-demo { display: flex; gap: 20px; align-items: flex-end; }
.mini-chart { display: flex; gap: 8px; align-items: flex-end; height: 90px; flex-shrink: 0; padding: 0 4px; }
.mini-chart i { width: 22px; border-radius: 6px 6px 0 0; background: var(--brand-400); opacity: .85; }
.mini-chart i:nth-child(1) { height: 30%; } .mini-chart i:nth-child(2) { height: 45%; }
.mini-chart i:nth-child(3) { height: 62%; } .mini-chart i:nth-child(4) { height: 80%; }
.mini-chart i:nth-child(5) { height: 95%; background: var(--brand-600); }
.openings { display: grid; gap: 10px; flex: 1; min-width: 0; }
.opening { border-radius: var(--r-sm); padding: 12px 16px; font-family: 'Fraunces', serif; font-size: calc(14.5px * var(--fs-scale-body)); line-height: 1.6; border: 1.5px solid var(--line-soft); background: var(--surface); }
.opening .o-lbl {
    display: inline-block; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(10px * var(--fs-scale-ui)); font-weight: 800;
    letter-spacing: .07em; text-transform: uppercase; padding: 2px 9px; border-radius: 20px; margin-bottom: 6px;
}
.opening.o-bad { border-style: dashed; }
.opening.o-bad .o-lbl { background: rgba(217, 83, 79, .12); color: var(--sig-red); }
.opening.o-bad .num { color: var(--sig-red); font-weight: 700; text-decoration: underline wavy var(--sig-red) 1.5px; text-underline-offset: 3px; }
.opening.o-good { border-color: var(--brand-400); }
.opening.o-good .o-lbl { background: var(--tint-2); color: var(--brand-600); }
.opening.o-good .ov { background: var(--tint-2); color: var(--brand-700); font-weight: 700; border-radius: 5px; padding: 1px 4px; box-shadow: inset 0 -2px 0 var(--sig-green); }
html[data-theme="dark"] .opening.o-good .ov { color: var(--brand-400); }
@media (max-width: 600px) { .chart-demo { flex-direction: column; align-items: stretch; } .mini-chart { align-self: center; } }
.para-pairs { display: grid; gap: 8px; }
.pp { display: flex; align-items: center; gap: 10px; font-size: calc(14px * var(--fs-scale-body)); flex-wrap: wrap; }
.pp .from { color: var(--ink-soft); text-decoration: line-through; text-decoration-color: var(--sig-red); }
.pp .arr { color: var(--brand-600); font-weight: 800; }
.pp .to { font-weight: 800; color: var(--brand-600); }
.warn-card .para-pairs { margin-top: 10px; }

/* ---- structure: the essay-type chips + tap-to-open skeleton ---- */
.etypes { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 6px; }
.etype {
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 700; padding: 5px 13px; border-radius: 20px;
    background: var(--tint); color: var(--ink-soft); border: 1px solid var(--line-soft);
}
.etypes .eq { font-size: 14px; font-weight: 800; color: var(--brand-600); }
.blueprint { display: flex; flex-direction: column; gap: 10px; }
.bp-block {
    position: relative; border-radius: var(--r-sm); padding: 14px 18px;
    background: var(--surface); border: 1.5px solid var(--line-soft);
    cursor: pointer; transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.bp-block:hover { border-color: var(--brand-400); }
.bp-block .bp-head { display: flex; align-items: center; gap: 10px; }
.bp-block .bp-n {
    flex-shrink: 0; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800; background: var(--tint-2); color: var(--brand-600);
}
.bp-block h4 { font-family: 'Fraunces', serif; font-size: calc(17px * var(--fs-scale-title)); font-weight: 600; margin: 0; }
.bp-block .bp-sub { margin-left: auto; font-size: calc(11.5px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft); text-align: right; }
.bp-block.body { border-color: var(--brand-400); background: var(--tint); }
.bp-block .bp-open { margin-left: 12px; color: var(--brand-600); font-size: 15px; flex-shrink: 0; transition: transform .3s ease; }
.bp-block.open .bp-open { transform: rotate(180deg); }
.bp-more { display: grid; grid-template-rows: 0fr; overflow: hidden; transition: grid-template-rows .4s ease; }
.bp-more > div { min-height: 0; }
.bp-block.open { border-color: var(--brand-400); box-shadow: 0 6px 18px rgba(90, 138, 58, .10); }
.bp-block.open .bp-more { grid-template-rows: 1fr; }
.bp-block.seen .bp-n { background: var(--brand-600); color: var(--on-brand); }
.bp-flag {
    display: inline-flex; align-items: center; gap: 6px; margin-top: 8px;
    font-size: calc(11.5px * var(--fs-scale-ui)); font-weight: 800; padding: 3px 10px; border-radius: 20px;
    background: rgba(224, 165, 58, .16); color: var(--sig-amber);
}
.tse { display: grid; gap: 6px; margin-top: 10px; }
.tse-row { display: flex; align-items: baseline; gap: 9px; font-size: calc(13.5px * var(--fs-scale-body)); color: var(--ink-soft); }
.tse-row .tse-tag {
    flex-shrink: 0; width: 86px; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .06em;
    text-transform: uppercase; color: var(--brand-600);
}
.tse-row b { color: var(--ink); font-weight: 800; }
.o3-progress { margin-top: 14px; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft); text-align: center; }
.o3-progress b { color: var(--brand-600); }

/* ---- pre-writing: the method rail + live layer split ---- */
.xprompt { font-family: 'Fraunces', serif; font-size: calc(17.5px * var(--fs-scale-body)); line-height: 1.75; color: var(--ink); }
.xprompt .seg { border-radius: 6px; padding: 1px 4px; transition: background .4s ease, color .4s ease; }
.xprompt .seg.lit.gen  { background: var(--lay-gen-fill);  color: var(--lay-gen);  font-weight: 700; }
.xprompt .seg.lit.spec { background: var(--lay-spec-fill); color: var(--lay-spec); font-weight: 700; }
.xprompt .seg.lit.inst { background: var(--lay-inst-fill); color: var(--lay-inst); font-weight: 700; }
.lay-item {
    display: flex; gap: 12px; align-items: flex-start; padding: 12px 16px;
    border-radius: var(--r-sm); background: var(--surface); border: 1px solid var(--line-soft);
    border-left: 4px solid var(--line);
}
.lay-item.gen  { border-left-color: var(--lay-gen); }
.lay-item.spec { border-left-color: var(--lay-spec); }
.lay-item.inst { border-left-color: var(--lay-inst); }
.lay-item .lay-tag {
    flex-shrink: 0; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    padding: 3px 10px; border-radius: 20px; margin-top: 2px;
}
.lay-item.gen  .lay-tag { background: var(--lay-gen-fill);  color: var(--lay-gen); }
.lay-item.spec .lay-tag { background: var(--lay-spec-fill); color: var(--lay-spec); }
.lay-item.inst .lay-tag { background: var(--lay-inst-fill); color: var(--lay-inst); }
.lay-item .lay-txt { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.5; }
.lay-item .lay-txt b { color: var(--ink); font-weight: 800; }
.lay-item .lay-txt .warn { color: var(--sig-red); font-weight: 700; }
.track { position: relative; display: grid; gap: 0; }
.tstep { position: relative; display: flex; gap: 16px; padding: 0 0 24px 0; }
.tstep:last-child { padding-bottom: 0; }
.tstep .rail { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; width: 34px; }
.tstep .tn {
    width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
    font-size: 14px; font-weight: 800; z-index: 1; background: var(--brand-600); color: var(--on-brand);
}
.tstep.locked .tn { background: var(--surface-2); color: var(--ink-soft); border: 1.5px solid var(--line); }
.tstep .rail::after { content: ''; flex: 1; width: 2px; background: var(--line); margin-top: 4px; }
.tstep:last-child .rail::after { display: none; }
.tstep.o1-lead .rail::after { display: none; }
.tstep .t-body { flex: 1; min-width: 0; padding-top: 4px; }
.tstep h4 { font-family: 'Fraunces', serif; font-size: calc(18px * var(--fs-scale-title)); font-weight: 600; margin: 0 0 6px; }
.tstep.locked h4 { color: var(--ink-soft); display: flex; align-items: center; gap: 8px; }
.tstep.locked h4 .pad { font-size: 13px; }
/* Step 1's worked content breaks out of the rail indent (34px rail + 16px gap) */
.o1-break { margin-left: -50px; }
.o1-legend { display: grid; gap: 10px; margin-top: 16px; }
.o1-legend .lay-item { opacity: 0; transform: translateY(12px); transition: opacity .45s ease, transform .45s cubic-bezier(.4, 1.3, .5, 1); }
.o1-legend .lay-item.in { opacity: 1; transform: none; }
.tstep .fuzz {
    font-size: 13px; color: var(--ink-soft); filter: blur(5px); user-select: none; pointer-events: none;
    overflow: hidden; white-space: nowrap; max-width: 100%;
}
.tstep.locked.f2 .fuzz { filter: blur(4px); opacity: .85; }
.tstep.locked.f3 .fuzz { filter: blur(6px); opacity: .65; }
.tstep.locked.f4 .fuzz { filter: blur(8px); opacity: .45; }
.reveal-row { display: flex; justify-content: center; margin-top: 16px; }
@media (max-width: 560px) { .o1-break { margin-left: 0; } }

/* ---- layer-split drill: the interactive 3-state AI-graded prompt X-ray ---- */
/* the Task 2 prompt, presented as the exam paper */
.the-prompt {
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: var(--r-sm);
    padding: 18px 22px; font-family: 'Fraunces', serif; font-size: calc(17px * var(--fs-scale-body)); line-height: 1.7; color: var(--ink);
}
.the-prompt .p-tag {
    display: block; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800;
    letter-spacing: .08em; text-transform: uppercase; color: var(--brand-600); margin-bottom: 6px;
}
/* graded highlights inside the prompt — unlit until the reveal lights them on grade */
.the-prompt .seg { border-radius: 6px; padding: 1px 4px; transition: background .4s ease, color .4s ease; }
.the-prompt .seg.lit.gen  { background: var(--lay-gen-fill);  color: var(--lay-gen);  font-weight: 700; }
.the-prompt .seg.lit.spec { background: var(--lay-spec-fill); color: var(--lay-spec); font-weight: 700; }
.the-prompt .seg.lit.inst { background: var(--lay-inst-fill); color: var(--lay-inst); font-weight: 700; }
/* the general-topic gloss is part of the REVEAL — hidden until grading, else it hands over
   the first layer's answer for free */
.the-prompt .gen-note { display: none; }
.the-prompt .gen-note.lit {
    display: block; width: fit-content; margin-top: 8px;
    font-family: 'Nunito', system-ui, sans-serif; font-size: calc(13px * var(--fs-scale-body));
}

/* the three layer input fields */
.lay-form { display: grid; gap: 16px; margin: 18px 0 4px; overflow: hidden; }
.lay-form.collapsing { transition: height .45s ease, opacity .4s ease, margin .45s ease; }
.lay-field { border-left: 4px solid var(--line); border-radius: 12px; padding-left: 14px; }
.lay-field.gen  { border-left-color: var(--lay-gen); }
.lay-field.spec { border-left-color: var(--lay-spec); }
.lay-field.inst { border-left-color: var(--lay-inst); }
.lay-field .lay-field-lbl { display: block; font-size: calc(13px * var(--fs-scale-ui)); font-weight: 700; margin-bottom: 8px; }
.lay-field .lay-field-lbl.gen  { color: var(--lay-gen); }
.lay-field .lay-field-lbl.spec { color: var(--lay-spec); }
.lay-field .lay-field-lbl.inst { color: var(--lay-inst); }

/* the graded reveal container */
.reveal-out { display: flex; flex-direction: column; gap: 18px; }

/* traffic-light legend (what yellow means) */
.tl-legend { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: calc(12.5px * var(--fs-scale-ui)); color: var(--ink-soft); }
.tl-legend .li { display: inline-flex; align-items: center; gap: 6px; }
.tl-legend .sw { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; }
.tl-legend .sw.g { background: var(--sig-green); }
.tl-legend .sw.y { background: var(--sig-amber); }
.tl-legend .sw.r { background: var(--sig-red); }

/* per-layer graded row — green (nailed) / AMBER (partial) / red (missed) */
.layer-row {
    display: grid; gap: 8px; padding: 14px 16px; border-radius: var(--r-sm);
    background: var(--surface-2); border-left: 4px solid var(--line);
}
.layer-row.good { border-left-color: var(--sig-green); }
.layer-row.part { border-left-color: var(--sig-amber); background: rgba(224,165,58,.07); }
.layer-row.bad  { border-left-color: var(--sig-red);  background: rgba(217,83,79,.06); }
.layer-row .lr-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.layer-row .lr-lay {
    font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    padding: 3px 10px; border-radius: 20px;
}
.layer-row .lr-lay.gen  { background: var(--lay-gen-fill);  color: var(--lay-gen); }
.layer-row .lr-lay.spec { background: var(--lay-spec-fill); color: var(--lay-spec); }
.layer-row .lr-lay.inst { background: var(--lay-inst-fill); color: var(--lay-inst); }
.layer-row .lr-state {
    margin-left: auto; font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
    padding: 3px 11px; border-radius: 20px;
}
.layer-row.good .lr-state { background: var(--tint-2); color: var(--brand-600); }
.layer-row.part .lr-state { background: rgba(224,165,58,.18); color: var(--sig-amber); }
.layer-row.bad  .lr-state { background: rgba(217,83,79,.13); color: var(--sig-red); }
.layer-row .lr-ans { font-size: calc(14.5px * var(--fs-scale-body)); color: var(--ink); }
.layer-row .lr-ans .q { font-style: italic; }
.layer-row .lr-comment { font-size: calc(13.5px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.5; }
.layer-row .lr-comment b { color: var(--ink); font-weight: 800; }
.layer-row .lr-model { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); border-top: 1px dashed var(--line); padding-top: 8px; }
.layer-row .lr-model b { font-weight: 800; }
.layer-row.good .lr-model b { color: var(--brand-600); }
.layer-row.part .lr-model b { color: var(--brand-600); }
.layer-row.bad  .lr-model b { color: var(--brand-600); }

/* ================================================================
   SPEAKING block (screens 1–5). Ported verbatim from
   design_system/speaking-tips-options.html's chosen variants.
   Reuses existing DS classes (.stage .card .motto .myth-* .pw-unit
   .ms-* .reveal-row .screen-lead); only the Speaking-specific pieces
   live here. All colours themed in BOTH modes.
   ================================================================ */
/* the three answer-part roles: Direct Answer / Brick / Depth */
:root {
    --spk-answer: #5a8a3a;  --spk-answer-fill: rgba(90,138,58,.16);
    --spk-brick:  #2f6f8f;  --spk-brick-fill:  rgba(47,111,143,.16);
    --spk-depth:  #b5731f;  --spk-depth-fill:  rgba(181,115,31,.18);
}
html[data-theme="dark"] {
    --spk-answer: #8bb36a;  --spk-answer-fill: rgba(139,179,106,.20);
    --spk-brick:  #6fb0cf;  --spk-brick-fill:  rgba(111,176,207,.20);
    --spk-depth:  #dda155;  --spk-depth-fill:  rgba(221,161,85,.22);
}

/* ---- Screen 1: the four Micro-Chunk families (chunk shelf) ---- */
.chunks { display: grid; gap: 12px; margin-top: 4px; }
.chunk-card {
    padding: 16px 18px; border-radius: var(--r-sm); background: var(--surface-2);
    border: 1px solid var(--line-soft); border-left: 4px solid var(--line);
}
.chunk-card .ck-lbl {
    display: inline-flex; align-items: center; gap: 7px; font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 8px;
}
.chunk-card .ck-lbl .b7 {
    font-size: calc(9.5px * var(--fs-scale-ui)); padding: 2px 8px; border-radius: 20px;
    background: var(--tint-2); color: var(--brand-600); letter-spacing: .05em;
}
.chunk-card .ck-phrase { font-family: 'Fraunces', serif; font-size: calc(15.5px * var(--fs-scale-body)); font-style: italic; line-height: 1.6; color: var(--ink); }
.chunk-card .ck-phrase + .ck-phrase { margin-top: 6px; display: block; }
.chunk-card.opinion    { border-left-color: var(--spk-answer); }
.chunk-card.concession { border-left-color: var(--spk-brick); }
.chunk-card.time       { border-left-color: var(--spk-depth); }
.chunk-card.detail     { border-left-color: var(--brand-400); }

/* ---- Screen 2: the three-part answer decode (Direct Answer / Brick / Depth) ---- */
.answer-line { font-family: 'Fraunces', serif; font-size: calc(19px * var(--fs-scale-body)); line-height: 1.85; color: var(--ink); }
.answer-line .part { border-radius: 6px; padding: 1px 6px; transition: background .4s ease, color .4s ease; cursor: default; }
.answer-line .part.lit.answer { background: var(--spk-answer-fill); color: var(--spk-answer); font-weight: 700; }
.answer-line .part.lit.brick  { background: var(--spk-brick-fill);  color: var(--spk-brick);  font-weight: 700; }
.answer-line .part.lit.depth  { background: var(--spk-depth-fill);  color: var(--spk-depth);  font-weight: 700; }
.part-legend { display: grid; gap: 10px; margin-top: 18px; }
.part-item {
    display: flex; gap: 12px; align-items: flex-start; padding: 12px 16px;
    border-radius: var(--r-sm); background: var(--surface); border: 1px solid var(--line-soft);
    border-left: 4px solid var(--line);
}
.part-item.answer { border-left-color: var(--spk-answer); }
.part-item.brick  { border-left-color: var(--spk-brick); }
.part-item.depth  { border-left-color: var(--spk-depth); }
.part-item .pt-tag {
    flex-shrink: 0; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    padding: 3px 10px; border-radius: 20px; margin-top: 2px;
}
.part-item.answer .pt-tag { background: var(--spk-answer-fill); color: var(--spk-answer); }
.part-item.brick  .pt-tag { background: var(--spk-brick-fill);  color: var(--spk-brick); }
.part-item.depth  .pt-tag { background: var(--spk-depth-fill);  color: var(--spk-depth); }
.part-item .pt-txt { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.5; }
.part-item .pt-txt b { color: var(--ink); font-weight: 800; }
.o2-cap { margin-top: 14px; font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); text-align: center; min-height: 1.7em; }
.o2-cap b { color: var(--ink); font-weight: 800; }

/* ---- Screen 3: the live cue card (topic pivoting) + pivot chips ---- */
.cue-card { border: 1.5px solid var(--line); border-radius: var(--r-md); background: var(--surface); padding: 20px 22px; box-shadow: var(--shadow); }
.cue-card .cc-main {
    font-family: 'Fraunces', serif; font-size: calc(18px * var(--fs-scale-title)); font-weight: 600; line-height: 1.5;
    padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px dashed var(--line);
}
.cue-card .cc-main .halo { background: var(--spk-answer-fill); color: var(--spk-answer); border-radius: 6px; padding: 1px 6px; box-shadow: 0 0 0 2px var(--spk-answer-fill); }
.cue-card .cc-you-say { display: block; font-family: 'Nunito', system-ui, sans-serif; font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--brand-600); margin-bottom: 8px; }
.cue-bullets { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.cue-bullets li { display: flex; align-items: center; gap: 10px; font-size: calc(14.5px * var(--fs-scale-body)); color: var(--ink-soft); padding: 8px 12px; border-radius: 12px; }
.cue-bullets li .bx { flex-shrink: 0; width: 18px; height: 18px; border-radius: 5px; border: 2px solid var(--line); }
.cue-bullets li.skip { opacity: .55; }
.cue-bullets li.skip .lab { text-decoration: line-through; text-decoration-color: var(--sig-red); }
.cue-bullets li.skip .verdict { margin-left: auto; font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; color: var(--sig-red); text-transform: uppercase; letter-spacing: .05em; }
.cue-bullets li.keep .lab { color: var(--ink); font-weight: 700; }
.cue-bullets li.keep .verdict { margin-left: auto; font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; color: var(--brand-600); text-transform: uppercase; letter-spacing: .05em; }
.pivots { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }
.pivot-chip { display: inline-flex; align-items: center; gap: 8px; padding: 10px 16px; border-radius: var(--r-pill); background: var(--surface-2); border: 1px solid var(--line); font-size: 14px; font-weight: 700; }
.pivot-chip .ic { font-size: 16px; }

/* ---- Screen 4: the Silent-Surrender rescue (discourse + pivot) ---- */
.rescue { display: grid; gap: 14px; }
.panic { padding: 18px 20px; border-radius: var(--r-md); background: rgba(217,83,79,.08); border: 1px dashed rgba(217,83,79,.4); }
.panic .cap { font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--sig-red); margin-bottom: 8px; }
.panic .silence { font-family: 'Fraunces', serif; font-size: calc(16px * var(--fs-scale-body)); font-style: italic; color: var(--ink); }
.panic .silence .dots { color: var(--sig-red); letter-spacing: .15em; font-weight: 700; }
.rescue-steps { display: grid; gap: 10px; }
.rs { display: flex; gap: 14px; align-items: flex-start; padding: 14px 18px; border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line-soft); border-left: 4px solid var(--line); }
.rs.discourse { border-left-color: var(--spk-brick); }
.rs.pivot     { border-left-color: var(--spk-answer); }
.rs .rs-tag { flex-shrink: 0; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; padding: 3px 10px; border-radius: 20px; margin-top: 2px; }
.rs.discourse .rs-tag { background: var(--spk-brick-fill); color: var(--spk-brick); }
.rs.pivot     .rs-tag { background: var(--spk-answer-fill); color: var(--spk-answer); }
.rs .rs-body h4 { font-size: calc(13.5px * var(--fs-scale-body)); font-weight: 800; margin: 0 0 3px; }
.rs .rs-body .said { font-family: 'Fraunces', serif; font-size: calc(15px * var(--fs-scale-body)); font-style: italic; color: var(--ink); }
.rs .rs-body .why { font-size: calc(13px * var(--fs-scale-body)); color: var(--ink-soft); margin-top: 3px; }

/* ---- Screens 3 & 4: the locked steps (blurred teaser → paywall reveal) ---- */
/* the Speaking locked-step device: full-width rows with a Fraunces token, a blurred
   fake line, and a lock badge. Distinct from Writing's .tstep rail — this is a flat list. */
.locked-steps { display: grid; gap: 10px; }
.lstep { position: relative; display: flex; align-items: center; gap: 14px; padding: 16px 20px; border-radius: var(--r-sm); background: var(--surface); border: 1.5px dashed var(--line); }
.lstep .ln {
    flex-shrink: 0; width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center;
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 800; background: var(--surface-2); color: var(--ink-soft);
    border: 1.5px solid var(--line); font-family: 'Fraunces', serif;
}
.lstep .lt { min-width: 0; }
.lstep h4 { font-family: 'Fraunces', serif; font-size: calc(16px * var(--fs-scale-title)); font-weight: 600; margin: 0; }
.lstep .fuzz {
    margin-top: 3px; font-size: 13px; color: var(--ink-soft);
    filter: blur(5px); user-select: none; pointer-events: none;
    overflow: hidden; white-space: nowrap; text-overflow: clip; max-width: 100%;
}
.lstep .lock-badge {
    margin-left: auto; flex-shrink: 0; font-size: 15px;
    width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
    background: var(--tint-2); color: var(--brand-600);
}

/* ---- Screen 5: the "before you walk in" checklist (v2 layout, v1 texts) ---- */
.checklist { display: grid; gap: 2px; }
.cl-row { display: flex; align-items: flex-start; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--line-soft); }
.cl-row:last-child { border-bottom: none; }
.cl-row .cb {
    flex-shrink: 0; width: 26px; height: 26px; border-radius: 8px; margin-top: 2px;
    background: var(--brand-600); color: var(--on-brand); display: grid; place-items: center;
    font-weight: 900; font-size: calc(14px * var(--fs-scale-ui));
}
.cl-row .cl-txt h4 { font-size: calc(15px * var(--fs-scale-body)); font-weight: 800; margin: 0 0 2px; }
.cl-row .cl-txt p { font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); margin: 0; }
.cl-row .cl-txt .phrase { font-style: italic; color: var(--ink); }

/* ---- Speaking reaction drill (final practice screen) ---- */
/* LAYOUT INTENT — the recording stage is deliberately a THREE-group rhythm, not a flat list:
     ask (question + phrase)  →  action (one button)  →  meta (EQ + countdown).
   The old stage spaced nine elements on one uniform 10px gap, so nothing grouped, and a
   28px count-up timer out-shouted the 22px question. Group spacing (28px) must stay clearly
   larger than within-group spacing (10px) or the grouping collapses back into noise. */
.sr-status { margin: 0 0 18px; max-width: 54ch; }
.sr-qbox { display: grid; gap: 28px; margin-top: 4px; }
.sr-qbox.hidden, .mic-eq.hidden, .sr-clock.hidden, .sr-meta.hidden,
.btn.hidden { display: none !important; }

/* Group 1: the only thing that should pull the eye. */
.sr-ask { display: grid; gap: 14px; }
.sr-question {
  font-family: 'Fraunces', serif; font-size: calc(27px * var(--fs-scale-title));
  font-weight: 600; margin: 0; line-height: 1.25; letter-spacing: -0.01em;
  text-wrap: balance;
}
/* The phrase to say gets the single brand accent on the card — a tinted panel with a rule.
   The instruction sits INSIDE the panel as a quiet sentence-case lead-in (.sr-filler-lead),
   NOT as an uppercase label above it: the panel stays one visual unit, and the quoted phrase
   is never left sitting there unexplained. */
.sr-filler {
  position: relative; margin: 0; padding: 13px 18px 15px 20px;
  border-radius: var(--r-sm); background: var(--tint);
}
.sr-filler::before {
  content: ""; position: absolute; left: 0; top: 10px; bottom: 10px;
  width: 3px; border-radius: 3px; background: var(--brand-600);
}
.sr-filler-lead {
  font-size: calc(12.5px * var(--fs-scale-ui)); font-weight: 700;
  color: var(--ink-soft); margin-bottom: 4px;
}
.sr-filler-text {
  margin: 0; font-size: calc(16.5px * var(--fs-scale-body)); font-style: italic;
  color: var(--brand-700); font-weight: 600; line-height: 1.45;
}
html[data-theme="dark"] .sr-filler { background: var(--tint-2); }
html[data-theme="dark"] .sr-filler-text { color: var(--brand-200); }
html[data-theme="dark"] .sr-filler::before { background: var(--brand-400); }

/* Group 2: the single action. Empty (zero-height) before the reveal, when the button still
   lives in the card. */
.sr-btn-slot:empty { display: none; }

/* Group 3: quiet telemetry. One line, muted, deliberately the least prominent thing here —
   it is feedback that recording is live, not information to act on. The count-UP timer was
   removed from this phase entirely (it duplicated the countdown and dominated the card);
   start speed is measured server-side from the audio, so nothing depends on displaying it. */
.sr-meta {
  display: flex; align-items: center; gap: 18px;
  padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.sr-clock {
  font-size: calc(16px * var(--fs-scale-ui)); font-weight: 800; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; margin-left: auto; letter-spacing: 0.01em;
}
.sr-again-row { display: flex; justify-content: center; margin: 20px 0 4px; }
.sr-again-note { text-align: center; margin: 0; max-width: 46ch; }
/* The loose explanatory line on the no-score paths (mic denied, grader skipped). It is NOT
   part of the result panel — those paths render no panel at all — and `clearResults()`
   sweeps it by this class, so it must keep one. */
.sr-note { font-size: calc(13px * var(--fs-scale-body)); }
/* On the reaction stage the EQ STRETCHES to fill the meta row (`flex: 1` on the strip) so the
   level meter spans the card instead of shrink-wrapping into a stub — it is the live proof
   that the mic is hearing you, so it should read at a glance. Bars divide that width. */
.mic-eq {
  display: flex; align-items: flex-end; gap: 6px; height: 26px;
  padding: 0; margin: 0; flex: 1; min-width: 0;
}
.mic-eq .eq-bar {
  flex: 1 1 0; min-width: 3px; height: 12%; min-height: 3px;
  border-radius: 3px; background: var(--brand-600);
  transition: height 60ms linear;
}
html[data-theme="dark"] .mic-eq .eq-bar { background: var(--brand-400); }
/* ------------------------------------------------------------
   THE REACTION-DRILL RESULT PANEL ("Scorecard + marked answer").
   Replaced a flat stack of ~14 same-weight siblings (a metric grid, a grey transcript, and
   eight bold-label pill rows) in which nothing led the eye and the start time was stated
   three times. Five bands instead, each with one job:
     .sr-q       the question that was answered
     .sr-hero    THE headline — start speed as a dial with the Band 7 line on the arc
     .sr-scales  the three graded ladders (every rung named, so a grade explains itself)
     .sr-vitals  the Deepgram numbers, deliberately quiet
     .sr-sec     the marked transcript + its mark cards, then the coach's notes
   then the tip strip and the Band-7 sample.
   Tone classes (pass/warn/fail) on .sr-panel drive every accent inside it.
   ------------------------------------------------------------ */
.sr-panel {
  overflow: hidden; background: var(--surface);
  border: 1px solid var(--line); border-left: 6px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow);
  animation: grow .35s ease;
}
.sr-panel.pass { border-left-color: var(--sig-green); }
.sr-panel.warn { border-left-color: var(--sig-amber); }
.sr-panel.fail { border-left-color: var(--sig-red); }

/* the question this result answers */
.sr-q {
  display: flex; align-items: baseline; gap: 10px; padding: 14px 28px;
  background: var(--tint); border-bottom: 1px solid var(--line-soft);
  font-size: calc(13.5px * var(--fs-scale-body));
}
.sr-q b {
  font-size: calc(10px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-soft); flex-shrink: 0;
}

/* ---- the hero: the dial + the verdict sentence ---- */
.sr-hero {
  display: grid; grid-template-columns: minmax(190px, 240px) 1fr; gap: 30px;
  align-items: center; padding: 26px 28px; border-bottom: 1px solid var(--line-soft);
}
/* no audible first word => no start figure => no dial, and the copy takes the full width */
.sr-hero.no-dial { grid-template-columns: 1fr; }
.sr-dial { position: relative; display: grid; place-items: center; }
.sr-dial svg { width: 100%; height: auto; display: block; overflow: visible; }
.sr-dial-track { fill: none; stroke: var(--line-soft); stroke-width: 13; stroke-linecap: round; }
.sr-dial-fill {
  fill: none; stroke-width: 13; stroke-linecap: round;
  transition: stroke-dashoffset 1s cubic-bezier(.32, .72, .29, 1);
}
.sr-panel.pass .sr-dial-fill { stroke: var(--sig-green); }
.sr-panel.warn .sr-dial-fill { stroke: var(--sig-amber); }
.sr-panel.fail .sr-dial-fill { stroke: var(--sig-red); }
/* the Band-7 benchmark notch, drawn ON the arc from the same angle function as the sweep */
.sr-dial-mark { stroke: var(--ink); stroke-width: 2.5; opacity: .5; stroke-linecap: round; }
.sr-dial-center { position: absolute; text-align: center; line-height: 1; }
.sr-dial-num {
  display: block; font-family: 'Fraunces', serif; font-weight: 700; letter-spacing: -.03em;
  font-size: calc(46px * var(--fs-scale-title));
}
.sr-panel.pass .sr-dial-num { color: var(--sig-green); }
.sr-panel.warn .sr-dial-num { color: var(--sig-amber); }
.sr-panel.fail .sr-dial-num { color: var(--sig-red); }
.sr-dial-unit {
  display: block; margin-top: 7px; font-size: calc(11px * var(--fs-scale-ui));
  font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
}
.sr-dial-bench {
  margin-top: 10px; text-align: center; font-size: calc(11px * var(--fs-scale-ui));
  font-weight: 700; color: var(--ink-soft);
}
.sr-hero-copy h3 {
  margin: 0 0 10px; font-family: 'Fraunces', serif; font-weight: 600; letter-spacing: -.015em;
  font-size: calc(25px * var(--fs-scale-title)); line-height: 1.2; text-wrap: balance;
}
.sr-panel.pass .sr-hero-copy h3 { color: var(--brand-700); }
.sr-panel.warn .sr-hero-copy h3 { color: var(--sig-amber); }
.sr-panel.fail .sr-hero-copy h3 { color: var(--sig-red); }
html[data-theme="dark"] .sr-panel.pass .sr-hero-copy h3 { color: var(--brand-400); }
.sr-hero-copy p {
  margin: 0; font-size: calc(15px * var(--fs-scale-body)); color: var(--ink-soft); max-width: 46ch;
}

/* ---- the three graded ladders ----
   Always exactly three, so the grid is fixed at 3 columns rather than auto-fit: auto-fit with
   a min track width laid out a fourth empty column on a wide panel, which stopped the row's
   dividers short of the panel edge and broke alignment with .sr-vitals underneath.
   Dividers are 1px rules in the column gutters, matching the vitals row below. */
.sr-scales {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px 0;
  padding: 24px 28px; border-bottom: 1px solid var(--line-soft); background: var(--surface-2);
}
.sr-scale { padding-inline: 15px; border-left: 1px solid var(--line); }
.sr-scale:nth-child(3n + 1) { border-left: none; padding-left: 0; }
.sr-scale:nth-child(3n) { padding-right: 0; }
.sr-scale-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-bottom: 9px;
}
.sr-scale-name {
  font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-soft);
}
.sr-scale-val { font-size: calc(14.5px * var(--fs-scale-body)); font-weight: 800; }
.sr-scale-val.good { color: var(--sig-green); }
.sr-scale-val.warn { color: var(--sig-amber); }
.sr-scale-val.bad { color: var(--sig-red); }
html[data-theme="dark"] .sr-scale-val.good { color: var(--brand-400); }
/* the track: one segment per rung, filled up to the rung reached */
.sr-rungs { display: flex; gap: 4px; }
.sr-rung { flex: 1; height: 7px; border-radius: 4px; background: var(--line-soft); }
.sr-rung.on.good { background: var(--sig-green); }
.sr-rung.on.warn { background: var(--sig-amber); }
.sr-rung.on.bad { background: var(--sig-red); }
html[data-theme="dark"] .sr-rung.on.good { background: var(--brand-400); }
/* every rung is named — the reason the scale explains itself instead of needing a legend */
.sr-rung-labels {
  display: flex; gap: 4px; margin-top: 7px;
  font-size: calc(9.5px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft);
}
.sr-rung-labels span { flex: 1; opacity: .5; line-height: 1.2; }
.sr-rung-labels span.here { opacity: 1; color: var(--ink); }
.sr-scale-note {
  margin: 9px 0 0; font-size: calc(12.5px * var(--fs-scale-body));
  color: var(--ink-soft); line-height: 1.45;
}

/* ---- the Deepgram vitals: quiet by design, they are evidence not verdicts ---- */
.sr-vitals {
  display: flex; flex-wrap: wrap; padding: 0 28px; border-bottom: 1px solid var(--line-soft);
}
.sr-vital {
  flex: 1 1 120px; padding: 15px 4px; text-align: center;
  border-right: 1px solid var(--line-soft);
}
.sr-vital:last-child { border-right: none; }
.sr-vital-v {
  font-family: 'Fraunces', serif; font-size: calc(20px * var(--fs-scale-title));
  font-weight: 700; line-height: 1;
}
/* was var(--ok/--warn/--bad) — three tokens this design system never defined, so every
   coloured metric silently rendered in its hardcoded fallback hex, off-palette from the
   --sig-* colours the rest of the panel uses */
.sr-vital-v.good { color: var(--sig-green); }
.sr-vital-v.warn { color: var(--sig-amber); }
.sr-vital-v.bad { color: var(--sig-red); }
html[data-theme="dark"] .sr-vital-v.good { color: var(--brand-400); }
.sr-vital-l {
  margin-top: 5px; font-size: calc(10px * var(--fs-scale-ui)); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft);
}
.sr-vital-read {
  margin-top: 3px; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 700;
  color: var(--ink-soft); opacity: .75;
}

/* ---- numbered sections ---- */
.sr-sec { padding: 24px 28px; border-bottom: 1px solid var(--line-soft); }
.sr-sec.alt { background: var(--surface-2); }
.sr-sec-head {
  display: flex; align-items: center; gap: 11px; margin-bottom: 18px;
  font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft);
}
.sr-sec-head::after { content: ''; flex: 1; height: 1px; background: var(--line-soft); }
/* fixed-geometry counter circle — its glyph stays plain px like the other icon circles */
.sr-sec-n {
  width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-600); color: var(--on-brand); font-size: 11px; font-weight: 900;
}

/* ---- the marked transcript ---- */
.sr-text {
  margin: 0; max-width: 68ch; font-family: 'Fraunces', serif; font-weight: 400;
  font-size: calc(18px * var(--fs-scale-body)); line-height: 1.85; color: var(--ink);
  letter-spacing: -.005em;
}
.sr-an { border-bottom: 2px solid; border-radius: 2px; padding: 0 1px; transition: background .18s ease; }
.sr-an.keep { border-color: var(--sig-green); }
.sr-an.link { border-color: var(--brand-400); }
.sr-an.weak { border-color: var(--sig-red); }
.sr-an.fixme { border-color: var(--sig-amber); }
.sr-an.keep.lit { background: rgba(90, 138, 58, .16); }
.sr-an.link.lit { background: rgba(139, 179, 106, .20); }
.sr-an.weak.lit { background: rgba(217, 83, 79, .15); }
.sr-an.fixme.lit { background: rgba(224, 165, 58, .22); }
html[data-theme="dark"] .sr-an.keep.lit { background: rgba(139, 179, 106, .24); }
html[data-theme="dark"] .sr-an.link.lit { background: rgba(139, 179, 106, .18); }
html[data-theme="dark"] .sr-an.weak.lit { background: rgba(221, 122, 151, .22); }
html[data-theme="dark"] .sr-an.fixme.lit { background: rgba(221, 161, 85, .24); }

/* one card per mark KIND, each ending in a visible solution */
.sr-marks {
  display: grid; gap: 10px; margin-top: 20px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.sr-mark {
  padding: 12px 14px; border-radius: 14px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--line); transition: background .18s ease;
}
.sr-mark.keep { border-left-color: var(--sig-green); }
.sr-mark.link { border-left-color: var(--brand-400); }
.sr-mark.weak { border-left-color: var(--sig-red); }
.sr-mark.fixme { border-left-color: var(--sig-amber); }
.sr-mark.lit { background: var(--tint-2); }
.sr-mark-top { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.sr-mark-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.sr-mark.keep .sr-mark-dot { background: var(--sig-green); }
.sr-mark.link .sr-mark-dot { background: var(--brand-500); }
.sr-mark.weak .sr-mark-dot { background: var(--sig-red); }
.sr-mark.fixme .sr-mark-dot { background: var(--sig-amber); }
.sr-mark-title { font-size: calc(12.5px * var(--fs-scale-body)); font-weight: 800; }
.sr-mark-why {
  margin: 0 0 8px; font-size: calc(12.5px * var(--fs-scale-body));
  color: var(--ink-soft); line-height: 1.45;
}
.sr-mark-phrases { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.sr-phrase {
  padding: 2px 9px; border-radius: 999px; background: var(--surface);
  border: 1px solid var(--line); font-family: 'Fraunces', serif; font-weight: 600;
  font-size: calc(12px * var(--fs-scale-ui));
}
.sr-mark.keep .sr-phrase { border-color: var(--sig-green); }
.sr-mark.link .sr-phrase { border-color: var(--brand-400); }
.sr-mark.weak .sr-phrase { border-color: var(--sig-red); }
.sr-mark.fixme .sr-phrase { border-color: var(--sig-amber); }

/* the solution row — always visible, never behind a click or a hover */
.sr-sol {
  display: grid; gap: 4px; padding: 8px 10px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--line-soft);
  font-size: calc(12.5px * var(--fs-scale-body)); line-height: 1.4;
}
.sr-sol-lbl {
  font-size: calc(9.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand-700);
}
html[data-theme="dark"] .sr-sol-lbl { color: var(--brand-400); }
.sr-sol-txt { margin: 0; color: var(--ink); }
.sr-sol-row { display: grid; grid-template-columns: auto 1fr; gap: 8px; align-items: baseline; }
/* `auto` + nowrap, not a fixed track: at the ui-tier scale "You said" wrapped to two lines
   inside a 52px column, which pushed the struck-through quote out of line with the fix. */
.sr-sol-tag {
  font-size: calc(9.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; text-align: right; white-space: nowrap;
}
.sr-sol-row.out .sr-sol-tag { color: var(--sig-red); }
.sr-sol-row.in .sr-sol-tag { color: var(--brand-700); }
html[data-theme="dark"] .sr-sol-row.in .sr-sol-tag { color: var(--brand-400); }
.sr-sol-row.out .sr-sol-txt {
  font-family: 'Fraunces', serif; opacity: .75;
  text-decoration: line-through; text-decoration-color: rgba(217, 83, 79, .45);
}
.sr-sol-row.in .sr-sol-txt { font-family: 'Fraunces', serif; font-weight: 600; }
/* the ACTION inside a solution line — amber by default, green when it is the target wording */
.sr-hl {
  background: rgba(224, 165, 58, .28); box-shadow: inset 0 -1.5px 0 var(--sig-amber);
  border-radius: 3px; padding: 0 2px; font-weight: 700; color: var(--ink);
}
html[data-theme="dark"] .sr-hl { background: rgba(224, 165, 58, .22); }
.sr-sol-row.in .sr-hl {
  background: rgba(139, 179, 106, .28); box-shadow: inset 0 -1.5px 0 var(--brand-400);
}

/* ---- the coach's notes ---- */
.sr-ngrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.sr-ncard {
  padding: 12px 14px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--brand-400);
}
.sr-ncard.good-edge { border-left-color: var(--sig-green); }
.sr-ncard.warn-edge { border-left-color: var(--sig-amber); }
.sr-ncard.bad-edge { border-left-color: var(--sig-red); }
.sr-ncard h4 {
  margin: 0 0 8px; font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-soft);
}
.sr-ncard p { margin: 0 0 8px; font-size: calc(13.5px * var(--fs-scale-body)); line-height: 1.5; }
.sr-ncard p:last-child { margin-bottom: 0; }

/* the structure path, drawn as connected beads so a weak step can be flagged in place */
.sr-path { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-bottom: 8px; }
.sr-bead {
  padding: 5px 12px; border-radius: var(--r-pill); background: var(--surface-2);
  border: 1px solid var(--line); font-size: calc(12px * var(--fs-scale-ui)); font-weight: 700;
}
.sr-bead.flag {
  border-color: var(--sig-amber); background: rgba(224, 165, 58, .14); color: var(--sig-amber);
}
.sr-path-arrow { color: var(--ink-soft); font-weight: 900; opacity: .5; }

/* speech rate against the natural band */
.sr-pace { margin-bottom: 8px; }
.sr-pace-track { position: relative; height: 8px; border-radius: 5px; background: var(--line-soft); }
.sr-pace-band {
  position: absolute; top: 0; bottom: 0; left: 40%; width: 26.7%; border-radius: 5px;
  background: var(--tint-2);
  border-left: 1px solid var(--brand-400); border-right: 1px solid var(--brand-400);
}
.sr-pace-pin {
  position: absolute; top: -4px; width: 3px; height: 16px; border-radius: 2px;
  background: var(--ink); transition: left .9s cubic-bezier(.32, .72, .29, 1);
}
.sr-pace-scale {
  display: flex; justify-content: space-between; margin-top: 6px;
  font-size: calc(10px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft); opacity: .75;
}

/* ---- the opening-phrase tip, then the Band-7 sample ---- */
.sr-tip {
  display: flex; gap: 11px; padding: 16px 28px;
  border-bottom: 1px solid var(--line-soft); background: var(--tint);
  font-size: calc(14px * var(--fs-scale-body)); line-height: 1.55;
}
.sr-tip-ic { flex-shrink: 0; font-size: 15px; }
.sr-model { padding: 22px 28px; background: linear-gradient(135deg, var(--tint), var(--tint-2)); }
.sr-model-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.sr-model-badge {
  padding: 4px 12px; border-radius: 999px; background: var(--brand-600); color: var(--on-brand);
  font-size: calc(10.5px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase;
}
.sr-model-cap {
  font-size: calc(13px * var(--fs-scale-body)); font-weight: 600; color: var(--ink-soft);
}
.sr-model-text {
  margin: 0; max-width: 62ch; font-family: 'Fraunces', serif; font-style: italic;
  font-size: calc(16.5px * var(--fs-scale-body)); line-height: 1.7; color: var(--ink);
}

/* Reflow. The ladder dividers have to be re-keyed at every column count, or a wrapped row
   starts with a rule hanging off its left edge. 3-up is the desktop case; ~810px drops the
   panel to 2-up and ~540px to a single column, where the rule turns horizontal. */
@media (max-width: 810px) {
  .sr-scales { grid-template-columns: repeat(2, 1fr); }
  .sr-scale:nth-child(3n + 1) { border-left: 1px solid var(--line); padding-left: 15px; }
  .sr-scale:nth-child(3n) { padding-right: 15px; }
  .sr-scale:nth-child(2n + 1) { border-left: none; padding-left: 0; }
  .sr-scale:nth-child(2n) { padding-right: 0; }
}
@media (max-width: 760px) {
  .sr-hero { grid-template-columns: 1fr; gap: 20px; text-align: center; }
  .sr-dial { max-width: 210px; margin: 0 auto; }
  .sr-hero-copy p { margin-inline: auto; }
  .sr-q, .sr-hero, .sr-scales, .sr-vitals, .sr-sec, .sr-tip, .sr-model { padding-inline: 20px; }
  .sr-sol-row { grid-template-columns: 1fr; gap: 2px; }
  .sr-sol-tag { text-align: left; }
}
@media (max-width: 540px) {
  .sr-scales { grid-template-columns: 1fr; gap: 0; }
  .sr-scale {
    border-left: none !important; padding-inline: 0 !important;
    padding-block: 16px; border-top: 1px solid var(--line);
  }
  .sr-scale:first-child { border-top: none; padding-top: 0; }
  .sr-scale:last-child { padding-bottom: 0; }
}
/* The dial sweep and the pace pin both animate from an empty state set inline in JS, so with
   motion reduced they must SNAP to the final value rather than never arriving. */
@media (prefers-reduced-motion: reduce) {
  .sr-dial-fill, .sr-pace-pin { transition: none; }
  .sr-panel { animation: none; }
}
.sr-fail-title {
  font-family: 'Fraunces', serif; font-size: calc(20px * var(--fs-scale-title));
  font-weight: 600; margin: 0 0 8px;
}
.sr-fail-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }

/* ============================================================
   THE PAYWALL — "Variant B3": the amber-glass Pro card and the quiet Handbook
   card, side by side, under a context block that reacts to the user's result.
   Ported from design_system/ielts-coach-paywalls.html (the copy/design reference,
   which links this file live). Built by screens/_paywall.js.
   Two deliberate departures from the reference: its `.vb-wrap` 900px cap is DROPPED
   (`.pw-unit` spans the screen column so the pair aligns with the sibling cards),
   and its 680px stack breakpoint moves to this file's own 760px, so mobile keeps
   rendering pre-scale sizes.
   ============================================================ */

/* Context block — lock + headline + result copy, above the pair */
.pw-context { max-width: 620px; margin: 0 auto 28px; text-align: center; }
.pw-context .lock {
    width: 56px; height: 56px; margin: 0 auto 14px;
    border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
    background: linear-gradient(135deg, var(--brand-400), var(--brand-200));
    display: flex; align-items: center; justify-content: center;
}
.pw-context .lock img { width: 32px; height: 32px; object-fit: contain; }
.pw-context h3 {
    font-family: 'Fraunces', serif; font-size: calc(22px * var(--fs-scale-title));
    font-weight: 600; margin-bottom: 8px;
}
.pw-context p { font-size: calc(15px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.5; }

/* The pair — warm amber-glass Pro card, quiet Handbook card */
.vb-pair { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 20px; align-items: start; }
.vb-card {
    border-radius: var(--r-md); padding: 26px 24px; position: relative;
    display: flex; flex-direction: column; backdrop-filter: blur(6px);
}
.vb-card.pro {
    background: linear-gradient(160deg, rgba(255,255,255,.95), rgba(243,248,236,.9));
    border: 2px solid rgba(221,161,85,.4);
    box-shadow: 0 12px 40px rgba(181,115,31,.12), 0 2px 8px rgba(90,138,58,.08);
    transform: translateY(-6px);
}
html[data-theme="dark"] .vb-card.pro {
    background: linear-gradient(160deg, var(--surface), var(--surface-2));
}
.vb-card.pro::before {
    content: 'RECOMMENDED'; position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 900; letter-spacing: .08em;
    padding: 5px 16px; border-radius: 20px;
    background: linear-gradient(135deg, var(--sig-orange), var(--sig-amber)); color: #fff;
    box-shadow: 0 4px 14px rgba(221,128,54,.30); white-space: nowrap;
}
.vb-card.handbook { background: rgba(255,255,255,.7); border: 1px solid var(--line-soft); }
html[data-theme="dark"] .vb-card.handbook { background: var(--surface); }
.vb-eyebrow {
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 800; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-soft); margin: 0 0 8px;
}
.vb-plan-name { font-size: calc(16px * var(--fs-scale-ui)); font-weight: 800; margin-bottom: 4px; }
.vb-card.pro .vb-plan-name { color: #b5731f; }
html[data-theme="dark"] .vb-card.pro .vb-plan-name { color: var(--sig-amber); }
.vb-price-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.vb-price {
    font-family: 'Fraunces', serif; font-size: calc(36px * var(--fs-scale-title));
    font-weight: 600; line-height: 1.1;
}
.vb-card.pro .vb-price { color: var(--sig-orange); }
html[data-theme="dark"] .vb-card.pro .vb-price { color: var(--sig-amber); }
.vb-unit { font-size: calc(13px * var(--fs-scale-ui)); font-weight: 600; color: var(--ink-soft); }
.vb-note {
    font-size: calc(13px * var(--fs-scale-body)); color: var(--ink-soft);
    line-height: 1.45; margin-bottom: 16px;
}
.vb-body { flex: 1; margin-bottom: 18px; }
.vb-cta {
    width: 100%; padding: 14px; font: inherit; font-size: calc(15px * var(--fs-scale-ui));
    font-weight: 800; border: none; border-radius: var(--r-sm); cursor: pointer;
    transition: transform .2s, box-shadow .2s;
}
.vb-card.pro .vb-cta {
    color: #fff; background: linear-gradient(135deg, var(--sig-orange), var(--sig-amber));
    box-shadow: 0 8px 22px rgba(221,128,54,.28);
}
.vb-card.pro .vb-cta:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(221,128,54,.38); }
.vb-card.handbook .vb-cta { color: var(--ink); background: transparent; border: 2px solid var(--line); }
.vb-card.handbook .vb-cta:hover { border-color: var(--brand-600); color: var(--brand-600); }
.vb-faq {
    font-size: calc(11px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft);
    text-align: center; margin-top: 10px; line-height: 1.4;
}
/* the "no checkout wired" stamp _paywall.js drops in on a CTA click */
.vb-card .mock-note {
    margin-top: 10px; font-size: calc(11.5px * var(--fs-scale-ui));
    color: var(--ink-soft); font-style: italic; text-align: center;
}

/* Key-term highlight, warm-tuned to sit inside the amber skin */
.vb-kw { font-weight: 800; color: #b5731f; background: rgba(224,138,43,.13); border-radius: 6px; padding: 1px 5px; }
html[data-theme="dark"] .vb-kw { color: var(--sig-amber); background: rgba(224,165,58,.18); }
/* Cool counterpart, for the Handbook column and secondary emphasis */
.vb-kw.cool { color: var(--lay-spec); background: var(--lay-spec-fill); }
html[data-theme="dark"] .vb-kw.cool { color: #6fb0cf; background: rgba(111,176,207,.20); }

/* Handbook column feature list */
.vb-hb-feats { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.vb-hb-feats > li { padding-left: 28px; position: relative; line-height: 1.45; }
.vb-hb-feats > li::before {
    content: '✓'; position: absolute; left: 0; top: 1px; width: 20px; height: 20px;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 900; border-radius: 50%;
    color: var(--brand-700); background: var(--tint-2);
}
html[data-theme="dark"] .vb-hb-feats > li::before { color: var(--brand-400); }
.vb-hb-feats .feat-title {
    font-weight: 800; font-size: calc(14px * var(--fs-scale-ui)); display: block; margin-bottom: 2px;
}
.vb-hb-feats .feat-sub {
    font-size: calc(13px * var(--fs-scale-body)); font-weight: 600;
    color: var(--ink-soft); line-height: 1.4;
}

/* B3's Pro body — one lead panel carrying both anchors as a single argument, then the
   remaining features compressed into a dense two-line grid. */
.vb3-lead {
    border-radius: 18px; padding: 16px 16px 14px; margin-bottom: 16px;
    background: linear-gradient(160deg, rgba(251,236,214,.8), rgba(255,255,255,.25));
    border: 1px solid rgba(224,138,43,.22);
}
html[data-theme="dark"] .vb3-lead {
    background: linear-gradient(160deg, rgba(224,165,58,.14), transparent);
}
.vb3-lead-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.vb3-lead-badge {
    font-size: calc(10px * var(--fs-scale-ui)); font-weight: 900; letter-spacing: .08em;
    text-transform: uppercase; color: #fff;
    background: linear-gradient(135deg, var(--sig-orange), var(--sig-amber));
    padding: 3px 9px; border-radius: var(--r-pill);
}
.vb3-lead h4 {
    font-family: 'Fraunces', serif; font-size: calc(17px * var(--fs-scale-title));
    font-weight: 600; margin: 0 0 6px; line-height: 1.3;
}
.vb3-lead p {
    font-size: calc(13px * var(--fs-scale-body)); color: var(--ink-soft);
    line-height: 1.5; margin: 0 0 10px;
}
.vb3-lead p:last-child { margin-bottom: 0; }
.vb3-split { display: grid; gap: 8px; margin-top: 10px; }
.vb3-half {
    background: rgba(255,255,255,.62); border-radius: 12px; padding: 10px 12px;
    padding-left: 32px; position: relative;
}
html[data-theme="dark"] .vb3-half { background: rgba(0,0,0,.18); }
.vb3-half::before {
    content: '✓'; position: absolute; left: 10px; top: 11px; width: 16px; height: 16px;
    display: grid; place-items: center; font-size: 10px; font-weight: 900; border-radius: 50%;
    background: rgba(224,138,43,.16); color: #b5731f;
}
html[data-theme="dark"] .vb3-half::before { color: var(--sig-amber); background: rgba(224,165,58,.2); }
.vb3-half.green::before { background: var(--tint-2); color: var(--brand-700); }
html[data-theme="dark"] .vb3-half.green::before { color: var(--brand-400); }
.vb3-half .ft {
    font-weight: 800; font-size: calc(13.5px * var(--fs-scale-ui));
    display: block; margin-bottom: 2px; line-height: 1.35;
}
.vb3-half .fs { font-size: calc(12.5px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.4; }
.vb3-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.vb3-rows > li {
    padding-left: 24px; position: relative;
    font-size: calc(13.5px * var(--fs-scale-body)); line-height: 1.4;
}
.vb3-rows > li::before {
    content: '+'; position: absolute; left: 0; top: 0; width: 17px; height: 17px;
    display: grid; place-items: center; font-size: 12px; font-weight: 900; border-radius: 50%;
    background: var(--tint-2); color: var(--brand-700);
}
html[data-theme="dark"] .vb3-rows > li::before { color: var(--brand-400); }
.vb3-rows .ft { font-weight: 800; }
.vb3-rows .fs {
    color: var(--ink-soft); font-size: calc(12.5px * var(--fs-scale-body));
    display: block; margin-top: 1px;
}
.vb3-more {
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 700; color: var(--ink-soft);
    margin: 12px 0 0; padding-top: 10px; border-top: 1px dashed var(--line);
}

/* ── The "Unfold" reveal (design_system/paywall_animations_mocks) ──
   The paywall grows into view on a 0fr → 1fr grid row, the pair fading + scaling in
   just behind it. Same 0fr-floor rule as .start-reveal: a 0fr track floors at its
   grid item's PADDING box, so .anim-unfold-inner keeps zero padding/border/margin —
   all spacing goes on .pw-unit, which the inner clips. */
.anim-unfold {
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows .62s cubic-bezier(.65,0,.35,1);
    /* The clip that makes the unfold read also shaves the Pro card's wide amber glow at
       the column edges. Bleed the clip box out into .wrap's own 24px side padding and pad
       .pw-unit back by the same amount: the shadow gets room, the pair still lines up with
       the sibling cards, and no actual content lands outside the wrap. */
    margin-left: -24px; margin-right: -24px;
}
.anim-unfold.in { grid-template-rows: 1fr; }
.anim-unfold-inner { overflow: hidden; min-height: 0; padding: 0; border: 0; margin: 0; }
.anim-unfold .pw-unit {
    padding: 6px 24px 26px; /* the bottom pad also keeps the drop shadow inside the clip */
    opacity: 0; transform: scale(.97);
    transition: opacity .45s ease .18s, transform .5s cubic-bezier(.4,1.3,.5,1) .18s;
}
.anim-unfold.in .pw-unit { opacity: 1; transform: none; }
/* the 1px sentinel a screen with no Next control observes instead. No screen uses it today
   (journey-recap renders its paywall open rather than unfolding it) — kept because it is the
   documented fallback for any future screen that ends without a next control. */
.pw-anchor { min-height: 1px; }
/* A paywall rendered OPEN, outside the unfold wrapper (journey-recap). It carries the top
   spacing the .anim-unfold wrapper would have supplied; it needs none of the negative side
   margins, because with no clip box there is nothing shaving the Pro card's amber glow. */
.pw-static { margin-top: 34px; }

/* ============================================================
   RECAP SCREENS — the two block-end recaps (listening-recap, journey-recap).
   Built by screens/_recap.js; ported from design_system/pre-paywall-c.html.
   `--pro` is the amber the Pro column speaks in — it must stay legible on
   --surface in BOTH themes, so light mode darkens the amber rather than reusing
   --sig-amber (which is a signal colour tuned for fills, not for body text).
   ============================================================ */
:root {
    --pro: #b5731f;
    --pro-fill: rgba(224, 138, 43, .13);
    --pro-line: rgba(224, 138, 43, .28);
    /* The glass wash the Pro-cell teaser lays over its own cell on hover. Near-opaque on
       purpose: it has to mute the copy underneath enough that the "Learn more" pill reads
       as the only live thing in the cell, not as a badge floating over readable text. */
    --hov-bg: rgba(251, 236, 214, .90);
}
html[data-theme="dark"] {
    --pro: #e0a53a;
    --pro-fill: rgba(224, 165, 58, .18);
    --pro-line: rgba(224, 165, 58, .32);
    --hov-bg: rgba(30, 41, 22, .90);
}

/* ── "what you did": a wrapping row of ticked facts ── */
.done-list { display: flex; flex-wrap: wrap; gap: 8px; justify-content: space-evenly; }
/* `.stack` = one full-width fact per line. Needed whenever the lines are long enough that
   two never share a row: space-evenly then centres each row at its own width and the left
   edges stagger. journey-recap's four block summaries are always in this case. */
.done-list.stack .done { width: 100%; }
.done {
    display: flex; align-items: flex-start; gap: 14px; padding: 14px 16px;
    border-radius: var(--r-sm); background: var(--surface);
    border: 1px solid var(--line-soft); box-shadow: 0 4px 14px rgba(63, 107, 35, .05);
}
.done .tick {
    flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
    display: grid; place-items: center; margin-top: 2px;
    background: var(--tint-2); color: var(--brand-700);
    font-size: calc(13px * var(--fs-scale-ui)); font-weight: 900;
}
html[data-theme="dark"] .done .tick { color: var(--brand-400); }
.done.miss .tick { background: rgba(217, 83, 79, .14); color: var(--sig-red); }
.done .dt { min-width: 0; }
.done h4 { margin: 0 0 2px; font-size: calc(15px * var(--fs-scale-ui)); font-weight: 800; line-height: 1.35; }
.done .val { margin: 0; font-size: calc(14px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.45; }
.done .val b { color: var(--brand-700); font-weight: 800; }
html[data-theme="dark"] .done .val b { color: var(--brand-400); }
.done.miss .val b { color: var(--sig-red); }

/* ── "today free vs with Pro": the comparison table ── */
.cmp {
    border-radius: var(--r-md); overflow: hidden;
    border: 1px solid var(--line); background: var(--surface); box-shadow: var(--shadow);
}
.cmp-head { display: grid; grid-template-columns: 4fr 5fr; }
.cmp-head div {
    padding: 14px 18px; font-size: calc(12.5px * var(--fs-scale-ui)); font-weight: 900;
    letter-spacing: .08em; text-transform: uppercase;
}
.cmp-head .h-free { color: var(--ink-soft); background: var(--surface-2); }
.cmp-head .h-pro { color: #fff; background: linear-gradient(135deg, var(--sig-orange), var(--sig-amber)); }
.cmp-row { display: grid; grid-template-columns: 4fr 5fr; border-top: 1px solid var(--line-soft); }
.cmp-row .cell { padding: 16px 18px; }
.cmp-row .cell.free { background: var(--surface-2); }
.cmp-row .cell.pro { background: linear-gradient(150deg, var(--pro-fill), transparent); }
.cmp-label {
    grid-column: 1 / -1; padding: 12px 18px 0; background: var(--surface);
    font-size: calc(12px * var(--fs-scale-ui)); font-weight: 900;
    letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
}
.cmp .cell h4 { margin: 0 0 4px; font-size: calc(15px * var(--fs-scale-ui)); font-weight: 800; line-height: 1.35; }
.cmp .cell p { margin: 0; font-size: calc(13.5px * var(--fs-scale-body)); color: var(--ink-soft); line-height: 1.5; }
.cmp .cell.free h4 { color: var(--ink-soft); }
.cmp .cell.pro h4 { color: var(--pro); }
.cmp .cell .mark { font-weight: 900; margin-right: 6px; }
.cmp .cell.free .mark { color: var(--ink-soft); opacity: .7; }
.cmp .cell.pro .mark { color: var(--pro); }
.cmp-foot {
    border-top: 1px solid var(--line-soft); padding: 16px 18px; background: var(--tint);
    font-size: calc(14.5px * var(--fs-scale-body)); font-weight: 700; line-height: 1.5;
}

/* ── Pro-cell teaser (opt-in: only a table built with compare()'s `onTeaser`) ──
   ONE node, `.pro-more`, in two presentations. The BASE state is the touch one — a small
   pill in the flow of the cell — because a device with no hover has no other way to show
   the affordance, and an invisible tap target on a phone-first funnel is not an affordance
   at all. `(hover: hover)` then re-lays the SAME node out as a full-cell glass overlay.
   One node is deliberate: it keeps exactly one click listener per cell, where an overlay
   button nested in a clickable cell would fire the reveal twice per click. */
.cmp-row .cell.pro-teaser { position: relative; }
.pro-more {
    display: inline-flex; align-items: center; margin-top: 10px; cursor: pointer;
    padding: 7px 16px; border: 1px solid var(--pro-line); border-radius: var(--r-pill);
    background: var(--surface); color: var(--pro);
    font: inherit; font-size: calc(12.5px * var(--fs-scale-ui)); font-weight: 800;
}
@media (hover: hover) {
    .pro-more {
        position: absolute; inset: 0; z-index: 2; margin: 0; padding: 10px;
        display: grid; place-items: center;
        border: 0; border-radius: 0; background: var(--hov-bg);
        opacity: 0; pointer-events: none; transition: opacity .2s ease;
    }
    .cell.pro-teaser:hover .pro-more { opacity: 1; pointer-events: auto; }
    /* Keyboard parity: the overlay is the only way in for a tab user, and `pointer-events`
       never blocks focus, so focusing it must also make it visible. */
    .pro-more:focus-visible { opacity: 1; pointer-events: auto; }
    .pro-more .pm-label {
        padding: 10px 22px; border-radius: var(--r-pill); color: #fff;
        background: linear-gradient(135deg, var(--sig-orange), var(--sig-amber));
        box-shadow: 0 8px 20px rgba(221, 128, 54, .30);
        transform: translateY(6px); transition: transform .25s ease;
    }
    .cell.pro-teaser:hover .pro-more .pm-label,
    .pro-more:focus-visible .pm-label { transform: none; }
}

/* The recap's explicit "Learn more". Not a DS `.btn-*` variant: amber is the Pro voice and
   belongs to the sell surfaces, not to the general button set. */
.pw-learn {
    align-self: center; width: 100%; max-width: 420px; margin-top: 26px; color: #fff;
    background: linear-gradient(135deg, var(--sig-orange), var(--sig-amber));
    box-shadow: 0 10px 26px rgba(221, 128, 54, .30);
}
.pw-learn:hover { transform: translateY(-2px); }
/* Once the paywall is open this button is spent: it sits directly above the offer it opens,
   so unlike the in-cell teasers it cannot even degrade into a jump link. Keyed on the
   unfolded wrapper rather than on its own click handler so the auto-unfold path (SEEN+READ)
   clears it identically — that user never clicked anything and must not be left with a
   button that does nothing. The teasers deliberately do NOT get this treatment: on ≤760px
   they are in the flow of their cells, and removing five of them would collapse the table
   at the moment the offer grows below it. */
.screen:has(.anim-unfold.in) .pw-learn { display: none; }

@media (max-width: 760px) {
    .vb-pair { grid-template-columns: 1fr; }
    .vb-card.pro { transform: none; }
    /* The comparison table stacks to one column, so each row reads "today, free" THEN
       "with Pro". The shared column headers can no longer label anything, so they are
       replaced by a per-cell ::before — drop these and the stacked cells lose all sense
       of which side of the comparison they are on. */
    .cmp-head { display: none; }
    .cmp-row { grid-template-columns: 1fr; }
    .cmp-row .cell.free::before,
    .cmp-row .cell.pro::before {
        display: block; margin-bottom: 6px;
        font-size: 11px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase;
    }
    .cmp-row .cell.free::before { content: "Today, free"; color: var(--ink-soft); }
    .cmp-row .cell.pro::before { content: "With Pro"; color: var(--pro); }
    /* one fact per line — two narrow cards side by side would hyphenate the result values */
    .done { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    .fo-sent .err, .fo-sent .band-chip, .fo-sent .fo-note,
    .bp-more, .bp-block .bp-open,
    .o1-legend .lay-item, .xprompt .seg,
    .the-prompt .seg, .lay-form.collapsing,
    .sw-seg .seg::before,
    .answer-line .part,
    .mic-eq .eq-bar { transition: none !important; }
    /* Screen 0's stepper swaps instantly — the rail is a state indicator, and the step
       body arrives in place (the JS skips the fade-out half too, so a swap is one paint) */
    .step, .step .step-num, .step + .step::before { transition: none !important; }
    .step-body { transition: none !important; opacity: 1 !important; transform: none !important; }
    /* the paywall arrives fully open, no growth and no fade (_paywall.js skips the
       animation too — this covers a setting changed after the screen rendered) */
    .anim-unfold { grid-template-rows: 1fr !important; transition: none !important; }
    .anim-unfold .pw-unit { opacity: 1 !important; transform: none !important; transition: none !important; }
}
@media (max-width: 560px) {
    .tone-grid { grid-template-columns: 1fr; }
}
