/* Double Skunk learn pages (/learn/*). Tokens and page chrome come from
   base.css, which is linked first. No Tailwind, no dark: variants;
   these pages are dark by construction. */

/* ---- page ---- */
.learn-head { padding: 56px 0 8px; }
.learn-head .kicker, .kicker { font-family: var(--font-sign); font-weight: 800; font-size: 12px;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--pop-ruby); }
.learn-head h1 { font-family: var(--font-display); font-weight: 400;
  font-size: clamp(34px, 5vw, 52px); line-height: 1.02; color: var(--chalk); margin: 10px 0 0; }
.learn-head .lede, .lede { font-family: var(--font-body); font-size: 18px; line-height: 1.55;
  color: var(--fg-2); max-width: 680px; margin: 16px 0 0; }
.lesson { padding: 40px 0 8px; max-width: 760px; scroll-margin-top: 76px; }
.lesson h2 { font-family: var(--font-display); font-weight: 400; font-size: 30px; color: var(--chalk); margin: 0 0 14px; }
.lesson h3 { font-family: var(--font-body); font-weight: 700; font-size: 20px; color: var(--chalk); margin: 24px 0 8px; }
.lesson p { font-size: 17px; line-height: 1.6; color: var(--fg-2); margin: 0 0 14px; }
.lesson ul { margin: 0 0 14px; padding-left: 22px; color: var(--fg-2); line-height: 1.6; }
.lesson b, .lesson strong { color: var(--chalk); font-weight: 600; }
.next-stop { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; align-items: center;
  margin: 40px 0 64px; padding: 20px 24px; border-radius: 14px; background: var(--surface-base); border: 1px solid var(--border-hair); }
.next-stop .kicker { color: var(--fg-4); }
.next-stop a.cta { margin-left: auto; }

/* ---- callouts and terms ---- */
.callout.in-ds { margin: 22px 0; padding: 16px 20px; border-radius: 12px; max-width: 760px;
  background: color-mix(in srgb, var(--brass) 8%, var(--surface-base)); border-left: 3px solid var(--brass); }
.callout-kicker { display: block; font-family: var(--font-sign); font-weight: 800; font-size: 11px;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--brass-glow); margin-bottom: 6px; }
.callout.in-ds p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--fg-2); }
.term { color: var(--chalk); border-bottom: 1px dotted var(--brass); text-decoration: none; position: relative; }
.term:hover, .term:focus-visible { color: var(--brass-glow); }
/* The popover is absolutely positioned inside a short inline <a>, so
   shrink-to-fit sizes it to the anchor (about 77px) and the max-width
   clamp never gets a say. max-content lets the clamp do its job. */
.term-pop { position: absolute; z-index: 40; width: max-content; max-width: min(300px, calc(100vw - 16px)); padding: 10px 12px; border-radius: 10px;
  background: var(--skunk-ink-4); color: var(--chalk); border: 1px solid var(--border-hair); box-shadow: var(--shadow-card);
  font-size: 14px; line-height: 1.45; font-family: var(--font-body); }
.term-pop b { display: block; font-family: var(--font-sign); letter-spacing: 0.12em; text-transform: uppercase; font-size: 11px; color: var(--brass-glow); margin-bottom: 4px; }

