/* FORA v3 — original styles */
/* Playfair Display 500 (OFL-1.1, see fonts/PlayfairDisplay-OFL.txt), subset to A–Z, space, middle dot */
@font-face { font-family: "Playfair Display"; src: url("/fonts/PlayfairDisplay-500-caps.woff2?v=39865b9adf") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Satoshi"; src: url("/fonts/Satoshi-Medium.woff?v=7aeaf037fb") format("woff"); font-weight: 500; font-display: swap; }
/* metric-matched fallbacks so a late font swap doesn't change line boxes */
@font-face { font-family: "Playfair Fallback"; src: local("Georgia"), local("Times New Roman"), local("Liberation Serif"), local("Noto Serif"), local("DejaVu Serif"); size-adjust: 104%; ascent-override: 104%; descent-override: 24%; line-gap-override: 0%; }
@font-face { font-family: "Satoshi Fallback"; src: local("Arial"), local("Liberation Sans"), local("Roboto"), local("Helvetica"); size-adjust: 99%; ascent-override: 98%; descent-override: 24%; line-gap-override: 0%; }

:root {
  --void: #0e0003;
  --velvet: #2a0008;
  --crimson: #c4102f;
  --ember: #ff2a4a;
  --cream: #f4ecdc;
  --cream-dim: rgba(244, 236, 220, .9);
  --serif: "Playfair Display", "Playfair Fallback", Georgia, serif;
  --text: "Satoshi", "Satoshi Fallback", system-ui, sans-serif;
  --pad: clamp(20px, 4vw, 48px);
}
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--void); color: var(--cream); -webkit-text-size-adjust: 100%; }
body { margin: 0; min-height: 100vh; min-height: 100svh; font-family: var(--text); overflow-x: hidden; -webkit-font-smoothing: antialiased; }

/* Layer 0: velvet void, pure CSS (always painted, no WebGL needed) */
.backdrop {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(60% 45% at 78% 22%, rgba(196, 16, 47, .22), transparent 70%),
    radial-gradient(70% 55% at 12% 88%, rgba(196, 16, 47, .30), transparent 72%),
    radial-gradient(120% 90% at 50% 50%, #1c0006 0%, var(--void) 62%, #050001 100%);
}
.backdrop::after { /* soft vignette */
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(85% 75% at 50% 48%, transparent 55%, rgba(0, 0, 0, .55) 100%);
}
/* static art for no-WebGL / reduced motion: text-free render of the scene */
.is-static .backdrop { background: #0e0003 url("/assets/fallback-wide.webp?v=d82dfca23e") center / cover no-repeat; }
@media (max-aspect-ratio: 4/5) { .is-static .backdrop { background-image: url("/assets/fallback-tall.webp?v=a007192504"); } }
@media (prefers-reduced-motion: reduce) {
  .backdrop { background: #0e0003 url("/assets/fallback-wide.webp?v=d82dfca23e") center / cover no-repeat; }
}
@media (prefers-reduced-motion: reduce) and (max-aspect-ratio: 4/5) {
  .backdrop { background-image: url("/assets/fallback-tall.webp?v=a007192504"); }
}

/* Layer 1: WebGL stage (decorative). touch-action only here: drag is ours, pinch-zoom stays with the browser */
.stage { position: fixed; inset: 0; z-index: 1; opacity: 0; transition: opacity 1.4s cubic-bezier(.2, .7, .2, 1); }
.stage canvas { display: block; width: 100%; height: 100%; touch-action: pinch-zoom; cursor: grab; outline: none; }
.stage canvas:active { cursor: grabbing; }
.stage.is-live { opacity: 1; }
@media (max-height: 520px) { .stage canvas { touch-action: pan-y pinch-zoom; } }

/* Layer 2: type, set directly on the scene; it lets taps through to the stage */
.hero, .hint { position: relative; z-index: 2; pointer-events: none; }
:focus-visible { outline: 2px solid var(--cream); outline-offset: 4px; }

.hero {
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 72px var(--pad); text-align: center;
}
.title { margin: 0; width: 100%; font-weight: 400; display: flex; flex-direction: column; align-items: center; }
/* Serif wordmark: inline SVG (Playfair Display outlines), so it needs no font download and cannot shift */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.wm { position: relative; display: block; width: min(72vw, 640px, 96vh); }
.wordmark { display: block; width: 100%; height: 100%; overflow: visible; }
.hat-tilt, .hat-sway { position: absolute; inset: 0; display: block; }
.hat-wobble { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 3px 7px rgba(10, 0, 3, .75)); }
.title-sub {
  display: block; width: 100%; margin-top: clamp(14px, 2.4vh, 24px);
  font: 500 clamp(15px, 4.2vw, 22px)/1.2 var(--serif); letter-spacing: clamp(.34em, 1.6vw, .5em); text-indent: clamp(.34em, 1.6vw, .5em); text-transform: uppercase;
  color: var(--cream); text-shadow: 0 1px 16px rgba(14, 0, 3, .85);
}
.rush {
  margin: clamp(18px, 3vh, 30px) 0 0; width: 100%;
  font: 500 15px/1.4 var(--text); letter-spacing: .42em; text-indent: .42em; text-transform: uppercase;
  color: var(--cream-dim); text-shadow: 0 1px 12px rgba(14, 0, 3, .9);
}
.hint {
  margin: clamp(16px, 2.6vh, 26px) 0 0; width: 100%; text-align: center;
  font: 500 14px/1 var(--text); letter-spacing: .3em; text-indent: .3em; text-transform: uppercase; color: rgba(244, 236, 220, .8);
  opacity: 0; transition: opacity .8s ease;
}
.hint.is-on { opacity: 1; }
@media (min-width: 900px) {
  .rush { font-size: 16px; }
}
@media (max-height: 520px) and (orientation: landscape) {
  .wm { width: min(46vw, 80vh); } .title-sub { margin-top: 6px; } .rush { margin-top: 8px; } .hint { margin-top: 8px; } .hero { padding-top: 10px; padding-bottom: 20vh; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0s !important; animation: none !important; } }

/* R1: soft dark wash behind the type (no box edges) so the tagline holds contrast over the serpent */
.title { position: relative; }
.hero { overflow: hidden; overflow: clip; }   /* the wash is wider than the viewport: clip it so mobile layout width stays = device width */
.title::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: 50%; top: 62%; width: min(1180px, 150vw); height: calc(100% + 30vh);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(10, 0, 3, .78) 0%, rgba(10, 0, 3, .62) 38%, rgba(10, 0, 3, .3) 68%, rgba(10, 0, 3, 0) 100%);
}
.hint { text-shadow: 0 0 10px rgba(10, 0, 3, .95), 0 1px 3px rgba(10, 0, 3, .9); }
/* wide screens: lift the type band so the low sweep of the serpent passes underneath it */
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  .hero { padding-bottom: 22vh; }
}

