:root {
  /* Twin Peaks Red Room palette (sampled from initial_screen_bg.jpg) */
  --rr-void: #0F0203;     /* page background, readability layer */
  --rr-umber: #4D342D;    /* quiet surfaces */
  --rr-oxblood: #4B090B;  /* button fills, hover surfaces */
  --rr-taupe: #705448;    /* pressed surfaces, subtle borders */
  --rr-clay: #8B6B58;     /* decorative accents */
  --rr-sand: #AB8B75;     /* loader, decorative highlights */

  /* Content over the Red Room */
  --cream: #F5F5DC;       /* primary text + icons */
  --cream-2: #E1D6C1;     /* secondary text */

  --sans: 'Oswald', 'Arial Narrow', 'Helvetica Neue', sans-serif;
  --serif: 'Libre Caslon Text', Georgia, 'Times New Roman', serif;
  --gutter: max(16px, env(safe-area-inset-left));

  /* Motion: quick, almost simultaneous top-to-bottom reveal */
  --stagger: 65ms;
  --fade: 420ms;
  --enter: 250ms;         /* text waits for background + readability layer */
  --ease: cubic-bezier(0.2, 0.6, 0.2, 1);
}

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

html, body {
  margin: 0;
  height: 100%;
  background: var(--rr-void);
  color: var(--cream);
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; }

/* Double ring (cream + dark halo) stays visible over the red room and over bright video. */
a:focus-visible,
button:focus-visible {
  outline: 2px solid transparent; /* forced-colors fallback */
  box-shadow: 0 0 0 3px var(--rr-void), 0 0 0 5px var(--cream);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- Layers: bg (0) → scrim (1) → video (2) → screens (3) → corners (10) ---------- */

#app { position: fixed; inset: 0; overflow: hidden; }

#bg, #scrim {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 600ms var(--ease);
}
#bg { z-index: 0; background: var(--rr-void) url("initial_screen_bg.jpg") center / cover no-repeat; }
/* 0.35 everywhere + 0.5 more in the center ≈ 0.68 behind the text: cream ≥ 7:1, cream-2 ≥ 5.5:1
   against the brightest spotlight/floor pixels. */
#scrim {
  z-index: 1;
  background:
    radial-gradient(ellipse 60% 55% at 50% 50%, rgb(15 2 3 / 0.5), rgb(15 2 3 / 0) 100%),
    rgb(15 2 3 / 0.35);
}
/* The start screen stays underneath while playing, so the video crossfades over it and back. */
:is([data-state="idle"], [data-state="playing"], [data-state="ended"]) #bg { opacity: 1; }
:is([data-state="idle"], [data-state="playing"], [data-state="ended"]) #scrim { opacity: 1; transition-delay: 100ms; }

/* ---------- Staggered fades ---------- */

.fx {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--fade) var(--ease), transform var(--fade) var(--ease);
  transition-delay: calc(var(--i, 0) * var(--stagger)); /* leaving: top to bottom, immediately */
}
[data-state="preload"] #preload .fx,
[data-state="idle"] #idle .fx,
[data-state="ended"] #idle .fx,
[data-state="error"] #error .fx,
:is([data-state="idle"], [data-state="playing"], [data-state="ended"]) .corner .fx {
  opacity: 1;
  transform: none;
  transition-delay: calc(var(--enter) + var(--i, 0) * var(--stagger));
}
[data-state="preload"] #preload .fx,
[data-state="error"] #error .fx { transition-delay: calc(var(--i, 0) * var(--stagger)); }
/* Start-screen items begin at --i:2 (the corners hold 0–1 and stay put), so their exit starts right away. */
#idle .fx { transition-delay: calc((var(--i) - 2) * var(--stagger)); }
/* The song credit appears only once the report has played. */
[data-state="idle"] .corner .song-row { opacity: 0; visibility: hidden; }
/* Play follows the fallback note, or takes its slot when the note is hidden (no gap in the rhythm). */
.play-wrap { --i: 6; }
#note[hidden] + .play-wrap { --i: 5; }

/* Containers switch visibility (and focusability) instantly when shown, after their children
   have faded when hidden. Hidden screens never take clicks, even mid-fade. */