/* ---- cards ---- */
.card-wrap { display: inline-block; width: 74px; line-height: 0; vertical-align: middle;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,0.45)); transition: transform 180ms cubic-bezier(0.34, 1.56, 0.64, 1), filter 180ms; }
.card-wrap.lg { width: 106px; }
.card-wrap.sm { width: 52px; }
.card-wrap .pc { width: 100%; height: auto; display: block; }
/* The cut card wears the game's ember frame so it reads apart from the hand. */
.card-wrap.cut .pc > rect:first-of-type { stroke: var(--card-cut-frame); stroke-width: 1.5; }
.card-wrap[data-selected="true"] { transform: translateY(-10px); filter: drop-shadow(0 0 3px var(--card-select)) drop-shadow(0 8px 14px rgba(0,0,0,0.5)); }
.card-wrap[data-lit="true"] { transform: translateY(-8px) scale(1.04); filter: drop-shadow(0 0 12px var(--brass-glow)); }
.card-wrap[data-dim="true"] { opacity: 0.45; }
button.card-btn { background: none; border: 0; padding: 0; cursor: pointer; border-radius: 8px; }
button.card-btn:focus-visible { outline: 3px solid var(--brass); outline-offset: 3px; }
.hand { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.hand .cut { margin-left: 18px; position: relative; }
.hand .cut::before { content: var(--cut-label, "cut"); position: absolute; top: -18px; left: 0; font-family: var(--font-sign); font-size: 11px;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg-4); }

/* ---- widgets ---- */
.widget { margin: 26px 0; padding: 22px 24px; border-radius: 16px; background: var(--surface-base);
  border: 1px solid var(--border-hair); box-shadow: var(--shadow-card); max-width: 760px; }
.widget-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.widget-head .kicker { color: var(--fg-accent); }
.widget-panel { margin-top: 16px; padding: 14px 16px; border-radius: 12px; background: var(--surface-raised); }
.widget-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 14px; }
.btn { display: inline-flex; align-items: center; gap: 8px; padding: 10px 16px; border-radius: 10px; cursor: pointer;
  font-family: var(--font-sign); font-weight: 800; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--chalk); border: 0; background: linear-gradient(180deg, var(--brass-bright), var(--brass) 65%, var(--brass-deep));
  box-shadow: var(--shadow-button); transition: transform 80ms, box-shadow 160ms; }
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.4; cursor: default; transform: none; }
.btn.ghost { background: transparent; box-shadow: inset 0 0 0 1px var(--border-hair); color: var(--fg-2); }
.btn:focus-visible { outline: 3px solid var(--brass-glow); outline-offset: 2px; }
.toggle { display: inline-flex; border-radius: 999px; background: var(--surface-raised); padding: 3px; }
.toggle button { border: 0; background: transparent; color: var(--fg-3); padding: 6px 14px; border-radius: 999px; cursor: pointer;
  font-family: var(--font-sign); font-weight: 800; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; }
