/* ═══════════════════════════════════════════════════════════════════════════
   adultswim.css — the alternate theme's component layer.

   Extracted from app.css on 2026-08-19. It was 1,124 lines living inside the
   base stylesheet, which meant every read of app.css was 45% a theme nobody
   was looking at and every base-layer edit risked a theme-only selector.
   The palette, the Impact display stack and the squared radii live in
   tokens.css; this is everything built on top of them — the broadcast-caps
   voice, the [media|forest] wordmark homage, the flat black field, the
   censor-chip cards, the test-card gate, the warning-sign buttons, the
   scanline / VHS / glitch / chroma / interrupt system and the bumper card.

   Load order: tokens.css → app.css → darkroom.css → adultswim.css.
   This file is LAST so that every selector here wins without needing extra
   specificity; nothing in it should ever need an !important.

   Every rule is scoped to html[data-theme="adultswim"]. If a rule in here is
   not, it is a bug — it will leak into Darkroom.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
   Adult Swim theme — broadcast-artefact styling. The palette (safety orange /
   SMPTE cyan / hazard yellow on true black), the Impact display stack and the
   squared radii live in tokens.css. This is the component layer: the
   broadcast-caps type voice, the [media|forest] wordmark homage, the flat
   black field, and (in the PHASE A / PHASE B sections below) the censor-chip
   cards, the test-card gate, the warning-sign buttons, the scanline/VHS/
   glitch/chroma/interrupt animation system and the deadpan bumper card.
   Phases 1 + A–D of the LUXURY-THEMES.txt Part I overhaul — all shipped.
   ─────────────────────────────────────────────────────────────────────────── */
/* ── §2.3 broadcast caps: everything titley goes UPPERCASE, tracked ── */
html[data-theme="adultswim"] .railhead .cap,
html[data-theme="adultswim"] .navlink,
html[data-theme="adultswim"] .slice h2,
html[data-theme="adultswim"] .slice .hero-eyebrow,
html[data-theme="adultswim"] .libtitle,
html[data-theme="adultswim"] .libtab,
html[data-theme="adultswim"] .gate-title,
html[data-theme="adultswim"] .gate-sub,
html[data-theme="adultswim"] .ltitle,
html[data-theme="adultswim"] .instrument-title,
html[data-theme="adultswim"] .together-title,
html[data-theme="adultswim"] .hero-title,
html[data-theme="adultswim"] .eyebrow,
html[data-theme="adultswim"] .cap,
html[data-theme="adultswim"] .btn,
html[data-theme="adultswim"] .btn--accent,
html[data-theme="adultswim"] .lbtn,
html[data-theme="adultswim"] .lplay-go,
html[data-theme="adultswim"] .hero-play,
html[data-theme="adultswim"] .reqcard-t,
html[data-theme="adultswim"] .syn-t,
html[data-theme="adultswim"] .menu-name{ text-transform:uppercase; letter-spacing:.06em; }
html[data-theme="adultswim"] .railhead .cap{ letter-spacing:.08em; }
html[data-theme="adultswim"] .slice h2{ letter-spacing:.08em; }
html[data-theme="adultswim"] .gate-title{ letter-spacing:.1em; }

/* ── §2.4 the wordmark is the ONE lowercase element: [media|forest] ── */
html[data-theme="adultswim"] .wordmark{
  text-transform:lowercase; letter-spacing:.02em;
  font-size:calc(var(--head-card)*.78);   /* Impact is wide — shrink to fit */
}
html[data-theme="adultswim"] .wordmark::before{ content:"[ "; opacity:.75; }
html[data-theme="adultswim"] .wordmark::after{ content:" ]"; opacity:.75; }
html[data-theme="adultswim"] .wordmark--lg{ font-size:clamp(17px,2.4vw,21px); letter-spacing:.04em; }
html[data-theme="adultswim"] .bar{ opacity:1; }   /* orange|cyan divider — the brand moment */

/* ── §1.5 orange broadcast text selection ── */
html[data-theme="adultswim"] ::selection{ background:color-mix(in srgb,var(--aurora-green) 40%,transparent); }

/* ── §5.2/§5.9 the flat-black field — dead black is the AS signature ── */
/* grain: killed outright. PERF — this was `opacity:0`, which is NOT the same
   as gone. body::before carries `mix-blend-mode:soft-light` at viewport size,
   and a blend mode forces the browser to keep the entire page beneath it as a
   separate compositing group that must be blended every frame — a transparent
   blend layer still costs a full-viewport blend pass. display:none takes the
   element out of the tree and dissolves the group. */
html[data-theme="adultswim"] body::before{ display:none; }
html[data-theme="adultswim"] .aurora-sky{ display:none; }             /* aurora: REPLACED by the as-fx layer (Phase B) */
html[data-theme="adultswim"] .cursor-glow{ display:none; }            /* deadpan — as-fx is the only atmosphere this theme owns */
html[data-theme="adultswim"] body::after{ height:3px; box-shadow:none; } /* scroll hairline: thicker, no glow — hazard gradient via tokens */
/* The ✦ that used to sit here is gone from the base layer entirely; what
   ::before carries now is the plate number, and a channel index is exactly
   the right register for this theme — so it stays, restyled as a broadcast
   channel marker rather than hidden. */
html[data-theme="adultswim"] .railhead .cap::before{
  display:block; content:"CH " counter(plate,decimal-leading-zero);
  color:var(--aurora-teal); letter-spacing:.16em;
}
html[data-theme="adultswim"] .brandmark{ display:none; }              /* no gem — text only */
/* §5.9 flourish: the gilt sparkle becomes a hard hazard bar */
html[data-theme="adultswim"] .flourish i{
  background:var(--aurora-amber); -webkit-mask:none; mask:none;
  border-radius:0; width:64px; height:2px; filter:none;
}
/* (the Phase-1 hero-eyebrow hairline box was replaced by the §5.7 censor-chip
   REC-dot treatment in the PHASE A section below) */

/* ───────────────────────────────────────────────────────────────────────────
   PHASE A — components + SVG assets (LUXURY-THEMES.txt Part I §4–§5). The
   static broadcast look: censor-chip poster synopses, the test-card gate,
   warning-sign buttons, the REC-dot hero eyebrow, hazard accents.
   SVG catalogue: §4.1 SMPTE bars / §4.3 warning triangle / §4.4 reticle are
   wired below; §4.2 hazard stripe is wired in PHASE B (bumper card). §4.5
   REC-dot, §4.6 censor-bar and §4.7 bracket-logo SVGs are DOCUMENTED VARIANTS
   for og-image/print/derivative contexts — the live forms are a CSS circle,
   the CSS censor chip and the wordmark's CSS brackets, respectively.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── §5.3 topbar + nav: the glass pill becomes a flat black slab ── */
html[data-theme="adultswim"] #topbar{
  background:var(--glass-header-bg);
  backdrop-filter:none; -webkit-backdrop-filter:none;   /* flat black slab: the near-opaque bg hides any blur, so drop the per-scroll pass on the sticky bar */
  border:1px solid var(--border-strong); border-radius:var(--radius-sm);
  box-shadow:0 0 0 1px rgba(0,0,0,.8);
}
html[data-theme="adultswim"] .navlink{border-radius:var(--radius-sm); letter-spacing:.08em;}
html[data-theme="adultswim"] .iconbtn,
html[data-theme="adultswim"] .avatar{border-radius:var(--radius-sm);}   /* the avatar keeps its cyan tint — an equipment lamp */
html[data-theme="adultswim"] .search{border-radius:var(--radius-sm);}
html[data-theme="adultswim"] .search:hover{border-color:var(--aurora-green);}

