/* ───────────────────────────────────────────────────────────────
   /lesson/ — profit maximization.

   ⚠ COHERENCE CONSTRAINT. This is a teaching surface. Decoration
   reduces learning (seductive details g = −0.16 on the best current
   estimate — smaller than the −0.37 once quoted, but the mechanism is
   what matters: motion is a scarce signalling budget). The only motion allowed is motion that carries
   meaning: an element appearing at the moment it is named. That is
   signalling (g = 0.38), not ornament. Nothing here tilts, wobbles,
   bounces or pulses. Do not "improve" this.

   And: on-screen text is LABELS, never sentences. Narration plus
   duplicated prose is the redundancy principle's failure case.
   ─────────────────────────────────────────────────────────────── */

body { font-variation-settings: "MONO" 0, "CASL" .3, "slnt" 0; padding: 0 0 4rem; }
.wrap { max-width: 74rem; margin-inline: auto; padding-inline: 1.4rem; }

.bar { display: flex; justify-content: space-between; align-items: baseline;
       padding: 1.5rem 0 1.4rem; font-size: .88rem; }
.bar .mark { font-variation-settings: "MONO" 0, "CASL" .3, "wght" 640; }
.bar a { text-decoration: none; color: var(--ink-soft); display: inline-block;
         padding: .15rem .2rem; margin: -.15rem -.2rem; }
.bar a:hover { color: var(--pipe); }

h1 { font-size: clamp(1.3rem, 1.1rem + 1vw, 1.65rem); margin: 0 0 .35rem;
     font-variation-settings: "MONO" 0, "CASL" .3, "wght" 600; letter-spacing: -.012em; }
.sub { color: var(--ink-soft); margin: 0 0 1.3rem; font-size: .95rem; max-width: 62ch; }

/* ── concept bar ────────────────────────────────────────────────
   past → bright, now → the accent, ahead → dimmer but still readable.
   Each state also carries a marker glyph so colour is never the only
   channel (WCAG 1.4.1).

   CORRECTION 2026-08-08. This comment used to claim the "ahead" state was
   exempt from SC 1.4.3 as an inactive item, and it measured 2.22:1 on the
   rail. That was a misreading, and worth naming because the file was
   teaching it to the next person who opened it: 1.4.3's exemption covers
   inactive USER INTERFACE COMPONENTS. A list item is not a control — it is
   text, and it is text a reader is meant to read, since the whole point of
   showing pending concepts is to show scope. So it needs 4.5:1 like any
   other text. color-mix at 52% measures 4.82:1 on the #232420 rail (50% is
   the first passing step at 4.57:1; 52% buys margin).            */
.vocab { background: var(--ink); border-radius: 10px; list-style: none;
         padding: .55rem .85rem; margin: 0 auto 1.1rem;
         display: flex; gap: .7rem 1.05rem; flex-wrap: wrap;
         width: min(100%, calc(2 * var(--sh) + 0.9rem)); }
.v-item { display: flex; gap: .5ch; align-items: baseline; font-size: .79rem;
          line-height: 1.3; white-space: nowrap; transition: color 300ms ease; }
.v-mark { font-variation-settings: "MONO" 1, "CASL" 0; }
.v-item.soon { color: color-mix(in srgb, var(--bg) 52%, var(--ink)); }
.v-item.now  { color: var(--coral); font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }
.v-item.past { color: var(--bg); }

/* ── stage: HEIGHT-driven ───────────────────────────────────────
   Both frames are anchored to height — video 2:3, surface 4:3 — so a
   single --sh determines everything and neither pane is ever squeezed
   by a percentage split. Nothing resizes between states.         */
:root { --sh: min(calc((min(74rem, 100vw - 2.8rem) - 0.9rem) / 2), 33rem); }

.stage { display: flex; gap: .9rem; height: var(--sh);
         width: min(100%, calc(2 * var(--sh) + 0.9rem));
         margin: 0 auto 2.4rem; }