.toggle button[aria-pressed="true"] { background: var(--brass); color: var(--chalk); }
.stat { display: inline-flex; flex-direction: column; gap: 2px; min-width: 96px; }
.stat .lbl { font-family: var(--font-sign); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg-4); }
.stat-num { font-family: var(--font-mono); font-size: 26px; font-weight: 700; color: var(--fg-accent); font-variant-numeric: tabular-nums; }
.stat-num.pop { animation: pop 320ms cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes pop { 0% { transform: scale(1); } 50% { transform: scale(1.35); color: var(--chalk); } 100% { transform: scale(1); } }
.hint { font-family: var(--font-body); font-size: 14px; color: var(--fg-3); margin-top: 10px; min-height: 1.4em; }
.srs { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---- worked discards (deal-and-crib) ---- */
.trainer-list { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 16px; }
.trainer-row { padding: 18px 20px; border-radius: 14px; background: var(--surface-base); border: 1px solid var(--border-hair); scroll-margin-top: 90px; }
.trainer-row .kicker { display: block; margin-bottom: 10px; }
.trainer-row .hand { margin: 0 0 10px; }
.trainer-row p { margin: 0 0 6px; font-size: 15px; }
.trainer-row:target { border-color: var(--brass); }

/* ---- count meter ---- */
.meter { display: grid; grid-template-columns: repeat(31, 1fr); gap: 3px; margin: 12px 0 6px; }
.meter-hole { aspect-ratio: 1; border-radius: 50%; background: var(--skunk-ink-5); box-shadow: var(--shadow-engrave); transition: background 160ms; }
.meter-hole.filled { background: var(--brass); }
.meter-hole.mark { box-shadow: inset 0 0 0 2px var(--gold); }
/* Same 31-column grid as the holes, so each label sits centred under its
   own hole (the 15 under the marked fifteenth, not in the middle of the row). */
.meter-labels { display: grid; grid-template-columns: repeat(31, 1fr); gap: 3px; font-family: var(--font-mono); font-size: 11px; color: var(--fg-4); }
.meter-labels span { grid-row: 1; display: flex; justify-content: center; white-space: nowrap; overflow: visible; }
.meter-labels span[data-n="1"] { grid-column: 1; }
.meter-labels span[data-n="15"] { grid-column: 15; }
.meter-labels span[data-n="31"] { grid-column: 31; }
.badge-score { display: inline-block; padding: 3px 10px; border-radius: 999px; font-family: var(--font-mono); font-size: 12px;
  color: var(--chalk); background: var(--brass-deep); box-shadow: inset 0 0 0 1px var(--brass); margin-left: 8px; }
.play-steps { list-style: none; margin: 12px 0 0; padding: 0; display: flex; gap: 8px; flex-wrap: wrap; }
.play-steps li { display: flex; flex-direction: column; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 12px; color: var(--fg-3); }
.play-steps li.future { opacity: 0.25; }
.play-steps li .by { font-family: var(--font-sign); letter-spacing: 0.14em; text-transform: uppercase; font-size: 10px; color: var(--fg-4); }
.play-steps li.go .card-wrap { visibility: hidden; }

/* ---- breakdown (count it) ---- */
.breakdown { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.breakdown li { display: flex; justify-content: space-between; gap: 12px; padding: 8px 12px; border-radius: 8px;
  font-family: var(--font-body); font-size: 15px; color: var(--fg-3); background: var(--surface-raised); transition: background 160ms, color 160ms; }
.breakdown li.lit { background: color-mix(in srgb, var(--brass) 22%, var(--surface-raised)); color: var(--chalk); }
.breakdown li .pts { font-family: var(--font-mono); color: var(--brass-glow); }
.breakdown li.total { font-weight: 700; color: var(--chalk); background: transparent; border-top: 1px solid var(--border-hair); border-radius: 0; }
/* Quiz mode. Blurring the rows is not enough on its own: the total sits
   right above the guess box, so its value is taken out of the flow too. */
.breakdown.hidden li { filter: blur(6px); pointer-events: none; }
.breakdown.hidden li.total .pts { visibility: hidden; }
/* The worked-example paragraph under each widget states the answer in
   prose, so quiz mode has to cover it too. */
body[data-quiz="on"] .score-line { filter: blur(6px); user-select: none; }
.quiz input { width: 80px; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border-hair); background: var(--skunk-ink); color: var(--chalk);
  font-family: var(--font-mono); font-size: 18px; }

/* ---- board ---- */
.board-svg { width: 100%; height: auto; display: block; }
.board-svg .hole { fill: var(--skunk-ink-5); }
.board-svg .street { fill: var(--surface-board); stroke: var(--border-hair); }
.board-svg .mark { stroke: var(--brass); stroke-width: 2; }
.board-svg .mark-label { font-family: var(--font-sign); font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; fill: var(--brass-glow); }
.board-svg .peg-you { fill: var(--brass-bright); stroke: var(--chalk); stroke-width: 1.5; transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1); }
.board-svg .peg-rival { fill: var(--seal-blue); stroke: var(--chalk); stroke-width: 1.5; transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1); }
.sliders { display: grid; gap: 10px; margin-top: 14px; }
.sliders label { display: grid; grid-template-columns: 70px 1fr 40px; align-items: center; gap: 12px; font-family: var(--font-sign);
  font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3); }
.sliders input[type="range"] { accent-color: var(--brass); width: 100%; }
.verdict { margin-top: 12px; font-family: var(--font-display); font-size: 22px; color: var(--chalk); }