/* ── §5.4 cards and posters — the censor-chip synopsis ── */
html[data-theme="adultswim"] .poster .syn{ background:none; }          /* soft gradient overlay → nothing; the chip carries the reveal */
html[data-theme="adultswim"] .poster .syn-in{
  background:rgba(0,0,0,.92);
  border-top:2px solid var(--aurora-amber);                            /* hazard top edge */
  width:100%;
}
@media(hover:hover){
  html[data-theme="adultswim"] .poster .syn-in{
    transform:translateY(101%);
    transition:transform .28s steps(3);                                /* three hard jumps up */
  }
  html[data-theme="adultswim"] .poster:hover .syn-in{transform:translateY(0);}
  /* keyboard path: the base .syn focus-within reveal (app.css:919) must not
     land on an empty wrapper — the chip follows focus the way it follows hover */
  html[data-theme="adultswim"] .poster:focus-within .syn-in{transform:translateY(0);}
}
html[data-theme="adultswim"] .syn-t{
  font-family:var(--font-serif); text-transform:uppercase;
  letter-spacing:.06em; font-size:var(--text-base);
}
html[data-theme="adultswim"] .syn-more{color:var(--aurora-green);}
/* spotlight dimming harshened — the gallery move becomes a signal cut. The
   base rule's scale-back is dropped too: AS wants a lighting change, not a
   physical one, and holding transform at `none` on the dimmed cards means the
   compositor only has one animated property to carry across the whole rail. */
html[data-theme="adultswim"] .addgrid:has(.pcard:hover) .pcard:not(:hover){opacity:.3; transform:none;}

/* ── §5.5 the gate — broadcast test card ── */
html[data-theme="adultswim"] #gate{
  background:#000;
  backdrop-filter:none; -webkit-backdrop-filter:none;
}
html[data-theme="adultswim"] .gh-orb,
html[data-theme="adultswim"] .gh-ring,
html[data-theme="adultswim"] .gh-skyline{display:none;}
/* the reticle (§4.4) replaces the glowing centre dot — the base
   translate(-50%,-50%) positioning is untouched */
html[data-theme="adultswim"] .gh-center{
  width:120px; height:120px; border-radius:0; background:transparent;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none'%3E%3Ccircle cx='60' cy='60' r='56' stroke='%23ffffff' stroke-opacity='.85' stroke-width='1'/%3E%3Ccircle cx='60' cy='60' r='44' stroke='%23ffffff' stroke-opacity='.4' stroke-width='1'/%3E%3Ccircle cx='60' cy='60' r='3' fill='%23ffffff'/%3E%3Cpath d='M60 4v18M60 98v18M4 60h18M98 60h18' stroke='%23ffffff' stroke-opacity='.85' stroke-width='1'/%3E%3Cpath d='M0 0h12v12M120 0h-12v12M0 120h12v-12M120 120h-12v-12' stroke='%23ff6600' stroke-width='2'/%3E%3C/svg%3E");
  background-size:contain; box-shadow:none; animation:none; z-index:2;
}
/* SMPTE colour-bar strip (§4.1) along the hero's bottom edge */
html[data-theme="adultswim"] .gate-hero::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:8px; opacity:.85;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='36'%3E%3Crect x='0' width='60' height='36' fill='%23fff'/%3E%3Crect x='60' width='60' height='36' fill='%23ffcc00'/%3E%3Crect x='120' width='60' height='36' fill='%2333ccff'/%3E%3Crect x='180' width='60' height='36' fill='%234de8a0'/%3E%3Crect x='240' width='60' height='36' fill='%23d43d3d'/%3E%3Crect x='300' width='60' height='36' fill='%23ff6600'/%3E%3Crect x='360' width='60' height='36' fill='%23111'/%3E%3C/svg%3E");
  background-size:auto 100%; background-repeat:repeat-x;
}
/* the tagline becomes a bumper line — flat white, tracked, no sheen */
html[data-theme="adultswim"] .gh-tagline h1{
  background:none; -webkit-text-fill-color:var(--text-primary); color:var(--text-primary);
  text-transform:uppercase; letter-spacing:.14em; font-family:var(--font-serif);
  animation:none;
}
html[data-theme="adultswim"] .gh-tagline h1 em{
  background:none; -webkit-text-fill-color:var(--aurora-green); color:var(--aurora-green);
  font-style:normal;
}
html[data-theme="adultswim"] .gh-tagline .sub{
  text-transform:uppercase; letter-spacing:.22em; font-size:var(--text-2xs);
}
/* the gate card: wordmark gradient flattened, hard frame */
html[data-theme="adultswim"] .gate-card .wordmark{
  background:none; -webkit-text-fill-color:var(--text-primary);
}
html[data-theme="adultswim"] .gate-card{
  box-shadow:0 0 0 1px var(--border-strong), 0 24px 60px -12px rgba(0,0,0,.95);
}
/* the documented #gate-user/#gate-pass focus asymmetry, fixed for this theme */
html[data-theme="adultswim"] #gate-user:focus,
html[data-theme="adultswim"] #gate-pass:focus{border-color:var(--aurora-green);}

/* ── §5.6 buttons — warning-sign language ──
   Primary tier: flat safety orange, black Impact caps, hard 2px frame. The
   enamel sheen (btn-sheen) is a luxe gesture — killed here. The "stamp press"
   (shadow collapses on :active) is the harsh interaction. */
html[data-theme="adultswim"] .btn--accent,
html[data-theme="adultswim"] .lbtn,
html[data-theme="adultswim"] .lplay-go,
html[data-theme="adultswim"] .hero-play{
  background:var(--aurora-green); color:#000;
  font-family:var(--font-serif); font-weight:400;
  text-transform:uppercase; letter-spacing:.08em;
  border:2px solid #000; border-radius:var(--radius-sm);
  box-shadow:0 0 0 1px var(--border-strong), 0 2px 0 rgba(0,0,0,.9);
}
html[data-theme="adultswim"] .btn--accent:hover,
html[data-theme="adultswim"] .lbtn:hover,
html[data-theme="adultswim"] .lplay-go:hover,
html[data-theme="adultswim"] .hero-play:hover{
  background:var(--aurora-green-hover); color:#000;
  box-shadow:0 0 0 1px var(--border-strong), 0 3px 0 rgba(0,0,0,.9);
  transform:translateY(-1px);
}
html[data-theme="adultswim"] .btn--accent:active,
html[data-theme="adultswim"] .lbtn:active,
html[data-theme="adultswim"] .lplay-go:active,
html[data-theme="adultswim"] .hero-play:active{
  transform:translateY(1px); box-shadow:0 0 0 1px var(--border-strong);
}
html[data-theme="adultswim"] .btn--accent::before,
html[data-theme="adultswim"] .lbtn::before,
html[data-theme="adultswim"] .lplay-go::before,
html[data-theme="adultswim"] .hero-play::before{display:none;}   /* no sheen */
/* plain tier — censor-chip: black fill, 1px white frame, white caps */
html[data-theme="adultswim"] .btn:not(.btn--accent){
  background:var(--color-bg-elevated); border:1px solid var(--border-strong);
  color:var(--text-primary); border-radius:var(--radius-sm);
}

/* ── §5.7 the hero strip ── */
/* slice titles flatten to broadcast white (the h2 gradient is luxe) */
html[data-theme="adultswim"] .slice h2{
  background:none; -webkit-text-fill-color:var(--text-primary); color:var(--text-primary);
  filter:none; text-shadow:0 2px 0 rgba(0,0,0,.8);
}
/* hero-eyebrow: a censor chip with a REC dot. The dot is the §4.5 form as a
   CSS circle (the SVG is a documented variant): red disc, black ring via
   border (live-dot animates box-shadow, so the ring must not ride it). */
html[data-theme="adultswim"] .slice .hero-eyebrow{
  background:#000; border:1px solid var(--border-strong);
  color:var(--text-primary); border-radius:var(--radius-sm);
  letter-spacing:.18em;
}
html[data-theme="adultswim"] .slice .hero-eyebrow::before{
  content:""; display:inline-block; width:12px; height:12px; margin-right:7px;
  border-radius:50%; background:var(--status-danger);
  border:1.5px solid #000; box-sizing:border-box;
  vertical-align:1px; animation:live-dot 2s ease-in-out infinite;   /* existing keyframes, app.css:600 */
}
/* hover/focus yield badge (§4.3) — rides .slice .in::after (the content
   wrapper; .slice::after is the scrim). Follows the .go buttons' focus/hover
   split exactly: keyboard reveal outside the hover query, pointer inside. */
