/* =====================================================================
   shell.css — the device, chrome (topbar/HUD, chip, act bar, sound), scene
   engine, overlays (grain, vignette, flash, fx, toast, sheet) and every shared
   primitive (type, words, k, aside, controls, lockup, round card, flap, score).
   CORE-OWNED. Scene-specific rules live in css/scenes/<module>.css.
   Only transform / opacity / clip-path animate. Grades are static img filters.
   ===================================================================== */

/* ---------- desktop stage + device ---------- */
.stage {
  position: fixed; inset: 0; display: none;
  background:
    radial-gradient(55% 45% at 18% 12%, rgba(210, 104, 74, 0.16), transparent 60%),
    radial-gradient(45% 55% at 86% 92%, rgba(201, 164, 92, 0.12), transparent 60%),
    linear-gradient(165deg, #070b13, #0b1220 55%, #0d1526);
}
.stage-names { position: absolute; left: 48px; bottom: 44px; margin: 0; font-family: var(--display); font-weight: 300; font-size: 44px; color: var(--cream); letter-spacing: -0.01em; }
.stage-names span { color: var(--clay); font-style: italic; font-variation-settings: var(--wonk); }
.stage-hint { position: absolute; right: 48px; bottom: 52px; margin: 0; font: var(--caps); letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--cream-30); }

/* overflow: clip (not hidden) so programmatic scrollIntoView can never shift the frame */
.device { position: fixed; inset: 0; height: 100dvh; background: var(--night); overflow: clip; color: var(--cream); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; margin: 0; }

@media (min-width: 760px) {
  .stage { display: block; }
  /* centred with margin:auto, not a translate: js/desktop-qr.js owns the frame's transform (it tilts toward the pointer) */
  .device {
    inset: 0; margin: auto;
    width: 400px; height: min(860px, calc(100vh - 64px)); border-radius: 50px;
    box-shadow: 0 0 0 11px #07090e, 0 0 0 13px #262c38; /* the bezel; the drop shadow is .stage-shadow so it can shift against the tilt */
  }
  .stage-shadow {
    position: absolute; inset: 0; margin: auto; width: 426px; height: calc(min(860px, 100vh - 64px) + 26px); border-radius: 63px;
    box-shadow: 0 50px 100px rgba(0, 0, 0, 0.7), 0 0 140px rgba(210, 104, 74, 0.1); pointer-events: none; will-change: transform;
  }
  .device::before { content: ""; position: absolute; top: 12px; left: 50%; transform: translateX(-50%); width: 112px; height: 30px; border-radius: 20px; background: #07090e; z-index: 40; }
  :root { --safe-top: 44px; --safe-bottom: 20px; }
}

/* ---------- overlays: grain, vignette, flash, fx canvas ---------- */
.grain-wrap { position: absolute; inset: 0; z-index: 30; overflow: clip; pointer-events: none; }
.grain {
  pointer-events: none; position: absolute; inset: -10%; z-index: 30; opacity: 0.16; mix-blend-mode: screen; transform: translateZ(0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.18 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 0.6s steps(1) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0) translateZ(0); } 17% { transform: translate(-3%, 2%) translateZ(0); } 34% { transform: translate(2%, -4%) translateZ(0); }
  51% { transform: translate(-4%, -1%) translateZ(0); } 68% { transform: translate(3%, 3%) translateZ(0); } 85% { transform: translate(1%, -2%) translateZ(0); } 100% { transform: translate(0, 0) translateZ(0); }
}
.program .grain { mix-blend-mode: multiply; opacity: 0.38; }
.vignette { pointer-events: none; position: absolute; inset: 0; z-index: 29; background: radial-gradient(120% 95% at 50% 45%, transparent 50%, rgba(5, 8, 15, 0.6)); opacity: 0; transition: opacity 1s ease; }
.device.dark .vignette { opacity: 1; }
.program .vignette { opacity: 1; background: radial-gradient(120% 95% at 50% 45%, transparent 55%, rgba(120, 90, 50, 0.08)); }
#flash { position: absolute; inset: 0; z-index: 31; background: var(--cream); opacity: 0; pointer-events: none; }
#fx { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 28; pointer-events: none; }
.shade { position: absolute; inset: 0; z-index: 20; background: #05080f; opacity: 0; pointer-events: none; }

/* ---------- top bar: segments + slate (round / story) ---------- */
.topbar {
  position: absolute; left: 0; right: 0; top: 0; z-index: 25; pointer-events: none;
  padding: calc(var(--safe-top) + 12px) 78px 0 var(--pad);
  display: flex; flex-direction: column; gap: 10px;
  transition: opacity 0.5s ease;
}
.topbar.hidden { opacity: 0; }
.segments { display: flex; gap: 4px; height: 2px; }
.segments i { flex: 1; background: var(--cream-30); border-radius: 2px; overflow: hidden; position: relative; }
.segments i::after { content: ""; position: absolute; inset: 0; background: var(--cream); transform: scaleX(0); transform-origin: left; transition: transform 0.45s var(--ease); }
.segments i.done::after { transform: scaleX(1); }
.segments i.now::after { animation: seg var(--hold, 5s) linear forwards; }
.segments i.now.static::after { transform: scaleX(1); animation: none; opacity: 0.55; }
@keyframes seg { to { transform: scaleX(1); } }
.slate { display: flex; justify-content: space-between; align-items: center; min-height: 26px; color: var(--cream-60); }
.slate-l { display: inline-flex; align-items: center; gap: 8px; }
.slate-l .flip { font: 500 13px/1 var(--sans); color: var(--cream); letter-spacing: 0.02em; }
.slate-l .of { font: 500 11px/1 var(--sans); color: var(--cream-30); letter-spacing: 0.1em; }
.slate-r { color: var(--cream); }
.slate-r:empty { display: none; }

/* SCORE chip: lives outside the scenes so it survives cuts and is a stable fly target */
.chip {
  position: absolute; z-index: 27; top: calc(var(--safe-top) + 24px); right: 78px;
  display: inline-flex; align-items: center; gap: 6px; height: 26px; min-width: 92px; padding: 0 10px 0 9px; border-radius: var(--r-pill);
  border: 1px solid var(--gold); background: rgba(5, 8, 15, 0.45); color: var(--gold);
  font: 600 11px/1 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; pointer-events: none; transform-origin: 50% 50%;
}
.chip[hidden] { display: none; }
.chip .star { font-style: normal; font-size: 10px; line-height: 1; transform: translateY(-0.5px); }
.chip b { font-weight: 600; }
.chip span { opacity: 0.75; }
.chip .badge { position: absolute; top: -8px; right: -6px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill); background: var(--clay); color: var(--cream); font: 600 10px/18px var(--sans); letter-spacing: 0.04em; text-align: center; font-style: normal; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4); }
.chip .badge[hidden] { display: none; }
.chip.left { right: auto; left: var(--pad); }
.chip.flash { border-color: var(--cream); }