/* ---- picker (calculator) ---- */
.picker { display: grid; grid-template-columns: repeat(13, 1fr); gap: 4px; margin-top: 12px; }
.picker button { padding: 6px 0; border-radius: 6px; border: 1px solid var(--border-hair); background: var(--surface-raised); cursor: pointer;
  font-family: var(--font-mono); font-size: 13px; color: var(--fg-2); }
.picker button.red { color: var(--card-red); }
.picker button[aria-pressed="true"] { background: var(--brass); color: var(--chalk); border-color: var(--brass); }
.picker button:disabled { opacity: 0.3; cursor: default; }
.best-cuts { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.best-cuts .card-wrap { width: 44px; }
.best-cuts .n { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); text-align: center; display: block; }
.share { font-family: var(--font-mono); font-size: 12px; color: var(--fg-4); margin-top: 12px; word-break: break-all; }

/* ---- hub ---- */
/* Deck on the left, the dealt hand beside it; on a phone the hand wraps
   under the deck. Cards enter from the deck with a staggered slide. */
.hero-deal { display: flex; gap: 28px; align-items: flex-start; margin: 30px 0 8px; }
.hero-deal button.deck { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 10px;
  background: none; border: 0; padding: 6px 4px 0; cursor: pointer; border-radius: 12px; }
.hero-deal button.deck:focus-visible { outline: 3px solid var(--brass); outline-offset: 4px; }
.deck-stack { position: relative; display: block; width: 88px; height: 132px; }
.deck-stack .card-wrap { position: absolute; left: 0; top: 0; width: 88px; }
.deck-stack .card-wrap:nth-child(1) { transform: translate(4px, 6px) rotate(3deg); }
.deck-stack .card-wrap:nth-child(2) { transform: translate(2px, 3px) rotate(-2deg); }
.deck-stack .card-wrap:nth-child(3) { animation: deck-nudge 3600ms ease-in-out infinite; }
.hero-deal.dealt .deck-stack .card-wrap:nth-child(3) { animation: none; }
button.deck:hover .deck-stack .card-wrap:nth-child(3), button.deck:focus-visible .deck-stack .card-wrap:nth-child(3) {
  animation: none; transform: translate(-6px, -10px) rotate(-4deg); }
@keyframes deck-nudge {
  0%, 62%, 100% { transform: translate(0, 0) rotate(0deg); }
  70% { transform: translate(-5px, -9px) rotate(-3deg); }
  80% { transform: translate(-3px, -6px) rotate(-2deg); }
}
.deck-label { font-family: var(--font-sign); font-weight: 800; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--brass-glow); }
.hero-table { flex: 1 1 auto; min-width: 0; }
.hero-hand { gap: 8px; min-height: 108px; }
.hero-hand .card-wrap { width: 72px; transition: transform 420ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 260ms, filter 180ms; }
.hero-hand .card-wrap.dealing { opacity: 0; transform: translate(-48px, 12px) rotate(-8deg) scale(0.92); }
.hero-panel { display: flex; gap: 18px 28px; flex-wrap: wrap; align-items: flex-end; margin-top: 12px; padding: 14px 16px;
  border-radius: 12px; background: var(--surface-base); border: 1px solid var(--border-hair); }
.hero-panel .stat { min-width: 0; }
.hero-panel .hint { flex-basis: 100%; margin-top: 0; }

/* ---- the five beats strip ---- */
.flow { list-style: none; margin: 22px 0 26px; padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; max-width: 760px; }
.flow li { position: relative; padding: 12px 14px; border-radius: 10px; background: var(--surface-base); border: 1px solid var(--border-hair); opacity: 0.55; }
.flow li[aria-current="step"] { opacity: 1; border-color: var(--brass); background: color-mix(in srgb, var(--brass) 10%, var(--surface-base)); }
.flow-name { display: block; font-family: var(--font-display); font-size: 15px; color: var(--chalk); line-height: 1.1; }
.flow-sub { display: block; font-family: var(--font-body); font-size: 12px; color: var(--fg-3); margin-top: 3px; }