html[data-theme="adultswim"] .slice .in::after{
  content:""; position:absolute; top:14px; right:14px; z-index:1;
  width:28px; height:24px; pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='56' viewBox='0 0 64 56'%3E%3Cpath d='M32 2 62 54H2Z' fill='%23ffcc00' stroke='%23000' stroke-width='5' stroke-linejoin='round'/%3E%3Crect x='29' y='18' width='6' height='18' fill='%23000'/%3E%3Ccircle cx='32' cy='44' r='3.5' fill='%23000'/%3E%3C/svg%3E");
  background-size:contain; background-repeat:no-repeat;
  opacity:0; transform:translateY(-4px);
  transition:opacity .18s steps(2), transform .18s steps(2);
}
html[data-theme="adultswim"] .slice:focus-visible .in::after{opacity:.92; transform:translateY(0);}
@media(hover:hover){
  html[data-theme="adultswim"] .slice:hover .in::after{opacity:.92; transform:translateY(0);}
}

/* ── §5.8 player: the loading state wears the bumper register ── */
html[data-theme="adultswim"] .pv-loading{
  font-family:var(--font-serif); letter-spacing:.2em; text-transform:uppercase;
}

/* ── §5.10 request chooser — the "!" accent. .ltitle has no base pseudos, so
   ::before is free. The triangle's black stroke reads on the black glass.
   Static signage — no animation, no RM rule. ── */
html[data-theme="adultswim"] .requestbox .ltitle::before{
  content:""; display:inline-block; width:14px; height:12px; margin-right:10px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='56' viewBox='0 0 64 56'%3E%3Cpath d='M32 2 62 54H2Z' fill='%23ffcc00' stroke='%23000' stroke-width='5' stroke-linejoin='round'/%3E%3Crect x='29' y='18' width='6' height='18' fill='%23000'/%3E%3Ccircle cx='32' cy='44' r='3.5' fill='%23000'/%3E%3C/svg%3E");
  background-size:contain; background-repeat:no-repeat;
  vertical-align:middle;
}

/* ───────────────────────────────────────────────────────────────────────────
   PHASE B — animations (LUXURY-THEMES.txt Part I §3, §5.1, §7.2). The
   scanline/VHS/glitch/chroma/typewriter/interrupt keyframes, the as-fx
   overlay layer (markup in index.html), the freeze rule, and the deadpan
   bumper card. The consolidated §5.9 reduced-motion group closes the block
   at the END, so every kill outranks its animation in the cascade.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── §5.1 the as-fx layer — one fixed FX overlay. display:none off-theme
   (unprefixed, following the .as-fx precedent), z 1300: above the gate (1200)
   and the overlays (80–110), below the offline bar (2000) and the theme flash
   (9999). pointer-events:none + aria-hidden: decoration only. ── */
.as-fx{position:fixed; inset:0; z-index:1300; pointer-events:none; display:none; overflow:hidden;
  contain:strict;}                                     /* PERF: hard containment — nothing inside can invalidate layout or paint outside this box */
html[data-theme="adultswim"] .as-fx{display:block;}
/* PERF (both children): each is its own compositor layer, promoted explicitly
   and permanently. There are exactly two of them and they animate continuously,
   so this is the case will-change was designed for — unlike the .pcard grid,
   the layer count is fixed at 2 no matter how big the page gets. */
.as-fx .scanline{position:absolute; left:0; right:0; top:0; height:2px;
  background:linear-gradient(180deg, transparent, rgba(255,255,255,.16) 45%, rgba(255,255,255,.28) 50%, rgba(255,255,255,.16) 55%, transparent);
  will-change:transform,opacity; backface-visibility:hidden;
  animation:as-scan 9s linear infinite;}
/* PERF: the band was one `repeating-linear-gradient` stretched over the full
   16vh × 100vw box, which Chrome rasters as a single region that size. Same
   gradient declared as a 6px tile + `background-repeat` rasters ONE 6px strip
   and tiles it — a ~1/200th reduction in raster area on a 1080p viewport, and
   it stops re-rastering the whole band on every window resize. */
.as-fx .vhs{position:absolute; left:0; right:0; bottom:0; height:16%;
  background-image:repeating-linear-gradient(0deg, rgba(255,0,0,.06) 0 2px, rgba(0,255,255,.06) 2px 4px, rgba(255,255,255,.03) 4px 6px);
  background-size:100% 6px; background-repeat:repeat;
  will-change:transform,opacity; backface-visibility:hidden;
  animation:as-vhs 26s linear infinite;}
/* §3.8 as-freeze — the broadcast holds when nobody is watching (the
   visibilitychange listener in app.js toggles .frozen) */
.as-fx.frozen .scanline,.as-fx.frozen .vhs{animation-play-state:paused;}
/* PERF — the freeze now covers every AS loop, not just the two inside .as-fx.
   app.js mirrors the visibilitychange onto <html class="as-frozen">, so a
   backgrounded tab stops the REC ring, the bumper caret and the player's VHS
   band as well. Chromium throttles rAF on hidden tabs but does NOT reliably
   stop compositor-driven CSS animations, which is exactly what these are now
   that C6 moved them off the paint path — so the pause has to be explicit. */
html.as-frozen[data-theme="adultswim"] .slice .hero-eyebrow::after,
html.as-frozen[data-theme="adultswim"] .as-bumper .rec i::after,
html.as-frozen[data-theme="adultswim"] .as-bumper .txt::after,
html.as-frozen[data-theme="adultswim"] .pv-stage::after{animation-play-state:paused;}

/* ── §3.1 as-scan — scanline interference. Compositor-only: transform +
   opacity on one tiny fixed layer, 9s period. ── */
@keyframes as-scan{
  0%  {transform:translateY(-3px); opacity:0;}
  2%  {opacity:1;}
  46% {transform:translateY(46vh);}
  48% {transform:translateY(47vh);}   /* the stutter */
  79% {transform:translateY(calc(100vh + 3px));}
  80% {opacity:0;}                    /* hard cut — no fade-out */
  100%{transform:translateY(calc(100vh + 3px)); opacity:0;}
}

/* ── §3.4 as-vhs — VHS tracking band. Compositor-only, 26s period. ── */
@keyframes as-vhs{
  0%,95.5%{opacity:0; transform:translateY(24%);}
  96%   {opacity:1; transform:translateY(0);}
  98%   {opacity:.65;}
  99%,100%{opacity:0; transform:translateY(24%);}
}
/* §5.8 the player's own band — the one place hard white chrome is right */
html[data-theme="adultswim"] .pv-stage::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:14%;
  pointer-events:none; opacity:0; z-index:3;
  background:repeating-linear-gradient(0deg, rgba(255,0,0,.07) 0 2px,
    rgba(0,255,255,.07) 2px 4px, rgba(255,255,255,.04) 4px 6px);
  animation:as-vhs 26s linear infinite;
}

/* ── §3.3 as-glitch — one-shot poster-art displacement on hover.
   PAINT-triggering (clip-path) but bounded: 0.4s per hover, small region,
   and the poster's contain:paint limits the damage. Never infinite. ── */
@keyframes as-glitch{
  0%,60%,100%{transform:translate(0,0); clip-path:inset(0);}
  10%{transform:translate(-6px,0); clip-path:inset(6% 0 66% 0);}
  22%{transform:translate(5px,0); clip-path:inset(52% 0 10% 0);}
  34%{transform:translate(-3px,0); clip-path:inset(0 0 40% 0);}
  46%{transform:translate(4px,0); clip-path:inset(28% 0 30% 0);}
}
@media(hover:hover){
  html[data-theme="adultswim"] .pcard:hover .poster img{
    /* PERF — hover intent. Unchanged visually on a deliberate hover; the 80ms
       delay is below the threshold where a pause reads as latency. What it
       kills is the cascade: sweeping a pointer across a 20-card rail used to
       fire twenty overlapping 0.4s clip-path animations, each one a fresh
       raster of a decoded poster image, and THAT is what made the theme feel
       like it was dropping frames. Now a scrub fires none of them — the
       animation is cancelled before it starts — and only the card you settle
       on glitches. Promotion is scoped to the one animating image. */
    animation:as-glitch .4s steps(1,end) 80ms both;
    will-change:transform, clip-path;
  }
}

