/* ==========================================================================
   course.vanpraag.ai — the participant watch page.

   ROUND 2 (18.8.2026). Leib's instruction: this page must sit at the design
   level of the new homepage, and must feel like the same house. The reference
   is Website/index-v2.html ("Gold Silk"), not the older site.

   What is carried over from index-v2, deliberately and by name:
     · the three-gold discipline (see the token block below)
     · .kicker — hairline + letterspaced eyebrow in gold-deep
     · serif display headings, tight leading, negative tracking
     · .rule — the short gold gradient bar under a section head
     · alternating cream / .alt white bands with hairline edges
     · .card with the hover lift, .facts pill row, .spec definition list
     · the console motif: .panel + .phead (live dot · label · mono tag)
     · the .board / .ch row list with mono machine text and tabular numerals
     · .btn-gold (gold-deep, white) and .btn-ghost — the site-wide button rule
     · .reveal scroll-in, plus index-v2's safety net and its body.qa switch

   TWO THINGS DELIBERATELY NOT COPIED FROM index-v2 — both measured, not felt:

   1. Fraunces has no Hebrew. A Hebrew page cannot inherit the homepage's
      display face, so the pairing is translated rather than copied:
      FRANK RUHL LIBRE (Yanek Iontef / Fontef, 2015; fsType 0, embedding
      permitted) carries the Hebrew display voice. It is the contemporary
      Frank Ruhl — an old-style Hebrew serif drawn for screen — which is the
      same editorial register Fraunces has in Latin. Fraunces itself is still
      here, subset to seven glyphs, for the one Latin thing on the page: the
      "Van Praag" wordmark. Same lockup as the homepage header.

   2. index-v2 puts an 11.5px gold-deep .kicker on a --panel ground, in the
      workshop strip. Measured: gold-deep on panel is 4.30:1, which is
      large-text-only and fails AA for an eyebrow that size. This page never
      places small gold text on panel. Kickers sit on cream (4.65) or on
      white (4.94) only, and the strip carries no eyebrow at all.

   Contrast, measured rather than assumed (audience is 30-60, older eyes):
     ink  #211C13 on cream #FAF6EC  15.69   display + body
     ink  on white  #FFFDF7         16.65   card text
     soft #6A6250 on cream           5.60   secondary
     soft on panel #F5EDD9           5.18   secondary on a panel
     gold-deep #8A6A2F on cream      4.65   kickers, small gold text
     gold-deep on white              4.94   kickers inside a card
     #fff on gold-deep               5.02   the primary button
     ink on gold #B8891F             5.35   the numbered disc
     gold #B8891F on cream           2.93   FILLS AND RULES ONLY, never text
     brick #8C3A1E on cream          7.10   the one error line

   Zero CDN, zero network requests. Fonts are local and subset to the glyphs
   this page can contain (90 KB for six faces), so it renders identically on a
   phone hotspot and with the wifi off.
   ========================================================================== */

/* ── the type system ──────────────────────────────────────────────────────
   Assistant is the brand sans and is SHIPPED, not merely named: naming it
   without a @font-face is how the homepage once rendered every visitor's body
   copy in Segoe UI while looking correct on the one machine that has it. */

@font-face { font-family:"Assistant"; src:url("assistant-400.woff2") format("woff2");
  font-weight:400; font-style:normal; font-display:swap }
@font-face { font-family:"Assistant"; src:url("assistant-600.woff2") format("woff2");
  font-weight:600; font-style:normal; font-display:swap }
@font-face { font-family:"Assistant"; src:url("assistant-800.woff2") format("woff2");
  font-weight:800; font-style:normal; font-display:swap }

/* Hebrew display. Medium, not Bold: at h1 size the Medium has the same quiet
   authority Fraunces has at weight 450 on the homepage. */
@font-face { font-family:"Frank Ruhl Libre"; src:url("frankruhl-500.woff2") format("woff2");
  font-weight:500; font-style:normal; font-display:swap }
@font-face { font-family:"Frank Ruhl Libre"; src:url("frankruhl-700.woff2") format("woff2");
  font-weight:700; font-style:normal; font-display:swap }