/* ---- recap + stop nav ---- */
.recap { margin: 36px 0 8px; padding: 18px 22px; border-radius: 14px; max-width: 760px;
  background: var(--surface-base); border: 1px solid var(--border-hair); border-top: 3px solid var(--brass); }
.recap .kicker { display: block; margin-bottom: 8px; }
.recap ul { margin: 0; padding-left: 20px; color: var(--fg-2); line-height: 1.6; font-size: 16px; }
.recap li { margin: 4px 0; }
.recap b { color: var(--chalk); font-weight: 600; }
.stop-nav { display: grid; grid-template-columns: 1fr 1.4fr; gap: 14px; margin: 28px 0 56px; max-width: 760px; }
.stop-link { display: flex; flex-direction: column; gap: 4px; padding: 18px 20px; border-radius: 14px; text-decoration: none;
  background: var(--surface-base); border: 1px solid var(--border-hair); transition: border-color 180ms, translate 120ms; }
.stop-link:hover { border-color: var(--brass); translate: 0 -2px; }
.stop-link .kicker { color: var(--fg-4); }
.stop-link.next { border-color: color-mix(in srgb, var(--brass) 45%, var(--border-hair)); }
.stop-link.next .kicker { color: var(--fg-accent); }
.stop-link-title { font-family: var(--font-display); font-size: 19px; color: var(--chalk); line-height: 1.15; }
.stop-link .hint { margin-top: 2px; min-height: 0; }
.stop-link.prev { text-align: left; }
.stop-nav .stop-link:only-child { grid-column: 1 / -1; }

/* ---- language switcher ---- */
.lang-switch { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 8px 0 40px; max-width: 760px; }
.lang-switch a { font-family: var(--font-mono); font-size: 12.5px; letter-spacing: 0.02em; color: var(--fg-3); text-decoration: none;
  border-bottom: 1px dotted var(--fg-4); transition: color 160ms, border-color 160ms; }
.lang-switch a:hover { color: var(--chalk); border-bottom-color: var(--chalk-4); }
.lang-switch a[aria-current="page"] { color: var(--brass-glow); font-weight: 600; border-bottom-color: var(--brass-glow); }

.stops { list-style: none; margin: 28px 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; counter-reset: stop; }
.stop { counter-increment: stop; position: relative; padding: 20px 22px 20px 62px; border-radius: 16px; background: var(--surface-base);
  border: 1px solid var(--border-hair); box-shadow: var(--shadow-card); transition: border-color 180ms, translate 120ms; }
.stop::before { content: counter(stop); position: absolute; left: 18px; top: 18px; width: 30px; height: 30px; border-radius: 50%;
  box-sizing: border-box; display: grid; place-items: center; padding-top: 2px; font-family: var(--font-display); font-size: 15px; line-height: 1; color: var(--chalk);
  background: var(--brass-deep); box-shadow: inset 0 0 0 1px var(--brass); }
.stop:hover { border-color: var(--brass); translate: 0 -2px; }
.stop a { color: var(--chalk); text-decoration: none; border: 0; font-family: var(--font-display); font-size: 19px; }
.stop a::after { content: ""; position: absolute; inset: 0; }
.stop p { margin: 6px 0 0; font-size: 14px; color: var(--fg-3); }
.stop.done::before { content: "✓"; background: var(--ok); box-shadow: none; }
.stop.soon { opacity: 0.55; }
.stop.soon .soon-tag { font-family: var(--font-sign); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold); margin-left: 8px; }
.quick-links { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 28px; }

/* ---- glossary ---- */
.glossary dt { font-family: var(--font-display); font-size: 20px; color: var(--chalk); margin-top: 26px; scroll-margin-top: 90px; }
.glossary dt:target { color: var(--brass-glow); }
.glossary dd { margin: 6px 0 0; color: var(--fg-2); line-height: 1.6; max-width: 720px; }
.glossary dd b { color: var(--chalk); font-weight: 600; }