.screen, .corner {
  visibility: hidden;
  pointer-events: none;
  transition: visibility 0s linear 700ms;
}
[data-state="preload"] #preload,
[data-state="idle"] #idle,
[data-state="ended"] #idle,
[data-state="error"] #error,
:is([data-state="idle"], [data-state="playing"], [data-state="ended"]) .corner {
  visibility: visible;
  pointer-events: auto;
  transition-delay: 0s;
}

.screen {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 96px var(--gutter) max(32px, env(safe-area-inset-bottom));
  text-align: center;
  text-shadow: 0 1px 10px rgb(15 2 3 / 0.6); /* extra polish only; the scrim carries contrast */
}

.corner { position: absolute; z-index: 10; top: max(20px, env(safe-area-inset-top)); }

/* ---------- Video (playing state only) ---------- */

/* Crossfade: the frame is present (not display:none, so the player survives between plays) but
   transparent while YouTube loads; data-video (set on PLAYING) fades it in over the start screen. */
#video {
  position: absolute; inset: 0; z-index: 2;
  background: var(--rr-void);
  opacity: 0;
  visibility: hidden;
  transition: opacity 800ms var(--ease), visibility 0s linear 800ms;
}
#video { pointer-events: none; } /* only the iframe itself ever takes taps, per the rules below */
[data-state="playing"] #video { visibility: visible; transition: opacity 800ms var(--ease), visibility 0s; }
[data-state="playing"][data-video] #video { opacity: 1; transition-duration: 500ms; } /* quicker in, gentler out */
/* First play (before any replay): a long, even crossfade from the start screen into the report. */
[data-state="playing"][data-video]:not([data-played]) #video { transition: opacity 1000ms ease-in-out, visibility 0s; }

/* Cover the viewport like background-size: cover (16:9 source), then grow the frame so YouTube's
   overlays the API can't hide sit off-screen: title/channel bar above, "More videos" + logo below. */
#video {
  /* Measured with the video paused (when overlays show) at 1440×900 and 1920×1080: title + channel
     occupy the top ~55px, "More videos" / YouTube logo the bottom ~62px. Raise if one peeks in. */
  --yt-crop-top: 64px;
  --yt-crop-bottom: 72px;
  --yt-h: calc(max(100vh, 56.25vw) + var(--yt-crop-top) + var(--yt-crop-bottom));
}
@supports (height: 100dvh) {
  #video { --yt-h: calc(max(100dvh, 56.25vw) + var(--yt-crop-top) + var(--yt-crop-bottom)); }
}
#video iframe {
  position: absolute; left: 50%;
  top: calc(50% + (var(--yt-crop-bottom) - var(--yt-crop-top)) / 2);
  height: var(--yt-h);
  width: calc(var(--yt-h) * 16 / 9);
  transform: translate(-50%, -50%);
  display: block;
  border: 0;
  pointer-events: none; /* no YouTube click-to-pause UI once playing; controls are ours */
}
/* Start screen: the preloaded player is rendered but transparent, ready to crossfade in on Play. */
[data-state="idle"] #video { visibility: visible; transition: opacity 800ms var(--ease), visibility 0s; }

/* Until playback actually starts, taps go to YouTube: iOS only allows unmuted play from a tap on the
   video itself, so if it blocked the start, YouTube's own play button is there to tap. */
[data-state="playing"]:not([data-started]) #video iframe { pointer-events: auto; }

/* Exact values from resources/reference/halftone_filter_and_video_filter_example.html */
[data-state="playing"] #video iframe {
  filter: blur(0px) brightness(0.95) contrast(1) grayscale(0.20) hue-rotate(-20deg) invert(0) opacity(1) saturate(2.5) sepia(0.6) drop-shadow(rgba(0, 0, 0, 0) -1px 0px 0px);
}

/* Solid Red Room tints over the untreated video, blended like Photoshop solid-color layers. */
.tint {
  position: absolute; inset: 0;
  pointer-events: none;
  background: var(--rr-oxblood); /* #4B090B */
}
.tint-soft-light { mix-blend-mode: soft-light; opacity: 0.3; }
.tint-screen { mix-blend-mode: screen; opacity: 0.2; }