/* split-flap digits (see flap() in core.js) */
.flap { display: inline-flex; gap: 2px; perspective: 300px; }
.flap .digit { position: relative; width: 0.72em; height: 1em; overflow: hidden; border-radius: 3px; }
.flap .digit .top, .flap .digit .bot, .flap .digit .leaf { position: absolute; left: 0; right: 0; height: 50%; overflow: hidden; display: flex; justify-content: center; backface-visibility: hidden; }
.flap .digit .top { top: 0; align-items: flex-start; border-bottom: var(--hairline) solid rgba(16, 24, 39, 0.12); }
.flap .digit .bot { bottom: 0; align-items: flex-start; }
.flap .digit .top > span, .flap .digit .leaf > span { transform: translateY(0); height: 200%; line-height: 1; display: block; }
.flap .digit .bot > span { height: 200%; line-height: 1; display: block; transform: translateY(-50%); }
.flap .digit .leaf { top: 0; align-items: flex-start; transform-origin: 50% 100%; z-index: 2; }

/* ---------- screen + scenes (cuts are GSAP timelines, see cut() in core.js) ---------- */
.screen { position: absolute; inset: 0; }
.scene { position: absolute; inset: 0; overflow: clip; display: flex; flex-direction: column; opacity: 1; contain: layout paint; }
.scene.scroll { overflow-y: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; contain: layout; }
.scene.scroll::-webkit-scrollbar { display: none; }
.scene.cutting { pointer-events: none; }
.no-gsap .scene { animation: cutIn 0.6s ease both; }
.no-gsap .scene.out { animation: cutOut 0.5s ease both; pointer-events: none; }
@keyframes cutIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes cutOut { to { opacity: 0; } }