/* ---- pinned stage (scrolly.js) ----
   A stage sticks under the site nav while short beats scroll beneath it;
   whichever beat sits on the reading line drives the stage. Every rule here
   is the resting state: without JS every beat is at full contrast and the
   stage shows pegs at 0, an empty meter, unlit cards. scrolly.js writes the
   camera transform, beat opacity and drift inline, so no class transition
   runs on the beats. */
.scrolly { position: relative; margin: 26px 0 0; }
.scrolly-stage { position: sticky; top: calc(var(--nav-h, 58px) + 6px); z-index: 5; padding: 6px 0 12px;
  /* Opaque, so beats passing behind the stage disappear cleanly under it. */
  background: var(--skunk-ink); box-shadow: 0 14px 18px -12px rgba(0, 0, 0, 0.7); }
.scrolly-frame { position: relative; overflow: hidden; border-radius: 16px; background: var(--surface-base);
  border: 1px solid var(--border-hair); box-shadow: var(--shadow-card); }
/* The board's own viewBox ratio, so the resting camera shows the whole board.
   The cap is on the width, so the frame keeps its ratio when a landscape
   phone needs a beat's worth of screen under it, and the cover-fit camera
   never crops a street off the whole-board beats. */
.scrolly-frame.board-frame { aspect-ratio: 1000 / 280; width: min(100%, calc(42svh * 1000 / 280)); margin-inline: auto; }
.scrolly-plane { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform-origin: 0 0; will-change: transform;
  transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1); }
.scrolly-plane .board-svg { width: 100%; height: 100%; }
.board-svg .peg-you.back { fill: var(--brass-deep); }
.board-svg .peg-rival.back { fill: color-mix(in srgb, var(--seal-blue) 60%, var(--skunk-ink)); }
.stage-panel { padding: 16px 22px; border-radius: 16px; background: var(--surface-base); border: 1px solid var(--border-hair); box-shadow: var(--shadow-card); }
.stage-panel .meter { margin-top: 4px; }
.stage-panel .widget-row { margin-top: 10px; }
.stage-panel .badge-score { margin-left: 0; }
/* The stage's badge row names the score, so its card line is rendered
   without per-step badges (play_steps badges={false}) and stays one row. */
.stage-panel .play-steps { flex-wrap: nowrap; }
.scrolly-beats { max-width: 560px; padding: 6svh 0 22svh; }
.beat { min-height: 52svh; display: grid; align-content: center; padding: 8px 0; opacity: 1; border-radius: 8px; }
.beat h2 { font-family: var(--font-display); font-weight: 400; font-size: 28px; color: var(--chalk); margin: 0 0 12px; }
.beat h3 { font-family: var(--font-body); font-weight: 700; font-size: 20px; color: var(--chalk); margin: 0 0 8px; }
.beat p { font-size: 17px; line-height: 1.6; color: var(--fg-2); margin: 0 0 12px; }
.beat .beat-line { display: flex; align-items: center; gap: 14px; font-size: 21px; line-height: 1.4; color: var(--chalk); }
.beat .beat-count { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.beat .beat-count .lbl { font-family: var(--font-sign); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg-4); }
.beat .beat-count .stat-num { font-size: 22px; }
.beat .widget { margin: 8px 0 0; }
.beat:focus-visible { outline: 2px solid var(--brass); outline-offset: 8px; }
/* One tick per beat, sticky at the foot of the tour. A scene's first tick
   stands off from the last so the rail reads as chapters, not one long row. */
.scrolly-rail { position: sticky; bottom: 0; z-index: 6; display: flex; justify-content: center; padding: 4px 12px;
  border-top: 1px solid var(--border-hair); background: color-mix(in srgb, var(--skunk-ink) 94%, transparent); }
.scrolly-rail:empty { display: none; }
.rail-tick { position: relative; width: 24px; height: 24px; border: 0; padding: 0; background: transparent; cursor: pointer; }
.rail-tick::before { content: ""; position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%;
  background: var(--skunk-ink-5); box-shadow: var(--shadow-engrave); transition: transform 200ms ease, background 200ms ease; }