.stage[data-mode="done"] { height: auto; }
.stage[data-mode="done"] .pane { display: none; }

.pane { position: relative; min-width: 0; display: flex; flex-direction: column;
        align-self: flex-start; }
#left  { flex: 1 1 auto; }
#right { flex: 0 0 auto; }

.frame { border: 2px solid var(--ink); border-radius: 12px; background: var(--card);
         overflow: hidden; position: relative; display: grid; }
#left .frame  { height: var(--sh); width: 100%; }
#right .frame { height: var(--sh); width: calc(var(--sh) * 4 / 3); }
.layer { grid-area: 1 / 1; min-width: 0; }

.pane .cap { font-size: .72rem; color: var(--ink-faint); margin: .45rem 0 0;
             letter-spacing: .04em; display: flex; justify-content: space-between; gap: 1rem; }
.vtime { font-variation-settings: "MONO" 1, "CASL" 0; white-space: nowrap; }

/* ── the video ──────────────────────────────────────────────────
   The boundary ramp is HERE, not baked into the encode. That keeps it
   reversible, lets it target the page background rather than black —
   a fade to black inside a cream page is a large luminance excursion
   that spends more attention than it saves — and lets it switch off
   under prefers-reduced-motion, which a fade in the pixels cannot. */
#left .frame { background: var(--bg-tint); }
#vid { width: 100%; height: 100%; object-fit: cover; display: block;
       background: var(--ink); cursor: pointer;
       opacity: 1; transition: opacity 260ms ease; }
#warm { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.stage[data-video="off"] #vid,
.stage[data-video="off"] .bigplay,
.stage[data-video="off"] .vbar { visibility: hidden; }

/* one big affordance, because the first block can't autoplay with sound
   until the browser has seen a gesture */
.bigplay { grid-area: 1 / 1; place-self: center; z-index: 2;
           width: 4.4rem; height: 4.4rem; border-radius: 50%; cursor: pointer;
           border: 0; padding: 0; display: grid; place-items: center;
           background: color-mix(in srgb, var(--ink) 82%, transparent);
           transition: opacity 200ms ease, transform 200ms var(--fold),
                       visibility 0s linear 200ms; }
.bigplay svg { width: 1.9rem; height: 1.9rem; fill: var(--bg); margin-left: .18rem; }
.bigplay:hover { transform: scale(1.06); }
/* Keyed off data-started, not data-playing: once this segment has begun, the
   overlay is gone for good. It used to come back on pause AND on `ended` —
   which, now that the last frame is held rather than faded away, meant a large
   dark disc parked over his face for the whole of an activity block.
   visibility, not just opacity + pointer-events: opacity:0 leaves the button in
   the tab order and in the accessibility tree, which is an SC 2.4.7 failure
   (a focusable control with no visible focus indicator, because it has no
   visible anything). The 200ms visibility delay lets the fade finish first. */
.stage[data-started="yes"] .bigplay { opacity: 0; visibility: hidden; pointer-events: none; }

.vbar { height: 3px; background: var(--rule); border-radius: 2px; margin-top: .4rem;
        overflow: hidden; }
.vprog { display: block; height: 100%; width: 0%; background: var(--pipe);
         transition: width 220ms linear; }

/* ── the working surface ────────────────────────────────────── */
.surface { padding: 1rem 1.15rem; overflow: auto; }

/* Everything cue-driven starts hidden and arrives when it is named.
   A short rise, not a bounce — the motion says "this is the thing he
   just said", which is the only justification it has. */
.sc [data-k], .ph-intro [data-k] {
  opacity: 0; transform: translateY(6px);
  transition: opacity 420ms ease, transform 420ms var(--fold);
}
.sc [data-k].on, .ph-intro [data-k].on { opacity: 1; transform: none; }

.sc-eyebrow { margin: 0 0 .7rem; font-size: .68rem; letter-spacing: .13em;
              text-transform: uppercase; color: var(--ink-faint);
              font-variation-settings: "MONO" 0, "CASL" .3, "wght" 620; }