/* ---------- backdrop: graded photo + act tint + directional scrim + linear Ken Burns ---------- */
.bg { --scrim: 30, 24, 22; position: absolute; inset: 0; z-index: 0; overflow: clip; background: var(--night); }
.bg img {
  width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); transform-origin: var(--kb-origin, 50% 50%);
  transform: scale(var(--kb-from, 1));
  filter: saturate(1.05) contrast(1.02) brightness(0.98);
}
.bg img.ready { animation: var(--kb-name, kbIn) var(--kb-dur, 45s) linear forwards; }
.bg.dim img { filter: saturate(1.04) contrast(1.03) brightness(0.85); }
.bg.deep img { filter: saturate(0.98) contrast(1.04) brightness(0.72); }
.bg.bokeh img { filter: blur(14px) saturate(1.25) brightness(0.6); --kb-from: 1.15; }
.bg.still img, .bg.still img.ready { animation: none; }
@keyframes kbIn { from { transform: scale(var(--kb-from, 1)) translate(0, 0); } to { transform: scale(var(--kb-to, 1.1)) translate(-1.5%, -1%); } }
@keyframes kbOut { from { transform: scale(var(--kb-from, 1.12)) translate(0, 0); } to { transform: scale(var(--kb-to, 1.02)) translate(0, 0); } }
.bg .tint { position: absolute; inset: 0; background: var(--tint, transparent); opacity: var(--tint-a, 0); mix-blend-mode: var(--tint-blend, color); pointer-events: none; }
.bg::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(var(--scrim), 0.9) 0%, rgba(var(--scrim), 0.55) 28%, rgba(var(--scrim), 0.08) 55%, rgba(var(--scrim), 0) 75%, rgba(var(--scrim), 0.3) 100%); }
.bg.dim::after { background: linear-gradient(to top, rgba(var(--scrim), 0.94) 0%, rgba(var(--scrim), 0.72) 30%, rgba(var(--scrim), 0.25) 55%, rgba(var(--scrim), 0.08) 75%, rgba(var(--scrim), 0.35) 100%); }
.bg.deep::after, .bg.bokeh::after { background: linear-gradient(to top, rgba(var(--scrim), 0.95) 0%, rgba(var(--scrim), 0.8) 35%, rgba(var(--scrim), 0.45) 65%, rgba(var(--scrim), 0.3) 100%); }

.fg { position: relative; z-index: 2; flex: 1; display: flex; flex-direction: column; padding: calc(var(--safe-top) + 56px) var(--pad) calc(var(--safe-bottom) + 28px); }
.fg.bottom { justify-content: flex-end; padding-bottom: calc(var(--safe-bottom) + 72px + var(--kb)); }
.fg.middle { justify-content: center; }
.spacer { flex: 1; }

/* ---------- type ---------- */
h1, h2, h3 { font-family: var(--display); font-weight: 300; margin: 0; line-height: 1.02; letter-spacing: -0.015em; }
.title { font-family: var(--display); font-weight: 300; font-size: var(--d-2); line-height: 1.04; letter-spacing: -0.015em; font-variation-settings: "opsz" 96; margin: 0; }
.title em { font-style: italic; color: var(--clay); font-variation-settings: var(--wonk); }
.title.xl { font-size: var(--d-3); font-variation-settings: "opsz" 144; }
.kicker { font: var(--caps); letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--cream-60); margin: 0 0 16px; }
.kicker.clay { color: var(--clay); }
.kicker.gold { color: var(--gold); }
.caption { position: absolute; z-index: 3; top: calc(var(--safe-top) + 62px); left: var(--pad); font-family: var(--display); font-style: italic; font-size: 15px; color: var(--cream-60); letter-spacing: 0.01em; }
.caption b { font: var(--caps); letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--cream); font-style: normal; font-variation-settings: normal; display: block; margin-bottom: 4px; }
.sub { color: var(--cream-60); font-size: var(--t-s); line-height: 1.5; margin: 16px 0 0; max-width: 34ch; }
.muted { color: var(--cream-60); }
.body { font-size: var(--t-m); line-height: 1.5; }

/* word-by-word mask reveal (words() in core.js). Masks open at rest (.done) so descenders show. */
.words { overflow: visible; }
.words .w { display: inline-block; overflow: hidden; vertical-align: bottom; margin-right: 0.22em; padding: 0.02em 0.04em 0.14em; margin-bottom: -0.14em; margin-left: -0.04em; }
.words .w > span { display: inline-block; transform: translateY(130%); animation: wordIn 0.9s var(--ease) forwards; animation-delay: calc(var(--i) * 70ms + var(--d, 0ms)); }
.words.done .w { overflow: visible; }
@keyframes wordIn { to { transform: none; } }
.words.fast .w > span { animation-delay: calc(var(--i) * 40ms + var(--d, 0ms)); }
.split-mask { overflow: hidden; display: inline-block; vertical-align: bottom; padding-bottom: 0.12em; margin-bottom: -0.12em; }
/* SplitText masks (reveal() in core.js) clip descenders while the glyphs rise; reveal() opens each as its glyph lands and marks the node .landed */
.landed .sc-mask, .landed .sw-mask, .landed .sl-mask, .landed .split-mask { overflow: visible !important; }