/* ── §3.5 as-chroma — chromatic aberration on display text hover. Used
   sparingly: the wordmark and hero titles, plus the primary buttons. ── */
@keyframes as-chroma{
  0%,88%,100%{text-shadow:0 0 0 transparent;}
  90%{text-shadow:3px 0 0 rgba(255,0,0,.8), -3px 0 0 rgba(0,255,255,.8);}
  94%{text-shadow:-2px 0 0 rgba(255,0,0,.7), 2px 0 0 rgba(0,255,255,.7);}
  97%{text-shadow:1px 0 0 rgba(255,0,0,.6), -1px 0 0 rgba(0,255,255,.6);}
}
@media(hover:hover){
  /* the header wordmark IS the .h1home element in index.html's markup, so the
     spec's descendant form would match nothing — target the element itself.
     PERF: text-shadow is a paint-only property, so every keyframe is a full
     re-raster of the glyph run. steps(1,end) already caps that at 4 rasters
     rather than ~30, and the same 80ms hover-intent delay as the poster
     glitch stops a pointer crossing the hero from firing it at all. */
  html[data-theme="adultswim"] .h1home:hover,
  html[data-theme="adultswim"] .slice:hover h2{animation:as-chroma .5s steps(1,end) 80ms both;}
  /* §5.6 warning-sign buttons get the same separation on hover */
  html[data-theme="adultswim"] .btn--accent:hover,
  html[data-theme="adultswim"] .hero-play:hover{animation:as-chroma .5s steps(1,end) 80ms both;}
}

/* ── §3.2 as-censor / as-censor-pop — the censor-block entrance. as-censor
   drives the bumper card; as-censor-pop is the §3.2 text-pop recipe, reserved
   (the bumper text uses as-type instead). ── */
@keyframes as-censor{from{transform:translateX(-101%)}to{transform:translateX(0)}}
@keyframes as-censor-pop{from{opacity:0}to{opacity:1}}   /* 0.01s duration = cut */

/* ── §3.6 as-type — the typewriter. JS writes the text and sets --chars to
   its length; CSS animates width 0→100% in exactly --chars hard steps. ── */
@keyframes as-type{to{width:100%;}}
@keyframes as-type-caret{0%,100%{opacity:1}50%{opacity:0}}

/* ── §7.2 the bumper card — deadpan "everything is fine". z 1250: above the
   gate (1200), below as-fx (1300) and the offline bar (2000). pointer-events
   :none + aria-hidden: it never blocks the gate form or traps focus. The JS
   skips it entirely under reduced motion — a hard cut with no animation is
   the RM-equivalent, and skipping is the safest read of "don't animate". ── */
.as-bumper{
  position:fixed; inset:0; z-index:1250; display:flex;
  align-items:center; justify-content:center;
  background:rgba(0,0,0,.9); pointer-events:none;
  opacity:0; visibility:hidden;
}
html[data-theme="adultswim"] .as-bumper{display:flex;}
/* .on is theme-scoped (not the spec's bare form) so a mid-show switch away
   from adultswim hard-cuts the card instead of lingering on its timer over
   the incoming theme — "the other themes never see the bumper" */
html[data-theme="adultswim"] .as-bumper.on{opacity:1; visibility:visible; transition:none;}  /* hard cut in */
.as-bumper .card{
  background:#000; border:1px solid var(--border-strong);
  box-shadow:0 0 0 1px rgba(0,0,0,.8);
  padding:clamp(28px,6vw,56px) clamp(32px,8vw,88px);
  text-align:center; position:relative;
  animation:as-censor .5s steps(4,end) both;                     /* 4 hard steps in */
  max-width:min(88vw, 720px);
}
.as-bumper .card::before{          /* hazard top edge (§4.2 stripe) */
  content:""; position:absolute; top:-2px; left:0; right:0; height:2px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Cdefs%3E%3Cpattern id='h' width='12' height='12' patternUnits='userSpaceOnUse' patternTransform='rotate(45)'%3E%3Crect width='12' height='12' fill='%23000'/%3E%3Crect width='6' height='12' fill='%23ffcc00'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='12' height='12' fill='url(%23h)'/%3E%3C/svg%3E");
}
.as-bumper .rec{
  display:flex; align-items:center; justify-content:center; gap:8px;
  font-family:var(--font-serif); text-transform:uppercase;
  letter-spacing:.3em; font-size:var(--text-2xs); color:var(--text-muted);
  margin-bottom:14px;
}
.as-bumper .rec i{
  width:8px; height:8px; border-radius:50%; background:var(--status-danger);
  animation:live-dot 1.6s ease-in-out infinite;
}
.as-bumper .txt{
  display:inline-block; overflow:hidden; white-space:nowrap;
  font-family:var(--font-serif); font-weight:400;
  text-transform:uppercase; letter-spacing:.12em;
  font-size:clamp(18px,4.2vw,34px); line-height:1.25; color:var(--text-primary);
  width:0; animation:as-type 1.4s steps(var(--chars,24)) .7s forwards;
  text-shadow:0 2px 0 rgba(0,0,0,.9);
}
.as-bumper .txt::after{content:"▌"; animation:as-type-caret .8s steps(2) infinite;}
@media(max-width:640px){ .as-bumper .txt{white-space:normal; animation:none; width:auto;} }

/* ── §3.7 as-interrupt — the theme switch becomes signal loss: 3 frames of
   SMPTE colour bars, then black. Rides the existing html.theming::after
   theme-flash hook (app.css:1848-1854), re-skilled under AS. ── */