/* Santa hat: its own SVG layer sharing the wordmark's viewBox, so it is anchored to the A at every size.
   The three wrappers are transformed as whole boxes (compositor-friendly: the fur filter is rasterised once). */
.hat-tilt { transform: rotate(var(--hat-tilt, 0deg)); transition: transform .9s cubic-bezier(.34, 1.8, .5, 1); }
/* The hat stays out of the first frame (visibility: hidden is not painted), so the type paints first and LCP isn't
   held up by rasterising the fur; it then drops onto the A. Absolutely positioned, so no layout shift. */
.hat-sway { visibility: hidden; animation: hat-drop .9s cubic-bezier(.3, 1.5, .45, 1) .45s forwards, hat-sway 5.2s ease-in-out 1.35s infinite alternate; }
@keyframes hat-drop { 0% { visibility: visible; opacity: 0; transform: translateY(-14%) rotate(-12deg); } 35% { opacity: 1; } 100% { visibility: visible; opacity: 1; transform: rotate(-2.2deg); } }
.hat-sway { will-change: transform; }
.hat-wobble.is-wobbling { animation: hat-wobble 1.1s cubic-bezier(.3, 0, .3, 1) both; }
@keyframes hat-show { to { visibility: visible; } }
@keyframes hat-sway { from { transform: rotate(-2.2deg); } to { transform: rotate(2.6deg); } }
@keyframes hat-wobble {
  0% { transform: rotate(0); } 14% { transform: rotate(-11deg) translateY(-1%); } 30% { transform: rotate(8deg); }
  46% { transform: rotate(-5deg); } 62% { transform: rotate(3deg); } 78% { transform: rotate(-1.4deg); } 100% { transform: rotate(0); }
}
@media (prefers-reduced-motion: reduce) {
  .hat-tilt, .hat-sway, .hat-wobble { animation: none !important; transition: none !important; transform: none !important; }
  .hat-sway { animation: hat-show 0s .45s forwards !important; }
}
/* wide screens: the pom-pom overhangs the A towards the ribbon, so the hat is ~10% smaller. `scale` composes with the
   tilt/sway transforms and pivots on the shared transform-origin (the A's apex); absolutely positioned, so no CLS. */
@media (min-width: 1024px) { .hat-tilt { scale: .9; } }

/*hat-origin:start*/ .wm { aspect-ratio: 2741 / 1435; } .hat-tilt, .hat-sway, .hat-wobble { transform-origin: 87.50% 24.25%; } /*hat-origin:end*/

/* iOS 18+ haptic: a visually hidden switch checkbox, toggled with label.click().
   Kept off-screen and out of the tab order so it cannot focus, scroll or shift layout.
   Not display:none / visibility:hidden, which can suppress the system haptic. */
.haptic-switch {
  position: fixed; left: -200px; top: 0; width: 44px; height: 44px;
  margin: 0; padding: 0; overflow: hidden; opacity: 0; pointer-events: none; z-index: -1;
}
.haptic-switch input { margin: 0; }


/* Music mute toggle: cream icon on a velvet disc, bottom-right only (top-left stays clear). */
.audio-toggle {
  position: fixed; z-index: 3; pointer-events: auto;
  right: max(16px, env(safe-area-inset-right, 0px));
  bottom: max(16px, env(safe-area-inset-bottom, 0px));
  width: 44px; height: 44px; margin: 0; padding: 0;
  display: grid; place-items: center;
  border: 1px solid rgba(244, 236, 220, .22);
  border-radius: 50%;
  background: var(--velvet);
  color: var(--cream);
  cursor: pointer;
  box-shadow: 0 2px 16px rgba(10, 0, 3, .55);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.audio-toggle svg { width: 22px; height: 22px; display: block; }
.audio-toggle .icon-off { display: none; }
.audio-toggle.is-muted .icon-on { display: none; }
.audio-toggle.is-muted .icon-off { display: block; }
.audio-toggle:hover { color: #fffaf1; border-color: rgba(244, 236, 220, .4); }

/* Admin draft preview marker (only rendered for /?draft=1 with an admin session). Bottom-left; top-left stays clear. */
.draft-badge {
  position: fixed; z-index: 3; left: max(16px, env(safe-area-inset-left, 0px)); bottom: max(22px, env(safe-area-inset-bottom, 0px));
  padding: 6px 12px; border: 1px solid rgba(244, 236, 220, .3); border-radius: 999px; background: rgba(42, 0, 8, .85);
  font: 500 11px/1 var(--text); letter-spacing: .24em; text-transform: uppercase; color: var(--cream); pointer-events: none;
}