/* generic keyframed entrances (k() in core.js) — kept as the no-GSAP / reduced fallback */
.k { opacity: 0; animation: kIn 1s var(--ease) forwards; animation-delay: var(--d, 0ms); }
.k.done, .answers > .done { animation: none; opacity: 1; }
.k.left { animation-name: kLeft; }
.k.scale { animation-name: kScale; }
@keyframes kIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes kLeft { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
@keyframes kScale { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }
.rule { height: var(--hairline); background: var(--cream-30); transform: scaleX(0); transform-origin: left; animation: rule 1.2s var(--ease) forwards; animation-delay: var(--d, 0ms); margin: 24px 0; }
@keyframes rule { to { transform: scaleX(1); } }

/* ---------- narrator aside (glass bubble; aside() in core.js) ---------- */
.aside { display: flex; align-items: flex-end; gap: 10px; margin-top: 16px; }
.avatar { flex: none; width: 34px; height: 34px; border-radius: 50%; overflow: hidden; background: linear-gradient(135deg, #2a3a5c, #141f33); display: grid; place-items: center; font-family: var(--display); font-size: 11px; letter-spacing: 0.04em; color: var(--cream); box-shadow: 0 0 0 1px var(--cream-30); transform-origin: 50% 100%; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar.avatar-seal { border-radius:0; overflow:visible; background:none; box-shadow:none; filter:drop-shadow(0 1px 2px #17180e45); }
.avatar.avatar-seal img { object-fit:contain; }
.bubble { position: relative; padding: 10px 14px; border-radius: 16px 16px 16px 4px; background: rgba(244, 238, 227, 0.1); border: 1px solid var(--cream-12); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); font-size: var(--t-m); line-height: 1.4; color: var(--cream); min-height: 42px; transform-origin: 0% 100%; }
.bubble .caret { display: inline-block; width: 1.5px; height: 1em; background: var(--clay); vertical-align: -0.15em; margin-left: 2px; animation: blink 1s steps(2) infinite; }
.bubble.done .caret { display: none; }
.bubble .dots { display: inline-flex; gap: 4px; align-items: center; height: 1.4em; }
.bubble .dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--cream-60); animation: dot 0.9s ease-in-out infinite; }
.bubble .dots i:nth-child(2) { animation-delay: 0.15s; } .bubble .dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes dot { 50% { opacity: 0.3; transform: translateY(-2px); } }
@keyframes blink { 50% { opacity: 0; } }

/* ---------- controls ---------- */
.answers { display: flex; flex-direction: column; gap: 8px; margin-top: 24px; }
.answers > * { opacity: 0; animation: kIn 0.8s var(--ease) forwards; animation-delay: calc(var(--i, 0) * 70ms + var(--d, 0ms)); }
.answers.gs > * { opacity: 1; animation: none; }

.choice, .pill {
  position: relative; width: 100%; min-height: var(--control); text-align: left; padding: 10px 20px; border-radius: var(--r-m); cursor: pointer;
  background: rgba(16, 24, 39, 0.62); border: 1px solid var(--cream-12); box-shadow: inset 0 1px 0 rgba(244, 238, 227, 0.08);
  color: var(--cream); font-size: var(--t-m); font-weight: 500; line-height: 1.3;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  transition: background 0.35s ease, border-color 0.35s ease, color 0.35s ease; /* GSAP owns opacity + transform on controls: a CSS opacity transition corrupts from() end values */
  transform-style: preserve-3d;
}
.choice::after { content: ""; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--cream-30); flex: none; transition: all 0.3s ease; }
.choice.picked { background: var(--cream); color: var(--ink); border-color: var(--cream); }
.choice.picked::after { background: var(--clay); border-color: var(--clay); box-shadow: 0 0 0 4px rgba(210, 104, 74, 0.25); }
.choice.dim { opacity: 0.25; } /* no-GSAP end state; choices() tweens the dim with GSAP */
.choice.prev { border-color: rgba(210, 104, 74, 0.7); }
.choice.prev::after { border-color: var(--clay); }
.choice.right { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), 0 0 24px -6px rgba(201, 164, 92, 0.6); color: var(--cream); }
.choice.right::after { background: var(--gold); border-color: var(--gold); }
.choice.wrong { border-color: var(--clay); }
.choice.wrong::after { background: var(--clay); border-color: var(--clay); }
.choice .face { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; backface-visibility: hidden; }
.choice .face.front { position: relative; overflow: hidden; border-radius: inherit; margin: -10px 0 -10px -20px; padding: 10px 0 10px 20px; min-height: calc(var(--control) - 2px); }
.choice .face.back { position: absolute; inset: 0; padding: 10px 20px; transform: rotateX(180deg); border-radius: inherit; display: flex; align-items: center; justify-content: space-between; }
.choice .face.back.gold { background: var(--gold); color: var(--ink); }
.choice .face.back.clay { background: var(--clay); color: var(--cream); }
.choice .face.back .pts { font: 600 11px/1 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; }
.choice.flipped::after { display: none; }

