/* scene.css — the shared visual core for Cue `scene`.
 *
 * Built to /Users/.../SF_2026-03_Brand/02_Strategy/cue-scene-design.md (§3, §5.2.7).
 * Both the maker (scene.html) and the live page (scene-live.html) import this.
 *
 * RULES baked in:
 *  - ALL scene visuals are driven by CSS custom properties set by the renderer:
 *      --sc-bg --sc-accent --sc-accent2 --sc-text --sc-font
 *    plus dataset hooks: [data-screen] [data-layout] [data-bgtex] on #screen / .sc-content.
 *  - HR-6: the type scale uses px/vw clamp() ONLY — NO `cqw`, no container-query units,
 *    so the exported foreignObject subtree sizes correctly at the true DIMS px width.
 *  - §5.2.7: NO `backdrop-filter`, NO `mix-blend-mode` (both unreliable in foreignObject).
 *  - The STREAMER palette lives ONLY on #screen. SF cream/ink/teal/copper stays on chrome.
 *
 * #screen is sized to DIMS[ar].w × h in REAL px (set inline by the page) and scaled
 * to fit the viewport via transform: scale() on a wrapper — never via cqw on type.
 */

/* ---- Self-hosted display faces (HR-7) — same-origin, fixes export font-inlining --- */
/* DM Sans + Oswald are variable fonts: one file each, weight range on the axis.        */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/cue/fonts/dmsans-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/cue/fonts/anton-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Bebas Neue';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/cue/fonts/bebasneue-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/cue/fonts/spacemono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/cue/fonts/spacemono-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/cue/fonts/oswald-var.woff2') format('woff2');
}

/* ---- The stage --------------------------------------------------------------------- */
/* #screen carries the streamer palette via CSS vars + a sensible fallback set so a bare
 * page (no token) still renders the brand defaults. The renderer overwrites these. */
#screen.scene-screen {
  --sc-bg: #18211f;
  --sc-accent: #2a7068;
  --sc-accent2: #c46828;
  --sc-text: #f5f0e6;
  --sc-font: "DM Sans", system-ui, sans-serif;

  position: relative;
  overflow: hidden;
  background: var(--sc-bg);
  color: var(--sc-text);
  font-family: var(--sc-font);
  /* width/height set inline to DIMS[ar].w × h in real px. */
}

/* ---- Background layers (decorative; aria-hidden) ----------------------------------- */
.sc-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

/* Radial floor from bg up into accent2 — translucent fill, NOT mix-blend (§5.2.7). */
.sc-bg-grad {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 50% 118%,
      color-mix(in srgb, var(--sc-accent2) 42%, transparent) 0%,
      transparent 60%),
    linear-gradient(180deg, transparent 40%, color-mix(in srgb, var(--sc-bg) 0%, transparent) 100%);
}

/* Texture: none | dots | scan, selected by [data-bgtex] on #screen. */
.sc-bg-tex { position: absolute; inset: 0; opacity: .5; }
#screen[data-bgtex="none"] .sc-bg-tex { display: none; }
#screen[data-bgtex="dots"] .sc-bg-tex {
  background-image: radial-gradient(color-mix(in srgb, var(--sc-text) 14%, transparent) 1.6px, transparent 1.6px);
  background-size: 34px 34px;
}
#screen[data-bgtex="scan"] .sc-bg-tex {
  background-image: repeating-linear-gradient(
    0deg,
    color-mix(in srgb, var(--sc-text) 7%, transparent) 0px,
    color-mix(in srgb, var(--sc-text) 7%, transparent) 2px,
    transparent 2px,
    transparent 5px);
}

/* Slow accent glow pulse — pure CSS animation, paused by export-freeze. */
.sc-bg-pulse {
  position: absolute; left: 50%; top: 50%;
  width: 70%; height: 70%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--sc-accent) 30%, transparent) 0%, transparent 70%);
  animation: sc-pulse 6s ease-in-out infinite;
}
@keyframes sc-pulse {
  0%, 100% { opacity: .35; transform: translate(-50%, -50%) scale(0.92); }
  50%      { opacity: .65; transform: translate(-50%, -50%) scale(1.06); }
}