/* Seven glyphs of the homepage's own display face, for the wordmark only.
   Declared exactly as index-v2 declares it, so the lockup matches.
   unslop-ignore: cream + Fraunces is flagged as the "tasteful default" palette,
   and the scanner's own fix is "anchor to an actual brand or reference" — this
   IS the anchor. It is here because Website/index-v2.html uses this exact face
   for this exact lockup, not because it was the pleasant thing to reach for. */
@font-face { font-family:"Fraunces"; src:url("fraunces-wordmark.woff2") format("woff2-variations");
  font-weight:100 900; font-display:swap }

:root {
  --cream:#FAF6EC; --panel:#F5EDD9; --white:#FFFDF7;
  --ink:#211C13; --soft:#6A6250;

  /* TWO golds plus a text gold, and the distinction is accessibility, not
     taste. Collapsing them is what broke contrast for 40-60-year-old eyes on
     the homepage's first pass.
       --gold-bright  large shapes, gradient ends, hairlines
       --gold         2.93:1 on cream — FILLS ONLY, never text
       --gold-deep    4.65:1 on cream — kickers, links, any gold text        */
  --gold:#B8891F; --gold-bright:#D6A85E; --gold-deep:#8A6A2F;
  --brick:#8C3A1E;

  --line:rgba(184,137,31,.30);
  --hair:rgba(184,137,31,.14);
  --maxw:1180px;

  --serif:"Frank Ruhl Libre","David Libre","Frank Ruehl",Georgia,serif;
  --sans:"Assistant","Arial",sans-serif;
  --wordmark:"Fraunces",Georgia,serif;   /* unslop-ignore: see the @font-face note */
  --mono:ui-monospace,"SF Mono","Cascadia Mono","Segoe UI Mono","Roboto Mono",Menlo,monospace;

  --shadow:0 30px 60px -34px rgba(60,45,15,.42), 0 2px 5px -2px rgba(60,45,15,.10);
  --shadow-card:0 24px 50px -30px rgba(60,45,15,.40);
}

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

/* .btn is inline-flex, which outranks the UA rule for [hidden]. Caught in a
   render last round, not in the source. */
[hidden] { display:none !important }

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

body {
  margin:0; background:var(--cream); color:var(--ink);
  font-family:var(--sans); font-weight:400; font-size:17.5px; line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
img { max-width:100%; display:block }
a { color:inherit }

/* Nothing flashes while /api/session and /api/manifest decide what to show. */
body.booting main, body.booting .foot { visibility:hidden }

.wrap { max-width:var(--maxw); margin:0 auto; padding:0 clamp(18px,5vw,56px) }

/* Latin inside Hebrew must be isolated AND given its own direction — isolate
   alone still lets a trailing digit run reorder. Measured, 17.8. */
.lat { direction:ltr; unicode-bidi:isolate }
.mono {
  font-family:var(--mono); font-variant-numeric:tabular-nums; letter-spacing:-.01em;
  direction:ltr; unicode-bidi:isolate;
}

/* ── shared type ──────────────────────────────────────────────────────────
   Hebrew has no case, so index-v2's text-transform:uppercase eyebrow cannot
   be reproduced. Letterspacing does the same work at .09em; past about .12em
   Hebrew letters stop reading as words. */
.kicker {
  display:flex; align-items:center; gap:13px;
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:.09em;
  color:var(--gold-deep); margin:0 0 18px;
}
.kicker::before {
  content:""; width:44px; height:1px; background:var(--gold); opacity:.6; flex:0 0 auto;
}

h1, h2 { font-family:var(--serif); font-weight:500; letter-spacing:0; margin:0 }
h1 { font-size:clamp(2rem,4.4vw,3.5rem); line-height:1.12; max-width:24ch; text-wrap:balance }
h2 { font-size:clamp(1.65rem,3vw,2.5rem); line-height:1.14; max-width:26ch }
h3 { font-family:var(--sans); font-weight:800; font-size:1.02rem; line-height:1.35; margin:0 }

.lede { font-size:clamp(1rem,1.3vw,1.14rem); color:var(--soft); max-width:44ch; margin:16px 0 0 }
.sub  { font-size:1rem; color:var(--soft); max-width:52ch; margin:14px 0 0 }

/* `to left` so the bright end sits at the reading edge, which in RTL is the
   right. A 90deg gradient puts the bright end where nobody starts reading. */
.rule {
  height:2px; width:64px; border-radius:2px; margin:26px 0 0;
  background:linear-gradient(to left,var(--gold-bright),var(--gold));
}

/* ── buttons ──────────────────────────────────────────────────────────── */

.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  border-radius:999px; padding:13px 25px; border:0;
  font-family:var(--sans); font-size:15px; font-weight:600; line-height:1.2;
  text-decoration:none; white-space:nowrap; cursor:pointer;
  transition:transform .25s cubic-bezier(.2,.7,.3,1), box-shadow .25s, border-color .25s, background .2s;
}
.btn-gold {
  background:var(--gold-deep); color:#fff;
  box-shadow:0 10px 26px -12px rgba(184,137,31,.75);
}
.btn-gold:hover { transform:translateY(-2px); box-shadow:0 16px 34px -12px rgba(184,137,31,.85) }
.btn-ghost {
  border:1px solid var(--line); color:var(--ink); background:rgba(255,255,255,.55);
}
.btn-ghost:hover { transform:translateY(-2px); border-color:var(--gold) }
.btn-sm { padding:10px 19px; font-size:14px }
.btn:active { transform:translateY(0) }
/* Measured at 390px: .btn-sm came out 37px tall, under the 44px touch floor.
   A mouse does not need the extra height, so this is scoped to touch. */