.rail-tick.scene-start { margin-left: 10px; }
.rail-tick:hover::before { background: var(--fg-4); }
.rail-tick.is-active::before { background: var(--brass); transform: scale(1.5); }
.rail-tick:focus-visible { outline: 2px solid var(--brass-glow); outline-offset: -2px; }

/* ---- rewards ----
   learn.js adds these when a reader gets something right (or, for .shake,
   wrong). All paint: the hint text and the live region already say which.
   --ease-pop and the stamp keyframes are base.css's, above its chrome line. */
.stat { position: relative; }
.hint.good { color: var(--ok); }
.stat-num[data-tone="good"] { color: var(--ok); }
.stat-num.pop-good { animation: pop-good 460ms var(--ease-pop); }
@keyframes pop-good {
  0% { transform: scale(1); }
  45% { transform: scale(1.4); color: var(--ok); text-shadow: 0 0 16px color-mix(in srgb, var(--ok) 65%, transparent); }
  100% { transform: scale(1); }
}
/* Beside the number rather than above it: above is the hand, and the chip
   would rise into the cards. learn.js sets `left` to just past the digits. */
.float-up { position: absolute; left: 100%; bottom: 2px; z-index: 2; pointer-events: none; white-space: nowrap;
  font-family: var(--font-mono); font-weight: 700; font-size: 19px; color: var(--ok);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.6); animation: float-up 1000ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards; }
@keyframes float-up {
  0% { opacity: 0; transform: translateY(8px) scale(0.7); }
  22% { opacity: 1; transform: translateY(0) scale(1.15); }
  100% { opacity: 0; transform: translateY(-30px) scale(1); }
}
.quiz.shake { animation: shake 380ms cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes shake {
  10%, 90% { translate: -1px 0; }
  20%, 80% { translate: 3px 0; }
  30%, 50%, 70% { translate: -6px 0; }
  40%, 60% { translate: 6px 0; }
}
/* The reader's own throw, when it is the best of the fifteen. */
.breakdown li.best { animation: gold-flash 1100ms ease-out; }
@keyframes gold-flash {
  0% { background: color-mix(in srgb, var(--gold) 45%, var(--surface-raised));
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--gold) 70%, transparent); }
  35% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--gold) 25%, transparent); }
  100% { box-shadow: 0 0 0 12px transparent; }
}
/* A chapter finished since the last hub visit stamps its tick in, once,
   when it scrolls into view, and the card rings green as it lands. */
.stop.done.stamp::before { animation: stamp 620ms var(--ease-pop) 150ms both; }
.stop.done.stamp { animation: stop-ring 1100ms var(--ease-out) 300ms both; }
@keyframes stop-ring {
  0% { box-shadow: var(--shadow-card), 0 0 0 0 color-mix(in srgb, var(--ok) 55%, transparent); border-color: var(--ok); }
  100% { box-shadow: var(--shadow-card), 0 0 0 14px transparent; }
}

