/* tv-layers.css — canonical z-index layering for game TV views.
   Solves the recurring z-index footgun: opaque body background hides
   `z-index: -1` fixed elements, broad `body > *` selectors trample
   already-positioned chrome. Use these classes instead of inventing
   per-game stacking. */

/* Background images stacked at z:0, fully covered, transitionable.
   Default opacity 0 — add the `.visible` modifier to show.
   Override opacity per element or per game by setting --tv-bg-opacity. */
.tv-bg-layer {
  position: fixed;
  inset: 0;
  /* width/height: 100% are NOT redundant with inset:0 for <img> tags.
     Replaced elements with no explicit dimensions fall back to their
     intrinsic image size, so without these the bg renders at the
     source-pixel size of the .webp (often >viewport). */
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  opacity: 0;
  transition: opacity 600ms ease;
  pointer-events: none;
}
.tv-bg-layer.visible {
  opacity: var(--tv-bg-opacity, 0.40);
}

/* Main game content lifts above bg layers via z:1 in its own stacking
   context. Apply to the top-level container (typically the .stage div). */
.tv-content-layer {
  position: relative;
  z-index: 1;
}

/* Chrome that should sit above all game content — mascots, toasts,
   floating controls. Authors still pick the corner via top/right/etc.
   Note: pointer-events: none is intentional for decorative chrome.
   Containers that wrap clickable controls must override with
   `pointer-events: auto` in per-game CSS. */
.tv-overlay-layer {
  position: fixed;
  z-index: 10;
  pointer-events: none;
}

/* ─── Fixed-resolution scaled canvas ─────────────────────────────────
   Wrap a game's TV content in <div class="tv-canvas"> and call
   mountTvCanvas() from /framework/tv-canvas.js. The canvas is sized
   at --tv-canvas-width × --tv-canvas-height (default 1920×1080) and
   uniformly scaled to fit the viewport via JS-set --tv-canvas-scale.
   A transformed ancestor establishes the containing block for
   `position: fixed` descendants, so .tv-bg-layer / .tv-overlay-layer
   become canvas-fixed (not viewport-fixed) automatically.
   See spec docs/superpowers/specs/2026-05-28-tv-canvas-scaling-design.md. */
/* The scaled stage overscans by ~1 device px (tv-canvas.js tvCanvasScale) to
   hide the fractional-scale canvas-compositing seam; this clips that bleed so
   it never produces a scrollbar. Scoped with :has() to only pages that mount a
   .tv-canvas stage (games + shell) — never a plain scrolling page that merely
   links this stylesheet. TV stages are fixed; panels use their own inner
   overflow. */
html:has(.tv-canvas) { overflow: hidden; }

.tv-canvas {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--tv-canvas-width, 1920px);
  height: var(--tv-canvas-height, 1080px);
  transform: translate(-50%, -50%) scale(var(--tv-canvas-scale, 1));
  transform-origin: center center;
}