html[data-theme="adultswim"].theming::after{
  background:repeating-linear-gradient(90deg,
    #ffffff 0 12.5%, #ffcc00 12.5% 25%, #33ccff 25% 37.5%,
    #4de8a0 37.5% 50%, #f4716f 50% 62.5%, #ff6600 62.5% 75%,
    #5bc8e8 75% 87.5%, #e6e6e6 87.5% 100%);
  animation:as-interrupt .32s steps(1,end) both;
}
@keyframes as-interrupt{
  0%{opacity:1;}
  33%{opacity:.3;}
  66%{opacity:.75;}
  100%{opacity:0;}
}

/* ───────────────────────────────────────────────────────────────────────────
   PHASE C — performance + depth pass.

   PART 1 (C1–C6) is performance. The finding that matters most is C1: a large
   share of what read as "lag" in this theme was not dropped frames at all, it
   was `--ease-standard:steps(2)` applied to base transitions that run for
   400–500ms. A half-second transition rendered in two discrete jumps is,
   frame for frame, exactly what a page looks like when it stalls. The theme
   was simulating jank. The rest (C2–C6) is real cost: paint-only animations,
   redundant backdrop passes and a full-page cross-fade.

   PART 2 (C7–C11) is depth — type craft, micro-interaction, surface texture
   and the signature bumper moments, all built on the compositor path so the
   polish does not re-introduce the cost Part 1 just removed.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── C1 — the snap. Hard cuts are the AS voice and they stay hard cuts; what
   changes is the WINDOW they happen in. steps(2) over 500ms = two frames
   250ms apart, which the eye reads as a stall. steps(2) over 140ms = a crisp
   two-frame snap, which the eye reads as broadcast switching gear. Same
   easing token, same number of steps, same aesthetic — a quarter of the
   duration. This single block is the biggest perceived-responsiveness win in
   the pass, and it costs nothing to render. ── */
html[data-theme="adultswim"] .pcard{
  transition-duration:.14s, .14s, .14s, .14s;   /* transform, box-shadow, border-color, opacity */
}
html[data-theme="adultswim"] .poster .syn,
html[data-theme="adultswim"] .poster::after,
html[data-theme="adultswim"] .railnav,
html[data-theme="adultswim"] .navlink,
html[data-theme="adultswim"] .iconbtn,
html[data-theme="adultswim"] .libtab,
html[data-theme="adultswim"] .search,
html[data-theme="adultswim"] .btn,
html[data-theme="adultswim"] .lbtn,
html[data-theme="adultswim"] .npc,
html[data-theme="adultswim"] .slice .go{ transition-duration:.14s; }
/* the censor chip keeps three steps — it is a signature move, not a state
   change, and it needs the extra travel to read as a mechanical shutter */
@media(hover:hover){
  html[data-theme="adultswim"] .poster .syn-in{ transition:transform .2s steps(3); }
}

/* ── C2 — the glint becomes a wipe. The base .pcard::after glint animates
   `background-position`, which is paint-only: every frame re-rasters a
   card-sized gradient, and it fires on every hover. Replaced with the same
   band of light moved by `translate3d` on a pre-rastered layer — compositor
   only, zero repaint. It also reads better here: a hard diagonal wipe is the
   bumper transition AS actually uses, where a slow sheen is a luxe gesture
   borrowed from the other themes. ── */
html[data-theme="adultswim"] .pcard::after{
  background:linear-gradient(105deg, transparent 40%, rgba(255,255,255,.16) 50%, transparent 60%);
  background-size:60% 100%; background-repeat:no-repeat; background-position:0 0;
  transform:translate3d(-170%,0,0);
  animation:none;
}
@media(hover:hover){
  html[data-theme="adultswim"] .pcard:hover::after{
    opacity:1; animation:as-wipe .34s steps(4,end) 80ms both;
  }
}
@keyframes as-wipe{
  from{transform:translate3d(-170%,0,0);}
  to  {transform:translate3d(280%,0,0);}
}

/* ── C3 — no-signal slate. The base poster placeholder runs a
   `background-position` shimmer five times per poster while art loads; on a
   catalog page that is dozens of concurrent paint-only animations firing
   exactly when the main thread is already busy decoding images. AS gets a
   static slate instead — flat black with a hazard hairline, the "no signal"
   card. Rastered once, animated never. ── */
html[data-theme="adultswim"] .poster::before{
  animation:none;
  background:
    linear-gradient(180deg, rgba(255,255,255,.05) 0 1px, transparent 1px) 0 0/100% 4px repeat,
    #0a0a0a;
}

/* ── C4 — the last live backdrop-filter. .railnav hardcodes
   `blur(16px) saturate(150%)` rather than reading --card-blur, so the token
   kill in tokens.css never reached it: two blurred regions per rail, each
   re-sampling its backdrop on every scroll frame, over posters that are fully
   opaque anyway. Flat black slab, consistent with the topbar. ── */
html[data-theme="adultswim"] .railnav{
  backdrop-filter:none; -webkit-backdrop-filter:none;
  background:#000; border:1px solid var(--border-strong);
  border-radius:var(--radius-sm);
  box-shadow:0 0 0 1px rgba(0,0,0,.9);
}
html[data-theme="adultswim"] .railnav:hover{
  background:var(--aurora-green); color:#000; border-color:#000;
}

/* ── C5 — the theme switch is a cut, not a fade. The global html.theming rule
   puts a 420ms transition on background/color/border/box-shadow/text-shadow
   for EVERY element and pseudo on the page — a universal-selector repaint
   storm, and the single most expensive moment in the app. Under AS it is also
   wrong: §3.7 already renders the switch as three frames of colour bars and
   then black. Cutting the cross-fade removes the storm AND sharpens the
   effect. ── */
html[data-theme="adultswim"].theming *,
html[data-theme="adultswim"].theming *::before,
html[data-theme="adultswim"].theming *::after{
  transition:none !important;
}

/* ── C6 — compositor-only REC pulse. `live-dot` animates box-shadow spread,
   which cannot be composited: an infinite paint-only animation on an element
   that is visible the entire time the homepage is open, repainting forever
   even on a completely idle tab. Rebuilt as a ring on ::after that scales and
   fades — visually the same expanding pulse, on the GPU, at zero main-thread
   cost. The dot itself is now inert. ── */
html[data-theme="adultswim"] .slice .hero-eyebrow{ position:relative; }
html[data-theme="adultswim"] .slice .hero-eyebrow::before{
  animation:none;                                   /* the dot stops pulsing… */
}
html[data-theme="adultswim"] .slice .hero-eyebrow::after{
  content:""; position:absolute; left:11px; top:50%;
  width:12px; height:12px; margin-top:-6px; border-radius:50%;
  box-shadow:0 0 0 1.5px var(--status-danger);
  pointer-events:none;
  will-change:transform,opacity; backface-visibility:hidden;
  animation:as-rec-ring 2s ease-out infinite;       /* …the ring pulses instead */
}
@keyframes as-rec-ring{
  0%  {transform:scale(1);   opacity:.9;}
  70% {transform:scale(2.1); opacity:0;}
  100%{transform:scale(2.1); opacity:0;}
}
/* same treatment inside the bumper card */
html[data-theme="adultswim"] .as-bumper .rec i{
  position:relative; animation:none;
}
html[data-theme="adultswim"] .as-bumper .rec i::after{
  content:""; position:absolute; inset:0; border-radius:50%;
  box-shadow:0 0 0 1.5px var(--status-danger);
  will-change:transform,opacity; backface-visibility:hidden;
  animation:as-rec-ring 1.6s ease-out infinite;
}

/* ═══ PART 2 — DEPTH ═══════════════════════════════════════════════════════ */

/* ── C7 — type craft. Impact-class faces are wide, tightly-fitted and have a
   very short x-height relative to their cap height, so the tracking scale
   that works for Inter reads as mush here. Three corrections:
   (a) tracking now scales INVERSELY with size — big display type gets less
       tracking, micro-labels get more, which is how broadcast type is
       actually set. A flat .06em everywhere was over-tracking the headlines
       and under-tracking the labels.
   (b) `font-synthesis:none` — the Impact stack has no real bold, so any
       fw-semibold/bold rule was triggering a synthesised smear.
   (c) optical alignment: uppercase Impact has no descenders and a flat
       baseline, so the default line-height leaves a visible gap under every
       heading. Tightened, with the space returned as real margin. ── */
html[data-theme="adultswim"] .hero-title,
html[data-theme="adultswim"] .gh-tagline h1,
html[data-theme="adultswim"] .libtitle{
  letter-spacing:.015em; line-height:.95; font-synthesis:none;
  text-wrap:balance;
}
html[data-theme="adultswim"] .slice h2,
html[data-theme="adultswim"] .together-title,
html[data-theme="adultswim"] .instrument-title{
  letter-spacing:.03em; line-height:1.02; font-synthesis:none;
}
html[data-theme="adultswim"] .railhead .cap{
  letter-spacing:.09em; line-height:1.1; font-synthesis:none;
}
/* micro-labels get MORE air, not less — this is the legibility floor */
html[data-theme="adultswim"] .eyebrow,
html[data-theme="adultswim"] .cap,
html[data-theme="adultswim"] .gate-sub{ letter-spacing:.2em; }
/* the rail head gains a hard rule to its right — structure without ornament,
   the way a broadcast lower-third is set. Pure border, no paint cost. */
html[data-theme="adultswim"] .railhead{ position:relative; }
html[data-theme="adultswim"] .railhead .cap::after{
  content:""; display:inline-block; vertical-align:.28em;
  width:clamp(24px,6vw,84px); height:2px; margin-left:.7em;
  background:var(--border-strong);
}

/* the base rule is a scroll-driven underline (`animation-timeline:view()`,
   absolutely positioned `left:0;right:0`), so it is already the lower-third
   gesture — it just wears the gilt gradient of the luxe themes. Re-skinned
   rather than replaced: a hard 2px rule with a safety-orange lead segment,
   still wiped in by the existing scroll animation, no extra cost.
   NB: do NOT set `width` here. With `left:0;right:0` already declared the box
   is over-constrained, and a width wins — which is what collapsed this to a
   stubby 84px dash under the label on the first pass. */
html[data-theme="adultswim"] .railhead .cap::after{
  bottom:-8px; height:2px;
  background:linear-gradient(90deg, var(--aurora-green) 0 22%, var(--border-strong) 22%);
}

/* ── C8 — focus and press. The base focus ring is the accent colour, which in
   this theme is safety orange on black — a hazard read, not a "you are here"
   read. Broadcast convention (and the better contrast pairing) is the yellow.
   The press state gets the stamp collapse the buttons already use, extended
   to every interactive surface so the whole UI feels like physical gear. ── */
html[data-theme="adultswim"] :focus-visible{
  outline:2px solid var(--aurora-amber); outline-offset:2px;
  border-radius:0;
}
html[data-theme="adultswim"] .navlink:active,
html[data-theme="adultswim"] .libtab:active,
html[data-theme="adultswim"] .iconbtn:active,
html[data-theme="adultswim"] .railnav:active,
html[data-theme="adultswim"] .pv-btn:active{
  transform:translateY(1px) scale(1);   /* stamp down, never shrink — gear does not squish */
}
/* nav links get a hard underscore that snaps in rather than growing */
html[data-theme="adultswim"] .navlink{ position:relative; }
html[data-theme="adultswim"] .navlink::before{
  content:""; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:var(--aurora-green); transform:scaleX(0); transform-origin:left;
  transition:transform .12s steps(2);
}
html[data-theme="adultswim"] .navlink:hover::before,
html[data-theme="adultswim"] .navlink[aria-current]::before{ transform:scaleX(1); }

/* ── C9 — surface texture. This theme deliberately has no grain (C-part-1
   removed the blend layer entirely), which left the surfaces reading as
   undifferentiated flat black — the "needs depth" complaint. The answer is
   not to put the blend layer back; it is a 4px CRT line pattern declared as a
   TILE, so the browser rasters one 4px strip per surface and repeats it.
   Static, no animation, no blend mode, effectively free — and it gives every
   panel the faint horizontal structure of a monitor rather than a void. ── */
html[data-theme="adultswim"] .pcard,
html[data-theme="adultswim"] .npc,
html[data-theme="adultswim"] #topbar,
html[data-theme="adultswim"] .gate-card,
html[data-theme="adultswim"] .requestbox,
html[data-theme="adultswim"] .board,
html[data-theme="adultswim"] .as-bumper .card{
  background-image:linear-gradient(180deg, rgba(255,255,255,.028) 0 1px, transparent 1px 4px);
  background-size:100% 4px; background-repeat:repeat; background-attachment:local;
}
/* a hard top highlight + bottom shade on every raised surface: one inset
   box-shadow, no blur radius, so it costs a single hairline of paint and
   gives the flat slabs a real edge. This is the "physical equipment" read. */
html[data-theme="adultswim"] .pcard,
html[data-theme="adultswim"] .npc,
html[data-theme="adultswim"] #topbar,
html[data-theme="adultswim"] .requestbox,
html[data-theme="adultswim"] .board{
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    inset 0 -1px 0 rgba(0,0,0,.9),
    0 2px 0 rgba(0,0,0,.85);
}
@media(hover:hover){
  html[data-theme="adultswim"] .pcard:hover{
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.16),
      inset 0 -1px 0 rgba(0,0,0,.9),
      0 0 0 1px var(--aurora-green),
      0 4px 0 rgba(0,0,0,.9);
  }
}