/* ---- motion + responsive ---- */
@media (prefers-reduced-motion: reduce) {
  .card-wrap, .board-svg .peg-you, .board-svg .peg-rival, .hero-deal .card-wrap, .stat-num.pop { transition: none; animation: none; }
  /* The camera and the pegs still land, without the glide. scrolly.js clears
     every parallax layer's inline transform under the same query. */
  .scrolly-plane, .rail-tick::before { transition: none; }
  /* Out-specifies the :nth-child(3) nudge rule, which would otherwise win. */
  .deck-stack .card-wrap:nth-child(3) { animation: none; }
}
@media (max-width: 720px) {
  .stops { grid-template-columns: 1fr; }
  /* Twenty ticks do not fit a phone, and the pinned stage already shares
     the screen with the beats. The scroll is the navigation here. */
  .scrolly-rail { display: none; }
  .scrolly-beats { padding-bottom: 14svh; }
  .beat { min-height: 44svh; }
  .beat .beat-line { font-size: 18px; }
  .stage-panel { padding: 12px 14px; }
  /* Seven cards across a 326px panel: 7 x (38 + 6) fits, 52 does not. */
  .stage-panel .play-steps { gap: 6px; }
  .stage-panel .play-steps .card-wrap.sm { width: 38px; }
  .stage-panel .play-steps li { font-size: 11px; }
  /* Four cards, the cut and its gap across the same panel, on one row. */
  .stage-panel .show-hand .hand { gap: 8px; flex-wrap: nowrap; }
  .stage-panel .show-hand .card-wrap { width: 52px; }
  .stage-panel .show-hand .hand .cut { margin-left: 10px; }
  .scrolly-frame.board-frame { width: min(100%, calc(34svh * 1000 / 280)); }
  .hero-deal { flex-direction: column; gap: 18px; }
  .hero-deal button.deck { flex-direction: row; gap: 16px; padding: 0; }
  .deck-stack { width: 64px; height: 96px; }
  .deck-stack .card-wrap { width: 64px; }
  /* Six across on one row: the button is the flex item, so it takes the
     share, and the card fills it (a percentage on the card alone would
     resolve against the shrink-wrapped button and collapse). */
  .hero-hand button.card-btn { flex: 0 0 calc((100% - 40px) / 6); max-width: 72px; }
  .hero-hand .card-wrap { width: 100%; }
  .flow { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px; }
  .flow li { padding: 10px 8px; }
  .flow-name { font-size: 13px; }
  .flow-sub { display: none; }
  .stop-nav { grid-template-columns: 1fr; }
  .card-wrap { width: 58px; }
  .card-wrap.lg { width: 84px; }
  .meter { gap: 2px; }
  .meter-labels { gap: 2px; font-size: 10px; }
  .picker { grid-template-columns: repeat(7, 1fr); }
}

/* ---- practice table ---- */
.practice .stepper { list-style: none; margin: 0; padding: 0; display: flex; gap: 8px; }
.practice .stepper li { position: relative; width: 12px; height: 12px; border-radius: 50%; background: var(--skunk-ink-5); box-shadow: var(--shadow-engrave); }
.practice .stepper li.current { background: var(--brass); }
.practice .stepper li.done { background: var(--ok); }
.table { display: grid; gap: 14px; padding: 16px; border-radius: 14px; background: var(--surface-table); border: 1px solid var(--border-hair); }
.table-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; min-height: 60px; }
/* Row gap leaves the cut card's label room on the wrap at narrow widths. */
.table-row.middle { justify-content: space-between; gap: 24px 10px; }
/* The middle row carries the crib, up to five played cards, the cut, and the
   count. At the page's max width that only fits with tighter cards. */
.table .hand { gap: 6px; }
.table .card-wrap.sm { width: 44px; }
.table-row .hand:empty { min-width: 74px; min-height: 40px; border: 1px dashed var(--border-hair); border-radius: 8px; }
.caption { margin-top: 16px; min-height: 4.5em; font-family: var(--font-body); font-size: 18px; line-height: 1.5; color: var(--chalk); }
.caption .cursor { display: inline-block; width: 0.5em; border-bottom: 2px solid var(--brass); margin-left: 2px; animation: blink 900ms steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* The hub's one-page rules walkthrough. */
.go-deeper { margin-top: 0.4rem; }
.go-deeper a { font-weight: 600; }

.score-chart table { width: 100%; border-collapse: collapse; margin-top: 0.75rem; }
.score-chart th, .score-chart td {
  text-align: left;
  padding: 0.45rem 0.6rem;
  border-bottom: 1px solid var(--border-hair);
}
.score-chart th:last-child, .score-chart td:last-child {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Each hub question reads as its own block, not one run of h3s and paragraphs. */
.faq-entry { margin: 0 0 22px; scroll-margin-top: 76px; }
.faq-entry h3 { margin-top: 0; }
.faq-entry:last-child { margin-bottom: 0; }