@media (hover:none) { .btn, .hlink { min-height:44px } }

:where(a,button):focus-visible { outline:3px solid var(--gold-bright); outline-offset:2px }

/* ── ב״ה and the header ───────────────────────────────────────────────── */

.bh {
  position:absolute; top:7px; left:50%; transform:translateX(-50%);
  font-size:11px; color:var(--soft); z-index:21;
}

header { position:fixed; inset:0 0 auto; z-index:20; backdrop-filter:saturate(120%) blur(6px) }
header::before {
  content:""; position:absolute; inset:-10px 0 -34px; z-index:-1; pointer-events:none;
  background:linear-gradient(180deg,var(--cream) 14%,rgba(250,246,236,.84) 58%,rgba(250,246,236,0));
}
header .bar {
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  max-width:var(--maxw); margin:0 auto; padding:20px clamp(18px,5vw,56px);
}

/* The homepage lockup: mark, Fraunces name, letterspaced line.
   ONE deliberate divergence from index-v2, which uses the full-colour foil mark
   at 44px: that file is mid-tone and measured 357x244, so at this size it
   rendered as a faint blur on cream. This page uses the gold-flattened mark
   instead — it reads, and it is 9 KB against 57 KB.
   `height:auto` is not decoration: an HTML height attribute squashed the 1.46:1
   mark into a square in the first render. */
/* The lockup is a <button> now, so the UA's button skin has to be undone or it
   paints a grey chip round the mark on cream. */
.brand {
  display:flex; align-items:center; gap:12px; text-decoration:none;
  background:none; border:0; padding:0; font:inherit; color:inherit;
  text-align:inherit; cursor:pointer;
}
.foot .brand { cursor:default }
.brand img { width:46px; height:auto }
.foot .brand img { width:40px }
.brand .wm { display:block; direction:ltr; unicode-bidi:isolate; text-align:left }
.brand b {
  font-family:var(--wordmark); font-weight:600; font-size:19px; display:block;
  letter-spacing:-.01em; white-space:nowrap; line-height:1.1;
}
.brand .wm span {
  display:block; font-family:var(--sans); font-size:9.5px; font-weight:600;
  letter-spacing:.22em; color:var(--gold-deep); margin-top:2px;
}

/* who Access says she is. Quiet, factual, and the email is machine text —
   which is what it is. Never styled as a greeting it cannot deliver. */
.who {
  display:flex; align-items:baseline; gap:9px; min-width:0;
  font-size:13px; color:var(--soft);
}
.who b { font-weight:600; flex:0 0 auto }
.who .mono {
  font-size:12px; color:var(--ink); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; max-width:min(42vw,300px);
}
.who:empty, .who[hidden] { display:none }

/* ── the two header controls ──────────────────────────────────────────────
   כל החומרים and יציאה. Both grey, both quiet: gold marks the primary action on
   a surface, and on this page that is צפייה and הורדה. A header control that
   competed with them would be the loudest thing above the fold and the least
   useful.

   The label on the home control names the destination, not the mechanism —
   pressing it also stops the clip and drops the Stream token, which is right for
   "all the materials" and would be a surprise under "back to top". */