.halftone { display: none; }
[data-state="playing"] .halftone {
  display: block;
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle,
      rgba(255, 0, 0, 0.45) 0 0.65px,
      transparent 1.3px) 0 0 / 7px 7px,
    radial-gradient(circle,
      rgba(0, 255, 80, 0.40) 0 0.65px,
      transparent 1.3px) 1px 1px / 7px 7px,
    radial-gradient(circle,
      rgba(0, 100, 255, 0.35) 0 0.65px,
      transparent 1.3px) 3px 3px / 7px 7px;
  background-size: 4px 4px;
  mix-blend-mode: multiply;
  opacity: 0.4;
}

/* Darken the corners so the forecast, song line and mute button stay readable over bright footage. */
[data-state="playing"] #video::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 60% 55% at 0 0, rgb(15 2 3 / 0.85), rgb(15 2 3 / 0.55) 45%, transparent),
    radial-gradient(ellipse 30% 30% at 100% 0, rgb(15 2 3 / 0.7), transparent),
    radial-gradient(ellipse at center, transparent 55%, rgb(15 2 3 / 0.55));
}

/* ---------- Corners ---------- */

/* Top-left forecast, built 1:1 from the design: every size is design px × --u.
   Oswald: cap height 0.81em; with line-height 1 the baseline sits 0.952em below the line top. */
.corner-left {
  --u: clamp(0.128px, 0.0124vw, 0.192px); /* one knob for the whole block's size */
  left: var(--gutter);
  color: var(--cream);
  font-family: var(--sans);
  text-shadow: 0 1px 10px rgb(15 2 3 / 0.6);
}

.forecast {
  display: flex; align-items: center;
  gap: calc(138 * var(--u));
  border-radius: 6px;
}
.forecast .w-icon {
  flex: none;
  width: calc(566 * var(--u)); height: calc(567 * var(--u));
  filter: drop-shadow(0 1px 6px rgb(15 2 3 / 0.6));
}
.forecast-text {
  display: flex; flex-direction: column; line-height: 1; white-space: nowrap;
  position: relative; top: calc(-2.5 * var(--u)); /* optical centering against the icon, per design */
}
.w-place {
  font-size: calc(84 * var(--u)); font-weight: 300;
  letter-spacing: 0.022em; text-transform: uppercase;
}
.w-temp {
  margin: calc(19.6 * var(--u)) 0 0 calc(-17 * var(--u)); /* the design sets the numerals a touch left */
  font-size: calc(298 * var(--u)); font-weight: 600;
}
.w-cond {
  margin-top: calc(7.6 * var(--u));
  font-size: calc(119 * var(--u)); font-weight: 500;
  text-transform: uppercase;
}
.forecast:hover .w-place { text-decoration: underline; text-underline-offset: 0.2em; text-decoration-thickness: 1px; }

.song-row {
  display: flex; align-items: flex-end;
  gap: calc(34.5 * var(--u));
  margin: calc(109 * var(--u)) 0 0;
  padding-top: calc(79.6 * var(--u));
  border-top: max(1px, calc(3 * var(--u))) solid var(--cream);
  font-size: calc(83 * var(--u)); font-weight: 300; line-height: 1;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.song-row[hidden] { display: none; }
.song-icon { flex: none; width: calc(49 * var(--u)); height: calc(65 * var(--u)); }

.corner-right { right: max(16px, env(safe-area-inset-right)); }
#mute {
  width: 48px; height: 48px; min-width: 44px; min-height: 44px;
  display: grid; place-items: center;
  border: 1px solid rgb(245 245 220 / 0.6);
  border-radius: 50%;
  background: rgb(15 2 3 / 0.55);
  padding: 0;
  transition: background-color 150ms ease, border-color 150ms ease;
}
#mute:hover { background: var(--rr-oxblood); border-color: var(--cream); }
#mute:active { background: var(--rr-taupe); }
#mute svg { width: 24px; height: 24px; animation: icon-in 180ms var(--ease); } /* new icon on every toggle */
@keyframes icon-in { from { opacity: 0; transform: scale(0.85); } }

/* ---------- Screens ---------- */