.sc-list { list-style: none; padding: 0; margin: 0; display: grid; gap: .55rem; }
.sc-row { display: flex; align-items: baseline; gap: .6ch; font-size: .98rem; flex-wrap: wrap; }
.sc-who { font-variation-settings: "MONO" 0, "CASL" .3, "wght" 640; }
.sc-arrow { color: var(--ink-faint); }
.sc-what { color: var(--ink-soft); }
.sc-row.lit .sc-who, .sc-row.lit .sc-what { color: var(--pipe); }
.sc-title { margin: 1.1rem 0 .2rem; font-size: 1.18rem;
            font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }
.sc-axes { display: block; width: 100%; max-width: 24rem; height: auto; margin-top: .5rem; }

.sc-formula { margin: 0 0 .9rem; font-size: 1.06rem;
              font-variation-settings: "MONO" 0, "CASL" .3, "wght" 560; }
.sc-formula.sm { font-size: .96rem; margin-bottom: .5rem; }
.f-p  { color: var(--num); font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }
.f-tr, .f-mr { color: var(--str); }
.f-tc, .f-mc { color: var(--pipe); }

.sc-curve, .sc-two { display: block; width: 100%; height: auto; }
.sc-curve { max-width: 26rem; }
.sc-q { fill: var(--pipe); font-size: 10px; font-family: var(--mono); }
.sc-ring { fill: none; stroke: var(--pipe); stroke-width: 2.5; }
.sc-rule { border-top: 1.5px dashed var(--rule); margin: 1rem 0 .8rem; }

/* No tinted background. A 14–16% wash of the tag's own colour behind its own
   text measured 3.95–4.38:1 — the tint eats exactly the contrast the colour
   was carrying. A left rule identifies the tag and costs nothing. */
.sc-tag { font-size: .78rem; letter-spacing: .02em; padding: 0 0 0 .45rem;
          border-left: 3px solid currentColor; white-space: nowrap;
          font-variation-settings: "MONO" 0, "CASL" .3, "wght" 640; }
.tag-mr { color: var(--str); }
.tag-mc { color: var(--pipe); }
.tag-p  { color: var(--num); }
.sc-defs .sc-what em { font-style: normal;
                       font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }

.sc-barkey { display: flex; gap: .9rem; margin: 0 0 .5rem; flex-wrap: wrap; }
.sc-chips { list-style: none; padding: 0; margin: 0 0 .9rem;
            display: flex; gap: .4rem; flex-wrap: wrap; }
.sc-chips li { font-size: .76rem; padding: .14rem .5rem; border-radius: 999px;
               border: 1.5px solid var(--rule); color: var(--ink-soft); }

/* ── the three-numbers explainer that becomes the hunt tool ──── */
.ph-intro { margin: 0 0 .2rem; }
.sc-slots { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; }
.sc-slots li { display: flex; align-items: baseline; gap: .7ch; flex-wrap: wrap; }
.sc-formal { font-size: .84rem; color: var(--ink-faint); opacity: 0;
             transition: opacity 400ms ease; }
.ph-intro.formal .sc-formal { opacity: 1; }

/* dormant: the tool exists but is not yet the learner's to touch */
.dormant .w-ask, .dormant .w-count, .dormant .w-stepper,
.dormant .w-books, .dormant .w-plot,
.dormant .w-hint, .dormant .w-escape { display: none; }
.live .ph-intro { display: none; }
.mg-legend { display: flex; gap: .9rem; margin: 0 0 .5rem; flex-wrap: wrap; }
.dormant .mg-legend { margin-bottom: .8rem; }

/* ── in-lesson corrections ──────────────────────────────────────
   Two places the narration misspeaks. The callout owns the slip at the
   moment it happens rather than an edit hiding it — which is the same
   move the rest of this site makes: state the limit out loud and be the
   one who noticed. Dismissible, and it never blocks anything. */