/* ── C10 — the hazard rule. One 2px hazard-stripe tile, reused as a top edge
   on the sections that carry weight. The stripe is a 12px SVG tile (§4.2),
   already inlined for the bumper card — declaring it once as a custom
   property means the browser decodes and rasters ONE tile for every use
   instead of one per rule. ── */
html[data-theme="adultswim"]{
  --as-hazard:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Cdefs%3E%3Cpattern id='h' width='12' height='12' patternUnits='userSpaceOnUse' patternTransform='rotate(45)'%3E%3Crect width='12' height='12' fill='%23000'/%3E%3Crect width='6' height='12' fill='%23ffcc00'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='12' height='12' fill='url(%23h)'/%3E%3C/svg%3E");
}
html[data-theme="adultswim"] .requestbox::before,
html[data-theme="adultswim"] .ledger::before{
  content:""; position:absolute; top:0; left:0; right:0; height:2px;
  background-image:var(--as-hazard); opacity:.85; pointer-events:none;
}
html[data-theme="adultswim"] .requestbox,
html[data-theme="adultswim"] .ledger{ position:relative; }

/* ── C11 — signature moments. The bumper card is the theme's one piece of
   theatre; it was doing the work with a typewriter line alone. Three cheap
   additions that make it read as a real broadcast card:
   (a) a black letterbox bar top and bottom, hard-cut in on a transform —
       the 4:3-in-16:9 framing every AS bumper has;
   (b) the card sits fractionally off-centre and off-square, because the
       joke of an AS bumper is that it is deadpan, not designed;
   (c) the caret stops blinking on `opacity` alone (paint) and blinks on a
       compositor-friendly `transform:scaleY()` collapse instead. ── */
.as-bumper::before,
.as-bumper::after{
  content:""; position:absolute; left:0; right:0; height:9vh;
  background:#000; pointer-events:none;
}
.as-bumper::before{ top:0;    transform:translateY(-100%); }
.as-bumper::after { bottom:0; transform:translateY(100%); }
html[data-theme="adultswim"] .as-bumper.on::before,
html[data-theme="adultswim"] .as-bumper.on::after{
  animation:as-letterbox .26s steps(2,end) both;
}
@keyframes as-letterbox{ to{ transform:translateY(0); } }
/* the tilt has to live INSIDE the keyframes, not as a static transform: the
   card already runs `as-censor` with fill-mode `both`, and an animation that
   targets `transform` owns that property outright for its whole duration and
   after it — a separate `transform:rotate()` declaration is simply discarded.
   (Verified in-browser: the static rule computed to the animation's matrix
   with no rotation component.) So AS re-points the card at a tilt-carrying
   variant of the same 4-step wipe. */
html[data-theme="adultswim"] .as-bumper .card{
  animation:as-censor-tilt .5s steps(4,end) both;
  margin-top:-2vh;                    /* sitting a hair above optical centre */
}
@keyframes as-censor-tilt{
  from{transform:translateX(-101%) rotate(-.35deg);}
  to  {transform:translateX(0)     rotate(-.35deg);}   /* deadpan: nearly, but not, square */
}
html[data-theme="adultswim"] .as-bumper .txt::after{
  transform-origin:center bottom;
  animation:as-caret-blink .8s steps(2) infinite;
}
@keyframes as-caret-blink{ 0%,49%{transform:scaleY(1)} 50%,100%{transform:scaleY(0)} }
/* the bumper's own hazard edge now reuses the shared tile */
html[data-theme="adultswim"] .as-bumper .card::before{
  background-image:var(--as-hazard);
}

/* ───────────────────────────────────────────────────────────────────────────
   PHASE D — visual pass.

   Everything here came out of looking at the rendered page rather than the
   stylesheet. Phases 1/A/B/C styled the surfaces the theme spec named; D
   fixes what that left behind — components the spec never listed, which
   quietly kept the *default* treatment and so read as another theme leaking
   through. Three findings drove it:

   D-i   The theme is uppercase everywhere it was told to be and sentence case
         everywhere it wasn't. Card titles, now-playing rows and footer links
         all still read in the default voice, directly beside headings that
         shout. That inconsistency is more visible than any single effect.
   D-ii  Nine components are still round in a theme whose radius tokens are
         all 0–2px. A pill badge next to a square card is the one thing the
         eye catches immediately.
   D-iii The texture added in C9 sits *behind* the poster art, which is
         opaque — so the "depth" layer was invisible exactly where the eye
         actually goes. It has to be over the art, not under it.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── D1 — voice. Uppercase in a broadcast lower-third is the register the
   whole theme is written in; leaving content titles in sentence case made
   every rail read half-committed. Tracking opens slightly to compensate —
   uppercase without added tracking sets tight and turns into a block. These
   are the sans stack, not the Impact stack: uppercase Helvetica-class type at
   small sizes is exactly the AS caption voice, and stays legible where
   condensed display caps would not. ── */
html[data-theme="adultswim"] .pt,
html[data-theme="adultswim"] .cw-t,
html[data-theme="adultswim"] .npc .ttl{
  text-transform:uppercase; letter-spacing:.05em; line-height:1.25;
}
html[data-theme="adultswim"] .py,
html[data-theme="adultswim"] .cw-meta,
html[data-theme="adultswim"] .npc .meta,
html[data-theme="adultswim"] .syn-g{
  text-transform:uppercase; letter-spacing:.12em;
}
/* Continue Watching is a separate card component (.cwcard, not .pcard), which
   is exactly why it kept the default voice through the first pass — the caps
   list was written from the theme spec's element names, and this one was
   built after it. Its progress bar is the same broadcast treatment as D6. */