.field { display: block; }
.field .label { display: block; font: var(--caps); letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--cream-60); margin: 0 0 10px 2px; }
.field input, .field textarea, .field select {
  width: 100%; display: block; min-height: var(--control); padding: 14px 16px; border-radius: var(--r-m); outline: none; -webkit-appearance: none; appearance: none;
  background: rgba(16, 24, 39, 0.62); border: 1px solid var(--cream-12); box-shadow: inset 0 1px 0 rgba(244, 238, 227, 0.08); color: var(--cream);
  font: 500 var(--t-l)/1.4 var(--sans); transition: border-color 0.3s ease, background 0.3s ease;
}
.field input::placeholder, .field textarea::placeholder { color: var(--cream-30); }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--cream-60); background: rgba(16, 24, 39, 0.75); }
.field textarea { resize: none; min-height: 112px; }
.field select option { color: var(--ink); }

.btn {
  position: relative; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
  min-height: var(--control); padding: 0 24px; border-radius: var(--r-pill); border: 0; cursor: pointer;
  background: var(--cream); color: var(--ink); font: 600 13px/1 var(--sans); letter-spacing: 0.12em; text-transform: uppercase;
  box-shadow: 0 10px 28px -14px rgba(0, 0, 0, 0.55); transition: background 0.3s ease, box-shadow 0.2s ease, color 0.3s ease; /* never opacity (see .choice) */
}
.btn.pressed { box-shadow: 0 3px 10px -6px rgba(0, 0, 0, 0.55); }
.btn:disabled { opacity: 0.5; cursor: wait; }
.btn.clay { background: var(--clay); color: var(--cream); }
.btn.gold { background: var(--gold); color: var(--ink); }
.btn.ghost { background: transparent; color: var(--cream); border: 1px solid var(--cream-30); box-shadow: none; }
.btn.sm { width: auto; min-height: var(--tap); padding: 0 18px; font-size: 11px; }
.btn.outline { background: transparent; color: var(--cream); border: 1px solid var(--cream-60); width: auto; align-self: flex-start; padding: 0 30px; box-shadow: none; }
.btn.outline:hover { background: var(--cream); color: var(--ink); }
.link { position: relative; overflow: hidden; background: none; border: 0; padding: 12px 4px; min-height: var(--tap); color: var(--cream-60); font-size: 13px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; border-radius: var(--r-xs); }
.row { display: flex; gap: 12px; align-items: center; }
.row.between { justify-content: space-between; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.error { color: #f0a08a; font-size: var(--t-s); margin: 8px 0 0; min-height: 1.2em; }
.error:empty { display: none; }
.hint { font: var(--caps); letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--cream-60); text-align: center; animation: pulse 2.4s ease-in-out infinite; margin: 0; }
@keyframes pulse { 50% { opacity: 0.3; } }
.ripple { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; background: currentColor; opacity: 0.28; pointer-events: none; transform: scale(0); }
.corner { min-height: var(--tap); font-size: var(--t-xs); }

/* ---------- names lockup (lockup() in core.js) ---------- */
.lockup { font-family: var(--display); font-weight: 300; line-height: 0.88; letter-spacing: -0.035em; font-variation-settings: "opsz" 144; }
.lockup .n { display: block; font-size: var(--d-4); white-space: nowrap; }
.lockup .n2 { margin-left: 26%; }
/* the ampersand: the real Fraunces italic glyph (.fill) under one SVG stroke (.draw, W.couple.amp) stretched over the glyph box; the stroke draws itself, then the glyph takes over */
.lockup .amp { display: block; font-style: italic; color: var(--clay); font-size: clamp(34px, 11vw, 46px); margin: -2px 0 -8px 48%; font-variation-settings: "opsz" 144, "WONK" 1, "SOFT" 30; line-height: 1; }
.lockup .amp .glyph { position: relative; display: inline-block; line-height: 1; vertical-align: baseline; }
.lockup .amp .draw { position: absolute; inset: 0; width: 100%; height: 100%; display: block; overflow: visible; pointer-events: none; }
.lockup .amp .draw path { fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.lockup .amp .fill { position: relative; }
.lockup.settled .amp .draw, .no-gsap .lockup .amp .draw { display: none; }
.lockup .c { display: inline-block; opacity: 0; transform: translateY(0.25em); animation: letterIn 0.9s var(--ease-spring) forwards; animation-delay: calc(var(--i) * 45ms + var(--d, 0ms)); margin-left: var(--kern, 0); transform-origin: 0% 100%; }
.lockup.gs .c { animation: none; opacity: 1; transform: none; }
@keyframes letterIn { to { opacity: 1; transform: none; } }
.lockup.sm .n { font-size: 40px; }
.lockup.sm .amp { font-size: 22px; margin: 0 0 -4px 46%; }

/* ---------- round card interstitial (roundCard() in core.js) ---------- */
.round-card { position: absolute; inset: 0; z-index: 12; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; padding: var(--pad); background: var(--night); overflow: hidden; }
.round-card::before { content: ""; position: absolute; inset: 0; background: radial-gradient(80% 60% at 50% 30%, #182540, var(--night) 70%); }
.round-card > * { position: relative; }
.round-card .caps { color: var(--cream-60); margin-bottom: 12px; }
.round-card .numeral { font-family: var(--display); font-weight: 300; font-size: 120px; line-height: 0.9; letter-spacing: -0.04em; font-variation-settings: "opsz" 144; color: var(--cream); transform-origin: 50% 100%; }
.round-card .rtitle { font-family: var(--display); font-style: italic; font-weight: 300; font-size: 30px; line-height: 1.1; margin-top: 16px; color: var(--cream); font-variation-settings: var(--wonk); }
.round-card .rsub { margin-top: 12px; color: var(--cream-60); }

/* ---------- score toast + streak + wax seal (score.add() in core.js) ---------- */
.score-toast { position: absolute; z-index: 29; left: 0; top: 0; transform: translate(-50%, -50%); text-align: center; pointer-events: none; white-space: nowrap; }
.score-toast .big { font-family: var(--display); font-weight: 300; font-size: 44px; line-height: 1; letter-spacing: -0.02em; color: var(--gold); font-variant-numeric: tabular-nums lining-nums; text-shadow: 0 2px 18px rgba(5, 8, 15, 0.6); }
.score-toast .big.zero { color: var(--cream-60); }
.score-toast .unit { margin-top: 6px; color: var(--cream); text-shadow: 0 1px 8px rgba(5, 8, 15, 0.8); }
.score-toast .unit.sub { color: var(--cream-60); margin-top: 4px; font-size: 10px; letter-spacing: 0.18em; }
.score-toast .wax { width: 56px; height: 56px; margin: 0 auto 10px; border-radius: 50%; display: grid; place-items: center; color: var(--cream); font-family: var(--display); font-style: italic; font-size: 20px;
  background: radial-gradient(circle at 36% 32%, #e28868, var(--clay) 50%, #9e4a33); box-shadow: inset 0 2px 5px rgba(255, 255, 255, 0.35), inset 0 -3px 6px rgba(0, 0, 0, 0.25), 0 8px 18px -6px rgba(0, 0, 0, 0.6); }
.score-fly { position: absolute; z-index: 29; width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 12px 2px rgba(201, 164, 92, 0.6); pointer-events: none; }
.streak-toast { position: absolute; z-index: 27; right: 78px; top: calc(var(--safe-top) + 54px); color: var(--gold); pointer-events: none; white-space: nowrap; }
.streak-spark { position: absolute; z-index: 27; width: 4px; height: 4px; margin: -2px 0 0 -2px; border-radius: 50%; background: var(--gold); pointer-events: none; }

/* ---------- toast (top pill) + bottom sheet ---------- */
#toasts { position: absolute; left: 0; right: 0; top: calc(var(--safe-top) + 62px); z-index: 32; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.toast { font: var(--caps); letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--cream); background: rgba(5, 8, 15, 0.85); border: 1px solid var(--cream-12); padding: 12px 18px; border-radius: var(--r-pill); max-width: calc(100% - 48px); text-align: center; line-height: 1.4; }
.toast.gold { color: var(--gold); border-color: var(--gold-soft); }
.toast.clay { color: #f0a08a; }
.program .toast { background: var(--ink); }
#sheets { position: absolute; inset: 0; z-index: 33; pointer-events: none; }
.sheet-scrim { position: absolute; inset: 0; background: rgba(5, 8, 15, 0.5); opacity: 0; pointer-events: auto; }
.sheet { position: absolute; left: 0; right: 0; bottom: 0; background: var(--paper); color: var(--ink); border-radius: var(--r-l) var(--r-l) 0 0; padding: 12px var(--pad) calc(var(--safe-bottom) + 24px); pointer-events: auto; box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.4); }
.sheet .grab { width: 36px; height: 4px; border-radius: 2px; background: rgba(16, 24, 39, 0.2); margin: 0 auto 18px; }
.sheet h2 { font-size: 28px; font-variation-settings: "opsz" 96; }
.sheet .body { color: var(--ink-3); margin-top: 8px; }
.sheet .actions { display: flex; flex-direction: column; gap: 8px; margin-top: 24px; }
.sheet .btn { background: var(--ink); color: var(--paper); }
.sheet .btn.clay { background: var(--clay); color: var(--cream); }
.sheet .btn.ghost { background: transparent; color: var(--ink); border: 1px solid rgba(16, 24, 39, 0.2); }
.sheet .link { color: var(--ink-3); align-self: center; }

/* ---------- act bar (bottom): four acts on a timeline; mini (line + dots) or full (pills) ---------- */
.actbar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 26; padding: 0 var(--pad) calc(var(--safe-bottom) + 10px); pointer-events: none; transition: opacity 0.5s ease; }
.actbar.hidden, .kb .actbar { opacity: 0; pointer-events: none; }
.actbar::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 110px; z-index: -1; background: linear-gradient(transparent, rgba(5, 8, 15, 0.75)); pointer-events: none; }
.acts { display: flex; justify-content: space-between; align-items: center; color: var(--cream-60); margin: 0 0 8px; }
.acts button { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); background: none; border: 0; padding: 6px 4px; margin: 0 -4px; border-radius: var(--r-xs); color: inherit; font: var(--caps-xs); letter-spacing: var(--caps-xs-track); text-transform: uppercase; cursor: default; pointer-events: auto; overflow: hidden; }
.acts button:last-child { margin-right: calc(-1 * var(--caps-xs-track)); }
.acts button.now { color: var(--cream); }
.acts button.open { cursor: pointer; }
.acts button.lock { color: var(--cream-30); }
.actline { position: relative; height: var(--hairline); background: var(--cream-12); display: flex; justify-content: space-between; }
.actline i { width: 5px; height: 5px; border-radius: 50%; background: var(--cream-30); margin-top: -2px; position: relative; z-index: 1; transition: transform 0.3s var(--ease), background 0.3s ease; }
.actline i.now { background: var(--clay); transform: scale(1.4); box-shadow: 0 0 0 3px rgba(210, 104, 74, 0.25); animation: dotPulse 2.2s ease-in-out infinite; }
.actline i.done { background: var(--cream); }
@keyframes dotPulse { 50% { box-shadow: 0 0 0 6px rgba(210, 104, 74, 0.12); } }
.actline b { position: absolute; left: 0; top: 0; height: var(--hairline); width: 100%; background: var(--cream); transform: scaleX(var(--p, 0)); transform-origin: left; transition: transform 0.9s var(--ease-cine); }
.actbar.mini .acts { height: 0; margin: 0; opacity: 0; overflow: hidden; }
.actbar.mini .actline { pointer-events: auto; cursor: pointer; }
.actbar.mini::before { height: 70px; }
.actbar.mini { padding-bottom: calc(var(--safe-bottom) + 14px); }
.actbar.full .acts { opacity: 1; height: auto; transition: opacity 0.4s ease; }

/* ---------- sound toggle (44px) + hint ---------- */
.sound { position: absolute; right: var(--pad); top: calc(var(--safe-top) + 15px); z-index: 27; width: var(--tap); height: var(--tap); border-radius: 50%; border: 1px solid var(--cream-30); background: rgba(5, 8, 15, 0.25); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); color: var(--cream); display: grid; place-items: center; cursor: pointer; opacity: 0.85; transition: opacity 0.3s ease; overflow: hidden; }
.sound[hidden] { display: none; }
.sound .w1, .sound .w2 { opacity: 0.25; transition: opacity 0.3s ease; }
.sound[aria-pressed="true"] .w1 { opacity: 1; animation: wave 1.6s ease-in-out infinite; }
.sound[aria-pressed="true"] .w2 { opacity: 1; animation: wave 1.6s ease-in-out infinite 0.3s; }
@keyframes wave { 50% { opacity: 0.3; } }
/* play() refused (autoplay policy): a slash across the icon until a tap succeeds; the hint says "Tap again for music" */
.sound .slash { opacity: 0; transition: opacity 0.3s ease; }
.sound.blocked .slash { opacity: 1; }
.sound.blocked .w1, .sound.blocked .w2 { opacity: 0.12; }
.sound-hint { position: absolute; z-index: 27; right: calc(var(--pad) + 52px); top: calc(var(--safe-top) + 15px); height: var(--tap); display: flex; align-items: center; color: var(--cream-60); margin: 0; pointer-events: none; white-space: nowrap; }
.sound-hint[hidden] { display: none; }

/* ---------- keyboard: --kb / .kb set by core from visualViewport ---------- */
.kb .bg img { animation-play-state: paused; }

/* ---------- chrome on the cream program page (.device.program) ---------- */
.program .topbar, .program .chip { display: none; }
.program .actbar { color: var(--ink); }
.program .actbar::before { background: linear-gradient(rgba(244, 238, 227, 0), rgba(244, 238, 227, 0.96) 55%); }
.program .acts { color: var(--ink-3); }
.program .acts button.now { color: var(--ink); }
.program .acts button.lock { color: rgba(16, 24, 39, 0.3); }
.program .actline { background: rgba(16, 24, 39, 0.12); }
.program .actline i { background: rgba(16, 24, 39, 0.3); }
.program .actline i.done { background: var(--ink); }
.program .actline b { background: var(--ink); }
.program .sound { color: var(--ink); border-color: rgba(16, 24, 39, 0.2); background: rgba(255, 255, 255, 0.5); }
.program .sound-hint { color: var(--ink-3); }
.program .muted { color: var(--ink-3); }

/* ---------- delight (js/delight.js): tilt sheen on paper objects, CTA sweep, chip shimmer, gold wash ---------- */
/* .sheen: a soft 115° highlight whose position follows --tilt (set on #device: gamma/45 on a phone, pointer x on desktop).
   It is a ::before so a module's own ::after scrim (the datecard) keeps working; background-position only repaints this layer. */
.sheen { position: relative; }
.sheen::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; pointer-events: none; /* z 1: above the paper, under z-indexed text (.datecard .in) and, inside the envelope's 3D context, under the front/flap */
  background: linear-gradient(115deg, rgba(255, 255, 255, 0) 42%, rgba(255, 255, 255, 0.22) 50%, rgba(255, 255, 255, 0) 58%);
  background-size: 250% 100%; background-position: calc(50% + var(--tilt, 0) * 50%) 0; }
/* a light sweeps the primary CTA every 4.5s (delight.js tweens xPercent; .btn clips it) */
.btn .cta-sheen { position: absolute; top: -20%; bottom: -20%; left: 0; width: 45%; pointer-events: none; z-index: 0;
  background: linear-gradient(100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.45) 50%, rgba(255, 255, 255, 0) 100%); transform: translateX(-160%) skewX(-18deg); }