/* --card, not --bg-tint: the tint dropped the coloured tags inside this box to
   4.08–4.46:1. A full rule plus the accent edge separates it just as well. */
.mg-fix { margin: .7rem 0; padding: .7rem .8rem; border-radius: 9px;
          background: var(--card); border: 1.5px solid var(--rule);
          border-left: 3px solid var(--num); }
.mg-fix p { margin: 0 0 .55rem; font-size: .86rem; line-height: 1.55; color: var(--ink); }
.mg-fix em { font-style: normal; font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }
.mg-fix .sc-tag { border-left-width: 3px; }
.mg-fix-x { font: inherit; font-size: .78rem; cursor: pointer; padding: .22rem .7rem;
            border: 1.5px solid var(--ink); border-radius: 7px;
            background: var(--card); color: var(--ink); }
.mg-fix-x:hover { background: color-mix(in srgb, var(--yellow) 50%, transparent); }
.sc-recap .mg-fix { margin-top: .9rem; }

/* ── focus ────────────────────────────────────────────────────
   The kernel sets a 2px --ink ring on every focusable thing. These rules used
   to end in `outline: none`, leaving only a yellow wash or a colour swap as the
   focus signal — measured at a 1.11:1 change on the steppers and 2.84:1 on the
   commit button, i.e. under both SC 2.4.7 (visible focus) and the 3:1 that
   SC 1.4.11 wants of a focus indicator. WCAG technique F78 names both criteria
   for precisely this construction. The washes stay as secondary reinforcement;
   the ring is what makes it conformant.
   --ink measures 15.24:1 on --card, 13.84:1 on --bg and 12.67:1 on --bg-tint,
   so one declaration covers every surface the lesson paints.        */
.w-step:focus-visible, .w-commit:focus-visible, .q-opt:focus-visible,
.w-escape:focus-visible, .w-slider:focus-visible, .mg-fix-x:focus-visible,
.transport button:focus-visible, #blocks button:focus-visible,
.transcript > summary:focus-visible, .after-btn:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* ── widgets ────────────────────────────────────────────────── */
.w-ask { margin: 0 0 .8rem; font-size: .95rem; line-height: 1.5;
         font-variation-settings: "MONO" 0, "CASL" .3, "wght" 540; }
.w-ask em { font-style: normal; font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }

.w-count { display: flex; align-items: center; gap: .6rem; margin: 0 0 .75rem; flex-wrap: wrap; }
.pips { display: flex; gap: .3rem; }
.pip { width: .72rem; height: .72rem; border-radius: 50%;
       border: 1.5px solid var(--ink); background: transparent; }
.pip.on { background: var(--pipe); border-color: var(--pipe); }
.w-countlab { font-size: .82rem; color: var(--ink-soft); }

.w-stepper { display: flex; align-items: center; gap: .5rem; margin: 0 0 .7rem; flex-wrap: wrap; }
.w-step { width: 2.1rem; height: 2.1rem; border: 2px solid var(--ink); border-radius: 8px;
          background: var(--bg-tint); color: var(--ink); font: inherit; font-size: 1.05rem;
          cursor: pointer; line-height: 1; }
.w-step:hover, .w-step:focus-visible {
  background: color-mix(in srgb, var(--yellow) 55%, transparent); }
.w-qty { min-width: 2.4rem; text-align: center; font-size: 1.3rem;
         font-variation-settings: "MONO" 1, "CASL" .3, "wght" 680; }
.w-commit { border: 2px solid var(--ink); border-radius: 9px; background: var(--ink);
            color: var(--bg); font: inherit; font-size: .88rem; padding: .45rem .9rem;
            cursor: pointer; font-variation-settings: "MONO" 0, "CASL" .3, "wght" 600; }
.w-commit:hover, .w-commit:focus-visible {
  background: var(--pipe); border-color: var(--pipe); }