html[data-theme="adultswim"] .cw-bar{ border-radius:0; }
html[data-theme="adultswim"] .cw-bar i{ background:var(--aurora-green); box-shadow:none; }
html[data-theme="adultswim"] .cw-play{ border-radius:var(--radius-sm); }
html[data-theme="adultswim"] .syn-more{ letter-spacing:.1em; }
html[data-theme="adultswim"] footer .foot-col a{
  text-transform:uppercase; letter-spacing:.1em; font-size:var(--text-2xs);
}
/* the footer wordmark line stays sentence case on purpose — it is the one
   piece of plain speech in the theme, and the deadpan needs somewhere to sit */

/* ── D2 — squaring off. Every one of these computed to a pill or a circle
   while `--radius-xs … --radius-xl` were 0–2px, so each was a visible defect
   rather than a stylistic choice. The status *dot* stays round: a lamp is a
   lamp, and squaring it would read as a bug rather than as a decision. ── */
html[data-theme="adultswim"] .back-to-top,
html[data-theme="adultswim"] .kbd-help-btn,
html[data-theme="adultswim"] .sheet-close,
html[data-theme="adultswim"] .avatar,
html[data-theme="adultswim"] .themerow button,
html[data-theme="adultswim"] .npc .badge,
html[data-theme="adultswim"] .npc .bar,
html[data-theme="adultswim"] .npc .tag,
html[data-theme="adultswim"] .chip,
html[data-theme="adultswim"] .pstatus{ border-radius:var(--radius-sm); }
/* the two fixed corner buttons also carried a live backdrop-filter each */
html[data-theme="adultswim"] .back-to-top,
html[data-theme="adultswim"] .kbd-help-btn{
  backdrop-filter:none; -webkit-backdrop-filter:none;
  background:#000; border:1px solid var(--border-strong);
  box-shadow:0 2px 0 rgba(0,0,0,.9);
}
html[data-theme="adultswim"] .back-to-top:hover,
html[data-theme="adultswim"] .kbd-help-btn:hover{
  background:var(--aurora-green); color:#000; border-color:#000;
}

/* ── D3 — the request chip becomes warning signage. It sat on the Popular
   rail as a soft amber pill with `backdrop-filter:blur(4px)` — one blurred
   region per card, seven-plus per rail, re-sampling over opaque poster art
   for an effect that could not be seen. Flat orange on black instead, which
   is both the theme's button language and free to paint. ── */
html[data-theme="adultswim"] .pstatus{
  backdrop-filter:none; -webkit-backdrop-filter:none;
  font-family:var(--font-serif); font-weight:400;
  text-transform:uppercase; letter-spacing:.08em;
  border-width:2px;
}
html[data-theme="adultswim"] .pstatus.want{
  background:var(--aurora-green); color:#000; border-color:#000;
}
html[data-theme="adultswim"] .pstatus.req{
  background:#000; color:var(--aurora-amber); border-color:var(--aurora-amber);
}

/* ── D4 — the CRT layer, moved on top of the art. This is the depth fix.
   C9 put a 4px line pattern on the card *background*, which the opaque
   poster image covers completely — so the texture existed everywhere except
   the 80% of each card the eye is actually looking at.

   `.poster::after` is the right host: it already exists (it carries the hover
   frame), it sits at z3 above both the image and the synopsis, and it is
   `pointer-events:none`. Declared as a 3px tile so the browser rasters one
   strip and repeats it — the same trick as the VHS band in C-part-1, and the
   reason this costs essentially nothing despite covering every poster on the
   page. The vignette is a second, static gradient in the same layer: it puts
   a soft dark edge on the art so the cards stop reading as flat colour
   rectangles against flat black. ── */
html[data-theme="adultswim"] .poster::after{
  background-image:
    linear-gradient(180deg, rgba(0,0,0,.32) 0 1px, transparent 1px 3px),
    radial-gradient(120% 100% at 50% 45%, transparent 52%, rgba(0,0,0,.55) 100%);
  background-size:100% 3px, 100% 100%;
  background-repeat:repeat, no-repeat;
}
/* the hero carries the same treatment at a larger line pitch — a big panel
   with a fine pitch reads as moiré, not as a screen. `.slice::before` is the
   luxe themes' aurora colour-wash, which AS has no use for; repurposing it
   costs one fewer layer than adding a new pseudo. */
html[data-theme="adultswim"] .slice::before{
  background:
    linear-gradient(180deg, rgba(0,0,0,.30) 0 1px, transparent 1px 4px),
    radial-gradient(115% 95% at 50% 40%, transparent 46%, rgba(0,0,0,.5) 100%);
  background-size:100% 4px, 100% 100%;
  background-repeat:repeat, no-repeat;
  mix-blend-mode:normal;
}

/* ── D5 — the hero signs off with colour bars. The gate already ends its hero
   on an SMPTE strip (§4.1); the homepage hero, which is the larger surface
   and the one members actually see, ended on nothing. Same tile, same 8px
   height — the two heroes now rhyme, and the strip gives the tallest element
   on the page a hard bottom edge instead of fading into the black. ── */
html[data-theme="adultswim"] .hero{ position:relative; }
/* sized and anchored, NOT tiled. First attempt used the gate's
   `background-size:auto 100%; repeat-x`, which on a 1440px-wide hero repeated
   the 7-bar set ~20 times and rendered as rainbow confetti — the gate gets
   away with it only because its hero is narrow. One bar set, 320px, pinned
   right, reads as a deliberate test signal instead of wallpaper. */
html[data-theme="adultswim"] .hero::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:6px;
  z-index:6; pointer-events:none; opacity:.9;
  background-position:right bottom; background-size:320px 100%;
  background-repeat:no-repeat;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='36'%3E%3Crect x='0' width='60' height='36' fill='%23fff'/%3E%3Crect x='60' width='60' height='36' fill='%23ffcc00'/%3E%3Crect x='120' width='60' height='36' fill='%2333ccff'/%3E%3Crect x='180' width='60' height='36' fill='%234de8a0'/%3E%3Crect x='240' width='60' height='36' fill='%23d43d3d'/%3E%3Crect x='300' width='60' height='36' fill='%23ff6600'/%3E%3Crect x='360' width='60' height='36' fill='%23111'/%3E%3C/svg%3E");
}

/* ── D5b — uppercase costs width, and width costs a straight baseline. Setting
   card titles in caps (D1) pushed the longer ones onto a second line, which
   dropped that card's year/kind row below its neighbours' and left every rail
   with a ragged meta line. Reserving two lines on the title makes the meta row
   align across the rail whether a title wraps or not — the alignment is the
   point, not the height. ── */
html[data-theme="adultswim"] .pt{
  min-height:calc(2 * 1.25em);
}

/* ── D6 — the now-playing bar reads as broadcast gear. It was a 4px rounded
   track with a gradient fill, a colour glow and an infinite highlight sweep
   (`barflow`) — three luxe gestures at once, and the sweep is a permanent
   animation on a permanently-visible element. Hard orange fill, square ends,
   no glow, no sweep. ── */
html[data-theme="adultswim"] .npc .bar{
  height:3px; background:rgba(255,255,255,.12);
}
html[data-theme="adultswim"] .npc .bar i{
  background:var(--aurora-green); box-shadow:none;
}
html[data-theme="adultswim"] .npc .bar i::after{ display:none; }   /* kills barflow outright */
/* status line becomes a labelled state, not prose */
html[data-theme="adultswim"] .npc .badge{
  border-width:2px; font-family:var(--font-serif); font-weight:400;
}

/* ── D7 — the flourish. Three unequal dashes (a 64px bar between two gilt
   gradient hairlines) read as a rendering accident rather than a mark. One
   hazard-stripe bar, centred, flanked by hard rules that actually meet it. ── */