.barend { display:flex; align-items:center; gap:clamp(6px,1.6vw,18px); min-width:0 }
.hnav   { display:flex; align-items:center; gap:2px; flex:0 0 auto }

.hlink {
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--sans); font-size:13.5px; font-weight:600; line-height:1;
  color:var(--soft); background:none; border:0; border-radius:999px;
  padding:9px 12px; white-space:nowrap; text-decoration:none; cursor:pointer;
  transition:color .2s, background .2s;
}
.hlink:hover { color:var(--gold-deep); background:rgba(184,137,31,.09) }
.hlink .chev { width:13px; height:13px; flex:0 0 auto }

/* ── sections and bands ───────────────────────────────────────────────── */

main { display:block }
section { padding:clamp(56px,8vh,92px) 0; position:relative }
.alt { background:var(--white) }
.alt::before, .alt::after {
  content:""; position:absolute; inset-inline:0; height:1px; background:var(--line);
}
.alt::before { top:0 } .alt::after { bottom:0 }
.head { max-width:var(--maxw); margin:0 auto }

/* ── the hero ─────────────────────────────────────────────────────────── */

.hero { padding:calc(84px + clamp(30px,6vh,64px)) 0 clamp(46px,7vh,74px); position:relative }

/* index-v2's fine technical grid, so the space reads engineered rather than
   merely empty. Masked to a soft ellipse and set behind everything. It is the
   one piece of texture on the page; there is no imagery, and this is a
   participant's utility page, not a promotional surface. */