.w-books { display: flex; gap: 1.3rem; margin: 0 0 .7rem; flex-wrap: wrap; }
.w-books div { display: flex; flex-direction: column; }
.w-books dt { font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.w-books dd { margin: 0; font-size: 1.02rem; font-variation-settings: "MONO" 1, "CASL" .3, "wght" 620; }
.w-books .lead dd { font-size: 1.35rem; color: var(--num); }
.w-books dd.neg { color: var(--pipe); }
.w-pending { margin: 0; color: var(--ink-soft); font-size: .88rem; }

.w-hint { font-size: .85rem; color: var(--ink-soft); margin: .6rem 0 .5rem; line-height: 1.5; min-height: 1.2em; }
/* --ink-soft, not --ink-faint: this control also appears inside .coda, whose
   background is --bg-tint, where --ink-faint measures 4.29:1. --ink-soft is
   5.01:1 there and 6.02:1 on --card, and reads just as recessive. */
.w-escape { background: none; border: 0; font: inherit; font-size: .78rem; color: var(--ink-soft);
            text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: .2rem 0; }
.w-escape:hover { color: var(--pipe); }
.solved .w-escape { visibility: hidden; }

/* The value sits OUTSIDE the label now (it was mutating the slider's accessible
   name on every drag — see firm.js), so it needs its own styling and the label
   has to stop being a block or the two land on separate lines. */
.w-slabel { font-size: .86rem; color: var(--ink-soft); line-height: 1.5; }
.w-sout { font-size: .86rem; margin-left: .5ch;
          font-variation-settings: "MONO" 1, "CASL" .3, "wght" 680; color: var(--num); }
.w-slider { display: block; width: 100%; margin: .5rem 0 .4rem; accent-color: var(--pipe); }
.w-verdict { font-size: .88rem; margin: .3rem 0 0; color: var(--ink-soft); }
.w-verdict em { color: var(--pipe); font-style: normal;
                font-variation-settings: "MONO" 0, "CASL" .3, "wght" 620; }
.w-aside { display: block; margin-top: .4rem; color: var(--ink-soft); line-height: 1.55; }

.w-plot, .w-bars { display: block; width: 100%; max-width: 30rem; height: auto; }
.w-sr, .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* plot marks — flat, no gradients, no shadows.

   Three of these were measured failing SC 1.4.11 Non-text Contrast, which
   asks 3:1 of graphical objects a reader needs in order to understand the
   content. All three were --rule (#e2dbd0), a hairline token doing work it
   is too light for:
     · axes and the zero line at 1.66:1 → --ink-faint (#616f66), 5.16:1
     · OFF-state bars at 1.34:1 → #9c9182, 3.02:1. This was the load-bearing
       one: on/off IS how the block-4 marker position reads, and at 1.34:1 it
       did not read at all.
     · the resting .q-opt border, below → --ink-faint
   --rule keeps its job as a decorative divider elsewhere, where 1.4.11 does
   not apply because nothing depends on seeing it.                       */
.ax     { stroke: var(--ink-faint); stroke-width: 1.5; }
.zero   { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 3 3; }
.tick   { fill: var(--ink-faint); font-size: 9px; font-family: var(--mono); }
.axlab  { fill: var(--cmt); font-size: 9.5px; font-family: var(--mono); }
.pt     { fill: var(--pipe); }
.ptlab  { fill: var(--ink-soft); font-size: 8.5px; font-family: var(--mono); }
.curve  { fill: none; stroke: var(--pipe); stroke-width: 2.5; stroke-linejoin: round; }
.curve.soft { stroke: #9c9182; stroke-width: 2; }
.peak   { stroke: var(--ink); stroke-width: 1.5; stroke-dasharray: 4 3; }
.rv-h   { fill: var(--cmt); font-size: 10px; font-family: var(--mono); letter-spacing: .08em; }
.bar-mr { fill: #9c9182; } .bar-mr.on { fill: var(--str); }
.bar-mc { fill: #9c9182; } .bar-mc.on { fill: var(--num); }
.key-mr { fill: var(--str); }  .key-mc { fill: var(--num); }
.marker { stroke: var(--pipe); stroke-width: 2.5; }

/* ── the closing question ───────────────────────────────────── */
.q-opts { list-style: none; padding: 0; margin: 0; display: grid; gap: .45rem; }
.q-opt { width: 100%; text-align: left; font: inherit; font-size: .88rem; line-height: 1.45;
         background: var(--bg-tint); color: var(--ink); border: 2px solid var(--ink-faint);
         border-radius: 9px; padding: .55rem .7rem; cursor: pointer; }
.q-opt:hover, .q-opt:focus-visible { border-color: var(--ink); }
.q-opt.picked.right { border-color: var(--str); background: color-mix(in srgb, var(--str) 12%, transparent); }
.q-opt.picked.wrong { border-color: var(--pipe); }
.q-fb { margin: .7rem 0 0; padding: .65rem .75rem; border-radius: 9px; font-size: .86rem;
        line-height: 1.55; border-left: 3px solid var(--rule); background: var(--bg-tint); }
.q-fb.right { border-left-color: var(--str); }
.q-fb.wrong { border-left-color: var(--pipe); }
.q-fb .again { margin-top: .6rem; display: block; }

/* ── transport ──────────────────────────────────────────────── */
.transport { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
             padding-top: .9rem; border-top: 1.5px dashed var(--rule); }
.transport button { font: inherit; font-size: .85rem; padding: .4rem .8rem; cursor: pointer;
                    border: 2px solid var(--ink); border-radius: 8px;
                    background: var(--card); color: var(--ink); }
.transport button:hover:not(:disabled) { background: color-mix(in srgb, var(--yellow) 50%, transparent); }
/* A disabled control is an inactive user interface component, which is what
   SC 1.4.3 actually exempts — so this is allowed to sit under 4.5:1 (it
   measures 2.27:1). Raised from .38 to .5 anyway: the exemption makes it
   conformant, not readable, and there is no reason to make it harder to read
   than it has to be. */
.transport button:disabled { opacity: .5; cursor: default; }
#continue { background: var(--ink); color: var(--bg); }
#continue:hover:not(:disabled) { background: var(--pipe); border-color: var(--pipe); }
.readynote { font-size: .82rem; color: var(--str); }
#cc { font-variation-settings: "MONO" 1, "CASL" 0, "wght" 700; letter-spacing: .04em; }
#cc.on { background: var(--ink); color: var(--bg); }
.skip { border-style: dashed !important; color: var(--ink-soft) !important; }
.sub-len { display: block; margin-top: .3rem; color: var(--ink-faint); font-size: .88em; }
video::cue { background: color-mix(in srgb, var(--ink) 86%, transparent); color: var(--bg);
             font-family: var(--mono); font-size: .82em; }
#blocks { display: flex; gap: .3rem; margin-left: auto; }
#blocks button { width: 1.9rem; height: 1.9rem; padding: 0; font-size: .76rem;
                 border-width: 1.5px; border-color: var(--rule); }
#blocks button.done { color: var(--ink-faint); }
#blocks button.on { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.budget { font-size: .78rem; color: var(--ink-faint); margin: .7rem 0 0; }

/* ── the end ────────────────────────────────────────────────── */
#done { margin: 1.4rem 0 0; padding: 1.1rem 1.2rem; border: 2px solid var(--ink);
        border-radius: 12px; background: var(--card); }
#done h2 { margin: 0 0 .5rem; font-size: 1.05rem;
           font-variation-settings: "MONO" 0, "CASL" .3, "wght" 620; }
#done h3 { margin: 0 0 .4rem; font-size: .92rem;
           font-variation-settings: "MONO" 0, "CASL" .3, "wght" 620; }
#done p { margin: 0 0 .8rem; color: var(--ink-soft); font-size: .93rem; line-height: 1.6; }
#done a { color: var(--ink); }
.coda { margin: 1.1rem 0; padding: .95rem 1rem 1rem; border: 1.5px dashed var(--rule);
        border-radius: 10px; background: var(--bg-tint); }
.coda .w-plot { max-width: 23rem; }
.coda-out { margin: .9rem 0 0; font-size: .88rem; }

/* ── the one commercial line, at the end ──────────────────────── */
.after { margin: 1.2rem 0 .4rem; padding-top: 1rem; border-top: 1.5px solid var(--rule); }
.after-lead { margin: 0 0 .8rem !important; color: var(--ink) !important;
              font-variation-settings: "MONO" 0, "CASL" .3, "wght" 540; }
.after-act { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
             margin: 0 !important; }
/* #done a is specificity 101 and would win over a bare .after-btn class (010),
   painting --ink on --ink — an invisible button, measured at 1.00:1. Scoped
   here so it beats it rather than relying on source order. */
#done a.after-btn { display: inline-block; background: var(--ink); color: var(--bg);
             border: 2px solid var(--ink); border-radius: 9px; padding: .5rem 1rem;
             text-decoration: none; font-size: .9rem;
             font-variation-settings: "MONO" 0, "CASL" .3, "wght" 580;
             box-shadow: 3px 3px 0 var(--pipe);
             transition: transform 150ms var(--fold), box-shadow 150ms var(--fold); }
#done a.after-btn:hover, #done a.after-btn:focus-visible { color: var(--bg);
             transform: translate(-1px,-1px); box-shadow: 5px 5px 0 var(--pipe); }