.btn > :not(.cta-sheen) { position: relative; }
/* the SCORE chip: a gold shimmer every 8s, clipped to the pill (the badge hangs outside, so the clip is its own layer) */
.chip .shine-clip { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.chip .shine { position: absolute; top: -30%; bottom: -30%; left: 0; width: 40%; transform: translateX(-160%) skewX(-18deg);
  background: linear-gradient(100deg, rgba(201, 164, 92, 0) 0%, rgba(201, 164, 92, 0.5) 50%, rgba(201, 164, 92, 0) 100%); }
/* gold wash: the vignette warms for 1.2s when your leaderboard row lands (.device.gold) */
.vignette::after { content: ""; position: absolute; inset: 0; opacity: 0; transition: opacity 0.9s ease; pointer-events: none;
  background: radial-gradient(100% 90% at 50% 50%, transparent 40%, rgba(201, 164, 92, 0.28)); }
.device.gold .vignette::after { opacity: 1; transition-duration: 0.3s; }
/* LQIP under a plate (backdrop() sets the image inline) */
.bg.lq { background-repeat: no-repeat; }

/* ---------- reduced motion: simplified, never dead (durations live in core M/R too) ---------- */
@media (prefers-reduced-motion: reduce) {
  .grain { animation: none; }
  .sheen::before { display: none; } /* a static highlight reads as a stain */
  .btn .cta-sheen, .chip .shine-clip { display: none; }
  .bg img, .bg img.ready { animation: none; transform: scale(1.04); }
  .k, .answers > * { animation: kFade 0.2s ease both; animation-delay: var(--d, 0ms); }
  .tiles .tile, .msg { animation-duration: 0.2s; }
  .words .w > span { animation: none; transform: none; }
  .words .w { overflow: visible; }
  .lockup .c { animation: none; opacity: 1; transform: none; }
  .lockup .amp .draw { display: none; }
  .rule { animation: none; transform: none; }
  .actline i.now { animation: none; }
  .segments i::after { transition: none; }
  .hint { animation: none; }
  @keyframes kFade { from { opacity: 0; } to { opacity: 1; } }
}

/* Charlie, Oct 24: no bottom bar anywhere. The act bar is retired; progress lives in the top HUD only. */
.actbar, .actbar::before { display: none !important; }

/* Charlie, Oct 24: don't show points during the game. Scores are still kept for the leaderboard. */
#chip { display: none !important; }

/* Charlie, Oct 24: don't show rounds. No "Round 03 / 07" slate or round segments in the HUD. */
.topbar .slate, .topbar .segments { display: none !important; }

/* Quiet return to the opening: a tiny visible circle within a 44px tap target. */
.start-over { position: absolute; left: calc(var(--pad) - 8px); top: calc(var(--safe-top) + 15px); z-index: 27; width: 44px; height: 44px; min-height: 44px; padding: 0; display: grid; place-items: center; border: 0; border-radius: 50%; color: var(--cream); background: transparent; opacity: 0.24; cursor: pointer; transition: opacity 0.2s ease; }
.start-over::before { content: ""; position: absolute; inset: 8px; border: 1px solid currentColor; border-radius: 50%; background: rgba(5, 8, 15, 0.1); opacity: 0.5; }
.scene-back { left: calc(var(--pad) + 36px); }
.start-over svg { width: 13px; height: 13px; }
.start-over span { display: none; }
.start-over[hidden] { display: none; }
.start-over:hover, .start-over:focus-visible { opacity: 0.9; }
.start-over:focus-visible { outline: 2px solid var(--gold); outline-offset: 0; }
.program .start-over { color: var(--ink); background: transparent; }
.program .start-over::before { background: rgba(255, 255, 255, 0.1); }
.story .caption { top: calc(var(--safe-top) + 72px); }