.w-icon svg { width: 100%; height: 100%; display: block; }

.eyebrow {
  margin: 0;
  font-family: var(--sans); font-size: 14px; font-weight: 400;
  letter-spacing: 0.5em; text-transform: uppercase;
  color: var(--cream-2);
}

.title {
  margin: 0 0 20px;
  font-family: var(--sans); font-weight: 500;
  font-size: clamp(40px, 9vw, 72px); line-height: 1;
  letter-spacing: 0.3em; text-transform: uppercase;
  margin-right: -0.3em; /* balance trailing letter-spacing */
}
.title > span { display: block; }
.title-sub {
  margin-top: 10px;
  font-size: 0.32em; font-weight: 400; letter-spacing: 0.6em;
  color: var(--cream-2);
}

.weekday {
  margin: 14px 0 32px;
  font-size: 15px; letter-spacing: 0.3em; text-transform: uppercase;
}

.note {
  margin: -12px 0 32px;
  max-width: 34ch;
  font-style: italic; font-size: 17px; line-height: 1.5;
}
.note span { display: block; }

.round-btn {
  width: 96px; height: 96px;
  flex-shrink: 0; aspect-ratio: 1; /* never squashed into an oval by the flex column */
  display: grid; place-items: center;
  border: 1.5px solid var(--cream);
  border-radius: 50%;
  background: rgb(75 9 11 / 0.55);
  padding: 0;
  transition: background-color 180ms ease, transform 180ms ease;
}
.round-btn:hover { background: var(--rr-oxblood); transform: scale(1.04); }
.round-btn:active { background: var(--rr-taupe); transform: scale(0.98); }
.round-btn svg { width: 40px; height: 40px; }
#play svg { margin-left: 5px; }
#replay, [data-played] #play { display: none; }
[data-played] #replay { display: grid; }

#error-msg { margin: 24px 0; font-size: 20px; max-width: 32ch; }

.text-btn {
  min-height: 44px; padding: 10px 28px;
  border: 1px solid var(--cream); border-radius: 999px;
  background: rgb(75 9 11 / 0.55);
  font-family: var(--sans); letter-spacing: 0.25em; text-transform: uppercase;
  transition: background-color 150ms ease;
}
.text-btn:hover { background: var(--rr-oxblood); }

/* ---------- Preloader ---------- */

.loader-line {
  display: block; width: 120px; height: 1px; margin-top: 20px;
  background: linear-gradient(90deg, transparent, var(--rr-sand), transparent) -120px 0 / 120px 1px no-repeat;
  animation: sweep 1.6s ease-in-out infinite;
}
@keyframes sweep { to { background-position: 120px 0; } }

@media (prefers-reduced-motion: reduce) {
  .fx, #bg, #scrim, #video, .screen, .corner {
    transition-duration: 120ms !important;
    transition-delay: 0s !important;
  }
  .fx { transform: none !important; }
  .loader-line { animation: none; background-position: 0 0; }
  #mute svg { animation: none; }
  .round-btn, .round-btn:hover, .round-btn:active { transform: none; }
}

/* ---------- TEMPORARY TEST PANEL (remove before launch) ---------- */

#test-panel {
  position: fixed; z-index: 100;
  top: 8px; left: 50%; transform: translateX(-50%);
  width: min(560px, calc(100vw - 16px));
  max-height: calc(100vh - 16px); overflow: auto;
  background: #fff8e6; color: #222;
  border: 2px dashed #c0392b; border-radius: 8px;
  font: 13px/1.3 system-ui, sans-serif;
}
#test-panel summary { padding: 8px 12px; font-weight: 700; color: #c0392b; cursor: move; touch-action: none; user-select: none; }
#test-panel summary small { font-weight: 400; opacity: 0.7; }
#test-form {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px;
  padding: 0 12px 12px;
}
#test-form label { display: grid; gap: 2px; font-weight: 600; }
#test-form input, #test-form select { font: inherit; padding: 4px 6px; min-width: 0; }
#test-form button {
  grid-column: 1 / -1; padding: 8px;
  background: #c0392b; color: #fff; border: 0; border-radius: 4px; font-weight: 700;
}