.after-note { font-size: .85rem; color: var(--ink-soft); }
#done .after-note a { color: var(--ink-soft); }

/* ── transcript ───────────────────────────────────────────────── */
.transcript { margin: 2rem 0 0; padding-top: 1.1rem; border-top: 1.5px dashed var(--rule); }
.transcript > summary { cursor: pointer; font-size: .88rem; color: var(--ink-soft);
                        font-variation-settings: "MONO" 0, "CASL" .3, "wght" 580;
                        padding: .3rem .4rem; margin: -.3rem -.4rem; border-radius: 6px; }
.transcript > summary:hover { background: color-mix(in srgb, var(--yellow) 45%, transparent); }
.tr-body { max-width: 68ch; margin-top: .9rem; }
.tr-h { font-size: .82rem; letter-spacing: .06em; text-transform: uppercase;
        color: var(--ink-faint); margin: 1.6rem 0 .5rem;
        font-variation-settings: "MONO" 0, "CASL" .3, "wght" 620; }
.tr-h:first-child { margin-top: 0; }
.tr-len { font-variation-settings: "MONO" 1, "CASL" 0, "wght" 400; letter-spacing: 0;
          text-transform: none; }
.tr-body p { margin: 0 0 .8rem; color: var(--ink-soft); font-size: .93rem; line-height: 1.65; }
.tr-fix { border-left: 3px solid var(--num); padding-left: .8rem;
          color: var(--ink) !important; }
.tr-fix em { font-style: normal; font-variation-settings: "MONO" 0, "CASL" .3, "wght" 680; }
.tr-loading { color: var(--ink-faint) !important; }

/* ── mobile: stack, surface on top ──────────────────────────── */
@media (max-width: 860px) {
  .stage { flex-direction: column; height: auto; width: 100%; gap: 1.4rem; }
  #left, #right { flex: 0 0 auto; width: 100%; }
  #right { order: -1; }
  #right .frame { height: auto; width: 100%; aspect-ratio: 4 / 3; }
  #left .frame { height: auto; aspect-ratio: 2 / 3; max-height: 70vh; }
  .vocab { width: 100%; }
  #blocks { margin-left: 0; flex-wrap: wrap; }
}

@media (prefers-reduced-motion: reduce) {
  .sc [data-k], .ph-intro [data-k] { transition: opacity .01ms; transform: none; }
  .vprog { transition: none; }
  #vid { transition: none; }        /* only possible because the fade isn't baked in */
}