html[data-theme="adultswim"] .flourish i{
  width:96px; height:4px;
  background-image:var(--as-hazard); background-color:transparent;
}
html[data-theme="adultswim"] .flourish::before,
html[data-theme="adultswim"] .flourish::after{
  height:2px; background:var(--border-default);
}

/* ── D8 — the topbar earns its edge. It is the only element pinned over
   scrolling content, and against a dead-black field it had nothing to
   separate it from the page. A hazard hairline along the bottom does the job
   with two pixels and reads as equipment trim. ── */
/* ── D9 — one last leak found by enumerating what was still animating on an
   idle page. `.sheen` runs `sheen` infinitely, and `sheen` animates
   `background-position` — paint-only, forever, on the gate title and the
   catalog heading. AS already flattens gradient-clipped display text to solid
   white everywhere it names one, so the sweep was repainting a gradient that
   the theme had made invisible. Kill the animation and hold the fill. ── */
html[data-theme="adultswim"] .sheen{
  animation:none;
  background:none; -webkit-text-fill-color:var(--text-primary); color:var(--text-primary);
}

html[data-theme="adultswim"] #topbar{ position:relative; }
html[data-theme="adultswim"] #topbar::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px; height:2px;
  background:linear-gradient(90deg, var(--aurora-green) 0 18%, transparent 18%);
  pointer-events:none;
}


/* ───────────────────────────────────────────────────────────────────────────
   PHASE F — reconciliation with the PHASE E base restructure.

   E3 and E13 moved the card surface off `.pcard` / `.cwcard` and onto the
   artwork (`.poster` / `.cw-thumb`), because the outer element now spans the
   caption too. Adult Swim's C9 treatment — the CRT line tile and the hard
   edge shadows — was still written against the old outer element, so it drew
   a lit box around every caption and tiled scanlines across empty page. Same
   treatment, correct host.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── F1 — the card surface follows the artwork ── */
html[data-theme="adultswim"] .pcard,
html[data-theme="adultswim"] .cwcard{
  background-image:none; box-shadow:none;
}
html[data-theme="adultswim"] .poster,
html[data-theme="adultswim"] .cw-thumb{
  background-image:linear-gradient(180deg, rgba(255,255,255,.028) 0 1px, transparent 1px 4px);
  background-size:100% 4px; background-repeat:repeat;
  border:1px solid var(--border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    inset 0 -1px 0 rgba(0,0,0,.9),
    0 2px 0 rgba(0,0,0,.85);
}
@media(hover:hover){
  html[data-theme="adultswim"] .pcard:hover .poster,
  html[data-theme="adultswim"] .cwcard:hover .cw-thumb{
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.16),
      inset 0 -1px 0 rgba(0,0,0,.9),
      0 0 0 1px var(--aurora-green),
      0 4px 0 rgba(0,0,0,.9);
    border-color:var(--aurora-green);
  }
}

/* ── F2 — the feature slides get their frame back ─────────────────────────
   E21 took the border off `.slice` in favour of elevation, which is right for
   the soft themes: a shadow reads as depth on a plum-black field. On dead
   black a drop shadow is invisible by definition — the slide simply lost its
   edge. This theme gets the edge back as a hard 1px frame, which is also the
   more on-brand read: a broadcast monitor, not a floating card. ── */
html[data-theme="adultswim"] .slice{
  border:1px solid var(--border-strong);
  box-shadow:0 0 0 1px rgba(0,0,0,.9);
}
@media(hover:hover){
  html[data-theme="adultswim"] .slice:hover{
    border-color:var(--aurora-green);
    box-shadow:0 0 0 1px rgba(0,0,0,.9);
  }
}

/* ── F3 — the rail buttons keep the reveal, lose the round ────────────────
   E4's hover-reveal is a straight improvement and this theme keeps it; only
   the geometry needs correcting, since E4 re-declared width/height/radius. ── */
html[data-theme="adultswim"] .railnav{
  width:38px; height:52px; border-radius:var(--radius-sm);
  background:#000; border:1px solid var(--border-strong);
  box-shadow:0 0 0 1px rgba(0,0,0,.9);
}

/* ── F4 — the C1 snap, now expressed in tokens ────────────────────────────
   The last pass had to re-time components by name because no duration scale
   existed. It does now (--dur-*), and --dur-fast is 140ms — exactly the value
   that block was hardcoding. Pointing at the token means a future component
   inherits the snap instead of silently inheriting a half-second stutter,
   which was the one follow-up that pass left open. ── */
html[data-theme="adultswim"] .pcard,
html[data-theme="adultswim"] .cwcard,
html[data-theme="adultswim"] .poster,
html[data-theme="adultswim"] .cw-thumb,
html[data-theme="adultswim"] .slice,
html[data-theme="adultswim"] .npc,
html[data-theme="adultswim"] .railnav,
html[data-theme="adultswim"] .pt,
html[data-theme="adultswim"] .cw-t,
html[data-theme="adultswim"] .pstatus{
  transition-duration:var(--dur-fast);
}

/* ── F5 — the eyebrow, re-fitted ──────────────────────────────────────────
   E2 rebuilt `.hero-eyebrow` as an inline-flex row with a leading rule on
   ::before — but ::before is this theme's REC lamp (C6), so the base rule was
   overridden and the flex gap was left sizing a dot instead of a rule. It
   happens to work, and it works BETTER than either did alone: a censor chip
   with a live lamp inside it. Made deliberate rather than accidental — the
   chip's padding comes back, since a chip with no box is just text. ── */
html[data-theme="adultswim"] .slice .hero-eyebrow{
  padding:5px 12px 5px 10px; gap:8px;
  background:#000; border:1px solid var(--border-strong);
  color:var(--text-primary);
}
html[data-theme="adultswim"] .slice .hero-eyebrow::before{
  width:11px; height:11px; margin-right:0;
}
html[data-theme="adultswim"] .slice .hero-eyebrow::after{ left:10px; }

/* ── F6 — the status dot ──────────────────────────────────────────────────
   E20's Now-Playing state indicator is new base furniture; the semantic
   status colours are already this theme's palette (§ tokens.css note), so it
   needs geometry only — and the dot stays round, for the same reason the REC
   lamp does. ── */
html[data-theme="adultswim"] .npc .meta{ color:var(--text-secondary); }

/* ── §5.9 consolidated reduced-motion group — one place, LAST: the kills must
   outrank every animation rule above (equal specificity, later source wins
   when both media queries match). Includes the §5.6 button-chroma kill the
   spec's group omits — the spec's own contract requires chroma dead under RM. */
@media(prefers-reduced-motion:reduce){
  html[data-theme="adultswim"] .as-fx{display:none;}
  html[data-theme="adultswim"] .pv-stage::after{display:none;}
  html[data-theme="adultswim"] .slice .hero-eyebrow::before{animation:none;}
  html[data-theme="adultswim"] .slice .in::after{transition:none;}
  html[data-theme="adultswim"] .pcard:hover .poster img{animation:none;}
  html[data-theme="adultswim"] .h1home:hover,
  html[data-theme="adultswim"] .slice:hover h2,
  html[data-theme="adultswim"] .btn--accent:hover,
  html[data-theme="adultswim"] .hero-play:hover{animation:none;}
  html[data-theme="adultswim"] .poster .syn-in{transition:none;}
  html[data-theme="adultswim"].theming::after{animation:none; opacity:0;}
  /* ── PHASE C additions ── every animation introduced above is killed here.
     The ring/caret/letterbox pseudos are hidden rather than merely paused,
     because a pulse frozen mid-scale is a visual artefact, not a still. */
  html[data-theme="adultswim"] .slice .hero-eyebrow::after,
  html[data-theme="adultswim"] .as-bumper .rec i::after{animation:none; display:none;}
  html[data-theme="adultswim"] .as-bumper .txt::after{animation:none; transform:none;}
  html[data-theme="adultswim"] .as-bumper.on::before,
  html[data-theme="adultswim"] .as-bumper.on::after{animation:none; transform:translateY(0);}
  html[data-theme="adultswim"] .pcard:hover::after{animation:none; opacity:0;}
  html[data-theme="adultswim"] .navlink::before{transition:none;}
}