.hero::before {
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:linear-gradient(rgba(184,137,31,.13) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(184,137,31,.13) 1px,transparent 1px);
  background-size:46px 46px;
  mask-image:radial-gradient(120% 78% at 30% 34%,#000 26%,transparent 74%);
  -webkit-mask-image:radial-gradient(120% 78% at 30% 34%,#000 26%,transparent 74%);
}
.hero .wrap { position:relative; z-index:1 }

/* The first render put the copy at the reading edge with nothing beside it, and
   two fifths of the fold was dead cream. index-v2 fills that column with its
   console; this page fills it with the spec panel, and the player then takes
   the full width underneath. */
.herogrid {
  display:grid; grid-template-columns:1.1fr .9fr;
  gap:clamp(24px,4vw,56px); align-items:start;
}
.herocopy h1 { max-width:22ch }
.herocopy .lede { max-width:38ch }
@media (max-width:900px) {
  .herogrid { grid-template-columns:1fr; gap:26px }
  /* the panel summarises what follows, so on a phone it reads after the promise */
  .herocopy { order:1 } .specpanel { order:2 }
}

/* ── the console motif: panel + phead ─────────────────────────────────── */

.panel {
  background:rgba(255,253,247,.94); border:1px solid var(--line);
  border-radius:14px; box-shadow:var(--shadow);
}
.specpanel { padding:20px 22px }

.phead {
  display:flex; align-items:center; gap:9px; margin-bottom:12px;
  font-size:12px; color:var(--soft); min-width:0;
}
.phead b { font-size:12.5px; color:var(--ink); font-weight:800 }
.phead .mono {
  margin-inline-start:auto; font-size:10.5px; color:var(--gold-deep);
  letter-spacing:.12em; flex:0 0 auto;
}
.dot { width:7px; height:7px; border-radius:50%; background:var(--gold); flex:0 0 auto }
.dot.live { box-shadow:0 0 0 0 rgba(184,137,31,.5); animation:pulse 2.4s ease-out infinite }
@keyframes pulse {
  70%  { box-shadow:0 0 0 9px rgba(184,137,31,0) }
  100% { box-shadow:0 0 0 0 rgba(184,137,31,0) }
}

/* the "what you get" list, straight off index-v2's why section */
.spec { margin:0; display:flex; flex-direction:column }
/* index-v2 gives dt a fixed 46% basis. In this narrower panel that stranded
   every value in the middle with 130px of dead space beside it, so the row is
   space-between here: label at the reading edge, value at the far edge. */
.spec > div {
  display:flex; gap:16px; align-items:baseline; justify-content:space-between;
  padding:11px 0; border-bottom:1px solid var(--hair);
}
.spec > div:last-child { border-bottom:0 }
.spec dt { font-size:12.5px; letter-spacing:.05em; color:var(--soft); flex:0 1 auto }
.spec dd {
  margin:0; font-size:14.6px; color:var(--ink); font-weight:600;
  flex:0 0 auto; text-align:end;
}
.spec dd.mono { font-size:14.5px }

/* ── the stage ────────────────────────────────────────────────────────────
   The player is this page's spectacle, the way the working agent is the
   homepage's. It gets the panel treatment and a real status bar, because it
   has a real status. */

.stage {
  margin-top:clamp(30px,5vh,48px);
  background:rgba(255,253,247,.94); border:1px solid var(--line);
  border-radius:16px; box-shadow:var(--shadow); overflow:hidden;
}
.stagebar {
  display:flex; align-items:center; gap:10px; min-width:0;
  padding:12px 18px; border-bottom:1px solid var(--line); background:var(--panel);
  font-size:12.5px; color:var(--soft);
}
/* soft on panel is 5.18, so the now-playing title is safe here at 12.5px */
.stagebar b {
  font-size:12.5px; font-weight:800; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
}
.stagebar .mono {
  margin-inline-start:auto; font-size:10.5px; color:var(--gold-deep);
  letter-spacing:.12em; flex:0 0 auto;
}
/* Idle, the player is capped short. A full 16:9 empty box is 665px of nothing
   at desktop width and it was the largest thing on the page — the squint test
   failed on a void. It grows to a real 16:9 the moment something plays. */
.screen { position:relative; height:clamp(220px,30vh,320px); background:var(--panel) }
.stage.live .screen { height:auto; aspect-ratio:16/9 }
.screen-empty {
  position:absolute; inset:0; display:grid; place-content:center; justify-items:center;
  gap:16px; padding:24px; text-align:center;
  color:var(--soft); font-size:clamp(15px,2vw,17.5px);
}
.screen-empty p { margin:0; max-width:32ch }

.play-glyph {
  width:60px; height:60px; border-radius:50%;
  border:2px solid var(--gold); display:grid; place-items:center;
}
.play-glyph::after {
  content:""; border-style:solid;
  border-width:10px 0 10px 16px;            /* points right: video is LTR everywhere */
  border-color:transparent transparent transparent var(--gold);
  margin-inline-start:4px;
}
#player {
  position:absolute; inset:0; width:100%; height:100%;
  border:0; background:#000; display:none;
}
.stage.live #player { display:block }
.stage.live .screen-empty { display:none }
.screen-empty .err { color:var(--brick); font-weight:600 }

/* ── the full recording: index-v2's workshop strip ────────────────────── */

.master-slot:not(:empty) { margin-top:clamp(20px,3vh,30px) }
.strip {
  background:var(--panel); border:1px solid var(--line); border-radius:20px;
  padding:clamp(24px,3.4vw,42px);
  display:grid; grid-template-columns:1fr auto; gap:26px; align-items:center;
}
.strip h2 { font-size:clamp(1.5rem,2.6vw,2.1rem); max-width:30ch }
.strip .chips { margin-top:14px }
.strip .btn { flex:0 0 auto }

/* ── the chapter board ───────────────────────────────────────────────────
   index-v2's jobs board, doing the job it was drawn for: one bordered panel,
   a panel-toned header row, hairline rows, machine text on the right. The
   thirteen clips ARE the chapter navigation, so this is a table of contents
   for one recording, not a list of thirteen videos. */

.board {
  margin-top:36px; border:1px solid var(--line); border-radius:16px; overflow:hidden;
  background:rgba(255,253,247,.94); box-shadow:0 26px 54px -34px rgba(60,45,15,.36);
}
.bhead {
  display:flex; align-items:center; gap:10px;
  padding:13px 18px; border-bottom:1px solid var(--line); background:var(--panel);
  font-size:12.5px; color:var(--soft);
}
.bhead b { font-size:12.5px; font-weight:800; color:var(--ink) }
.bhead .mono {
  margin-inline-start:auto; font-size:10.5px; letter-spacing:.12em; color:var(--soft);
}

.chapters { list-style:none; margin:0; padding:0 }
.ch {
  display:grid; grid-template-columns:auto minmax(0,1fr) auto auto;
  align-items:center; gap:8px 18px;
  padding:13px 18px; border-bottom:1px solid var(--hair);
  transition:background .18s ease;
}
.ch:last-child { border-bottom:0 }
.ch:hover { background:rgba(245,237,217,.55) }
.ch h3 { font-size:15.2px; font-weight:600; line-height:1.4 }

.num {
  width:32px; height:32px; border-radius:50%;
  background:var(--gold); color:var(--ink);
  display:grid; place-items:center;
  font-family:var(--sans); font-weight:800; font-size:14px;
  font-variant-numeric:tabular-nums; flex:0 0 auto;
}

/* the row that is playing, and the master card when it is */
.ch[aria-current="true"], .strip[aria-current="true"] { background:rgba(214,168,94,.16) }
.ch[aria-current="true"] { box-shadow:inset 3px 0 0 0 var(--gold) }
[dir="rtl"] .ch[aria-current="true"] { box-shadow:inset -3px 0 0 0 var(--gold) }
.strip[aria-current="true"] { border-color:var(--gold) }

/* Label and value are separate elements so the gap supplies the space: no
   Hebrew one-letter prefix ever touches a digit run (never "מ-38:45"). */
.chips { display:flex; flex-wrap:wrap; gap:4px 22px; color:var(--soft); font-size:13.5px }
.chips > :empty { display:none }
.chip { display:inline-flex; align-items:baseline; gap:6px; white-space:nowrap }
.chip .mono { font-size:13px; font-weight:600; color:var(--ink) }
/* Thirteen rows each repeating both labels was visual noise in the render, so
   inside the board the label recedes and the number carries the row. */
.ch .chips { justify-content:flex-end; font-size:12px }
.ch .chip .mono { font-size:12.5px }

.badge { display:inline-flex; align-items:center; gap:7px; color:var(--gold-deep); font-weight:600 }
.badge::before {
  content:""; width:8px; height:8px; border-radius:50%;
  background:var(--gold-deep); flex:0 0 auto;
}

/* ── downloads ────────────────────────────────────────────────────────────
   Four cards: two columns sit square, three leave an orphan on row two. */

.grid { display:grid; gap:18px; margin-top:38px; grid-template-columns:repeat(2,minmax(0,1fr)) }
.card {
  background:var(--white); border:1px solid var(--line); border-radius:16px;
  padding:24px; display:flex; flex-direction:column;
  transition:transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s;
}
/* a card must not vanish into the band it sits on */
.alt .card { background:var(--cream) }
.card:hover { transform:translateY(-4px); box-shadow:var(--shadow-card) }
.card .ico { width:32px; height:32px; margin-bottom:14px; color:var(--gold-deep); flex:0 0 auto }
.card .note { color:var(--soft); font-size:14.5px; margin:8px 0 0 }
/* margin-top:auto on the action row, so all four buttons share a baseline even
   when one title wraps to two lines */
.card .act { margin-top:auto; padding-top:18px; align-self:start }

/* ── footer ───────────────────────────────────────────────────────────── */

.foot { background:var(--white); border-top:1px solid var(--line); padding:38px 0 44px }
.foot .row {
  display:flex; justify-content:space-between; gap:26px 40px;
  align-items:flex-start; flex-wrap:wrap;
}
/* `flex:0 1 auto` sized .foot-a to the brand lockup — 235px — and the ask line
   sat on the edge of wrapping while the fine print floated 490px away. */
.foot-a { flex:1 1 300px; min-width:0 }
/* no max-width: 56ch capped this at 372px and it ran to three lines while
   656px of footer sat empty beside it. The wrap already bounds it. */
.foot-b { flex:1 1 340px }
/* index-v2's .proof line: one small gold dot, then a fact */
.foot .ask { display:flex; align-items:baseline; gap:10px; margin:16px 0 0; font-size:16px }
.foot .ask::before {
  content:""; width:6px; height:6px; border-radius:50%; flex:0 0 auto;
  background:var(--gold-bright); transform:translateY(-3px);
}
.foot .fine { color:var(--soft); font-size:13.5px; margin:0; line-height:1.65 }

.noscript {
  background:var(--panel); border:1px solid var(--line); border-radius:12px;
  padding:16px 20px; margin:0 0 24px; font-size:16.5px;
}

/* ── reveal on scroll ─────────────────────────────────────────────────── */

.reveal {
  opacity:0; transform:translateY(18px);
  transition:opacity .8s cubic-bezier(.2,.7,.25,1), transform .8s cubic-bezier(.2,.7,.25,1);
}
.reveal.in { opacity:1; transform:none }
.reveal.d1 { transition-delay:.07s } .reveal.d2 { transition-delay:.14s }
.reveal.d3 { transition-delay:.21s } .reveal.d4 { transition-delay:.28s }
.rv { opacity:0; transform:translateY(14px); animation:rise .9s cubic-bezier(.2,.7,.25,1) forwards }
@keyframes rise { to { opacity:1; transform:none } }
.a1 { animation-delay:.08s } .a2 { animation-delay:.18s }
.a3 { animation-delay:.28s } .a4 { animation-delay:.38s }

/* ── small screens ────────────────────────────────────────────────────── */

@media (max-width:760px) {
  body { font-size:17px }
  /* the 44px touch floor again, this time keyed to width: `hover:none` is not
     emulated by setDeviceMetricsOverride, so the rule above cannot be proved in
     my own harness and this one can */
  .btn { min-height:44px }
  header .bar { padding:14px clamp(18px,5vw,56px) }
  .brand img { width:34px }
  .brand b { font-size:17px }
  /* the email is the first thing to go: she knows who she is, and the lockup
     must not wrap */
  .who b { display:none }
  .who .mono { max-width:38vw }
  .hero { padding-top:calc(70px + 26px) }

  .strip { grid-template-columns:1fr; gap:20px }
  .strip .btn { width:100% }

  /* Disc + title on line one; times and the button share line two, times at the
     reading edge and the button at the far edge. Explicit placement, because
     auto-flow puts the button on a third row of its own. Track 1 is the
     rightmost track in RTL, which is where the disc belongs. */
  .ch { grid-template-columns:auto minmax(0,1fr) auto; padding:14px 16px; gap:11px 14px }
  .ch > :nth-child(1) { grid-area:1/1/2/2 }   /* the number */
  .ch > :nth-child(2) { grid-area:1/2/2/4 }   /* the title, spanning */
  .ch > :nth-child(3) { grid-area:2/2/3/3 }   /* the times */
  .ch > :nth-child(4) { grid-area:2/3/3/4 }   /* צפייה */
  .ch .chips { justify-content:flex-start }

  .grid { grid-template-columns:1fr }
  .card .btn, .card .act .btn { align-self:stretch; width:100% }
  .foot .row { flex-direction:column }
}
@media (max-width:420px) {
  .who { display:none }
}

@media (prefers-reduced-motion:reduce) {
  html { scroll-behavior:auto }
  *, *::before, *::after { transition:none !important; animation:none !important }
  .reveal { opacity:1; transform:none } .rv { opacity:1; transform:none }
}

/* ── QA only ──────────────────────────────────────────────────────────────
   index-v2's own switch, carried over. A screenshot under virtual time never
   fires IntersectionObserver, so a capture would show half-faded elements and
   send me hunting a contrast bug that is not there. ?qa forces the finished
   state. Never used in production. */
body.qa .reveal { opacity:1 !important; transform:none !important; transition:none !important }
body.qa .rv { animation:none !important; opacity:1 !important; transform:none !important }

/* ── print ────────────────────────────────────────────────────────────────
   She may want the chapter list and the file names on paper. The player is
   meaningless there, so it goes. */
@media print {
  header, .stage, .btn, .bh { display:none !important }
  body { background:#fff; font-size:11pt }
  section { padding:14pt 0 }
  .hero { padding-top:0 }
  .alt::before, .alt::after { display:none }
  .board, .strip, .card, .panel { box-shadow:none }
  .hero::before { display:none }

  /* Measured on the printed PDF, not assumed: `break-inside:avoid` on .board
     cannot be honoured — thirteen rows do not fit on one A4 — so the browser
     broke inside it anyway and split row 11's title from its own times onto the
     next page. The row is the unit that must stay whole; the board is not. */
  .board { break-inside:auto }
  .ch, .card, .strip, .specpanel, .head { break-inside:avoid }
  .foot, .foot .row { break-inside:avoid }

  /* on paper the buttons are gone, so the download links need their real URLs */
  .card .act::after { content:attr(data-href); font-size:9pt; color:#555; direction:ltr;
    unicode-bidi:isolate; display:block }
}