/* ---- Content layer ----------------------------------------------------------------- */
.sc-content {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column;
  /* type scale: px + vw only (HR-6) — vw resolves against the export width. */
  padding: 6vw;
  gap: 1.4vw;
}

/* Eyebrow — small label in accent. */
.sc-eyebrow {
  font-size: clamp(18px, 2.2vw, 64px);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sc-accent2);
  line-height: 1.1;
}

/* Title — the big channel name. */
.sc-title {
  font-size: clamp(48px, 8.5vw, 220px);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.02em;
  color: var(--sc-text);
  margin: 0;
}

/* Subtitle. */
.sc-sub {
  font-size: clamp(20px, 2.6vw, 72px);
  font-weight: 400;
  line-height: 1.2;
  color: color-mix(in srgb, var(--sc-text) 82%, transparent);
}

/* Hide any binding the screen map turned off (renderer sets hidden=true). */
.sc-content [data-bind][hidden] { display: none !important; }

/* ---- Countdown clock --------------------------------------------------------------- */
.sc-clock {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--sc-font);
  font-size: clamp(56px, 11vw, 300px);
  font-weight: 800;
  line-height: 1;
  color: var(--sc-accent);
  letter-spacing: 0;
}
/* fixed-width cells so the digits don't jitter as they tick (tabular). */
.sc-clock .cd-cell {
  display: inline-block;
  width: 0.62em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.sc-clock .cd-sep {
  display: inline-block;
  width: 0.34em;
  text-align: center;
  opacity: .75;
}
/* When the countdown reaches 0:00 it flips to accent2 (elapsed). */
.sc-clock.elapsed { color: var(--sc-accent2); }

/* ---- Social pills (built by bindSocials via DOM API only — HR-3) ------------------- */
.sc-socials {
  display: flex; flex-wrap: wrap;
  gap: 1vw;
  margin-top: auto;
}
.sc-handle {
  display: inline-flex; align-items: center; gap: .4em;
  padding: .35em .85em;
  border: 2px solid color-mix(in srgb, var(--sc-accent) 70%, transparent);
  border-radius: 999px;
  font-size: clamp(16px, 1.9vw, 54px);
  font-weight: 700;
  color: var(--sc-text);
  background: color-mix(in srgb, var(--sc-bg) 55%, transparent);
}
.sc-handle-i { color: var(--sc-accent2); line-height: 1; }

/* ---- Optional corner logo (MAKER PREVIEW ONLY — bakes into PNG, never live) -------
 * The renderer (bindLogo) sets img.src to a data:image/ URI only (HR-10) and writes
 * [data-logopos] + [data-logosize] on #screen. The live OBS stage has no .sc-logo
 * element, so this never renders on the broadcast surface. object-fit:contain keeps
 * the streamer's mark undistorted; pointer-events:none keeps it out of the way; a
 * margin holds it off the very edge. z-index:2 = above bg + content, a true overlay.
 * Size is keyed to screen HEIGHT so a logo reads consistently across 16:9 / 9:16 / 4:5. */
.sc-logo {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  object-fit: contain;
  /* default M; [data-logosize] overrides below */
  height: 14%;
  width: auto;
  max-width: 38%;
}
.sc-logo[hidden] { display: none !important; }

/* corner placement (margin from the edges scales with the stage via vw/vh-ish %) */
#screen[data-logopos="lower-right"] .sc-logo { right: 3.5%; bottom: 3.5%; left: auto; top: auto; }
#screen[data-logopos="lower-left"]  .sc-logo { left: 3.5%;  bottom: 3.5%; right: auto; top: auto; }
#screen[data-logopos="upper-right"] .sc-logo { right: 3.5%; top: 3.5%;    left: auto; bottom: auto; }
#screen[data-logopos="upper-left"]  .sc-logo { left: 3.5%;  top: 3.5%;    right: auto; bottom: auto; }

/* S / M / L size (height-based; M is the default already on .sc-logo) */
#screen[data-logosize="S"] .sc-logo { height: 9%; }
#screen[data-logosize="M"] .sc-logo { height: 14%; }
#screen[data-logosize="L"] .sc-logo { height: 20%; }

/* ===================================================================================
 * LAYOUTS (kits) — data-layout on .sc-content, set from LAYOUTS[cfg.kit]
 *   1 center-stack · 2 lower-left · 3 split
 * =================================================================================== */

/* Kit 1 — center-stack: everything centered, vertical rhythm. */
.sc-content[data-layout="center-stack"] {
  align-items: center;
  justify-content: center;
  text-align: center;
}
.sc-content[data-layout="center-stack"] .sc-socials { justify-content: center; margin-top: 2vw; }

/* Kit 2 — lower-left: copy anchored bottom-left, large title. */
.sc-content[data-layout="lower-left"] {
  align-items: flex-start;
  justify-content: flex-end;
  text-align: left;
}
.sc-content[data-layout="lower-left"] .sc-socials { justify-content: flex-start; }

/* Kit 3 — split: eyebrow/title left-top, clock/sub pushed to a right rhythm.
 * Implemented as a 2-column-ish flow without grid template fragility. */
.sc-content[data-layout="split"] {
  align-items: flex-start;
  justify-content: center;
  text-align: left;
}
.sc-content[data-layout="split"] .sc-title { max-width: 70%; }
.sc-content[data-layout="split"] .sc-clock { align-self: flex-end; }
.sc-content[data-layout="split"] .sc-sub { align-self: flex-end; text-align: right; }
.sc-content[data-layout="split"] .sc-socials { justify-content: flex-start; }

/* ===================================================================================
 * LIVE overlay treatment — transparent bg, lower-third bug.
 * [data-screen="live"] forces a transparent canvas so the PNG export carries ALPHA.
 * =================================================================================== */
#screen[data-screen="live"] {
  background: transparent;
}
#screen[data-screen="live"] .sc-bg-grad,
#screen[data-screen="live"] .sc-bg-tex,
#screen[data-screen="live"] .sc-bg-pulse {
  display: none;            /* no full-frame paint behind a live overlay */
}
/* Shrink the content to a lower-third bug pinned bottom-left, regardless of kit. */
#screen[data-screen="live"] .sc-content {
  inset: auto auto 0 0;
  width: auto; height: auto;
  max-width: 70%;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  text-align: left;
  padding: 3vw;
  gap: .6vw;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--sc-bg) 88%, transparent) 0%,
    color-mix(in srgb, var(--sc-bg) 60%, transparent) 70%,
    transparent 100%);
  border-left: 0.5vw solid var(--sc-accent2);
}
#screen[data-screen="live"] .sc-title { font-size: clamp(32px, 4.5vw, 120px); }
#screen[data-screen="live"] .sc-eyebrow {
  color: var(--sc-text);
  background: var(--sc-accent2);
  padding: .15em .6em;
  border-radius: .2em;
}
#screen[data-screen="live"] .sc-socials { margin-top: .6vw; }

/* ===================================================================================
 * STATE rules
 * =================================================================================== */

/* Freeze every animation at its current frame before a PNG shot; restored after. */
body.export-freeze *,
body.export-freeze *::before,
body.export-freeze *::after {
  animation-play-state: paused !important;
}

/* Live page body: chrome-free, fill the viewport, autoplay/loop (OBS has no controls). */
body.live { margin: 0; background: transparent; overflow: hidden; }
body.live #cwrap { width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center; }
/* The stage is a fixed DIMS-px box scaled ONLY by scene-live.js's uniform transform.
   Without flex:none it inherits flex-shrink:1 and the flex row squeezes its width on the
   main axis (while the transform scales off the unshrunk width) → non-uniform "squeeze to
   4:3" in any window whose aspect ≠ the scene's. flex:none keeps the box pristine. */
body.live #screen { flex: none; }

/* Demo embed (guide iframe): hide maker chrome, fill the frame. */
body.demo header,
body.demo #cue-menubar,
body.demo #controls { display: none !important; }
body.demo .sf-cue-body,
body.demo #main { height: 100vh; }
body.demo { overflow: hidden; background: #000; }
