/* =====================================================================
   PARALLOX — stylesheet

   PERFORMANCE CONTRACT (read before editing)
   ---------------------------------------------------------------------
   1. Nothing here animates a property the compositor cannot handle
      (background-position, width/height, box-shadow, filter on the
      element itself). Motion is transform + opacity only.
   2. Expensive effects (backdrop-filter, glows, hover 3D) are *opt-in*
      behind `@media (hover:hover)` and `html[data-fx="full"]`. They are
      never switched off later by a media query — the previous stylesheet
      did that and lost every override to the cascade, leaving 25
      backdrop-filter elements live on phones.
   3. Decorative layers are frozen while their section is off screen
      (`.in-view` is toggled by script.js).
   ===================================================================== */

/* ── FONTS (self-hosted: no external request, no render block) ───── */
@font-face{
  font-family:'Orbitron';
  font-style:normal;
  font-weight:400 900;
  font-display:swap;
  src:url('assets/fonts/orbitron.woff2') format('woff2');
}
@font-face{
  font-family:'Share Tech Mono';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/share-tech-mono.woff2') format('woff2');
}

/* ── TOKENS ───────────────────────────────────────────────────────── */
:root{
  /* palette */
  --void:#05070e;
  --void-deep:#03050b;
  --surface:#0b1018;
  --surface-2:#101724;
  --line:rgba(255,255,255,.09);
  --line-strong:rgba(255,255,255,.16);

  --ink:#f2f5ff;
  --muted:#a6b0c6;   /* 7.4:1 on --void — passes AA at any size */
  --faint:#7b869d;   /* 4.9:1 — AA for large/secondary text only */

  --red:#ff2d55;
  /* Solid fills that carry white text. #ff2d55 only reaches 3.65:1 against
     white, which fails AA for button-sized type; this is the same hue taken
     down just far enough to clear 4.5:1 with margin. */
  --red-solid:#d9103c;
  --red-soft:rgba(255,45,85,.14);
  --cyan:#22e0ff;
  --green:#25f5a8;
  /* Sampled straight out of assets/originals/laymon.png — its dominant warm
     pixel is rgb(240,208,48). The brand word is set to the same value so the
     label and the sprite read as one mark. */
  --lemon:#f0d030;

  /* type */
  --display:'Orbitron','Segoe UI',system-ui,sans-serif;
  --mono:'Share Tech Mono',ui-monospace,'Cascadia Mono',Consolas,monospace;
  --body:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;

  --fs-h2:clamp(1.7rem,5.2vw,3.1rem);
  --fs-h3:clamp(1.05rem,2.4vw,1.35rem);
  --fs-lede:clamp(1rem,2.1vw,1.15rem);
  --fs-body:clamp(.95rem,1.6vw,1.02rem);
  --fs-small:.82rem;
  --fs-label:.7rem;

  /* space + shape */
  --pad-x:clamp(1.25rem,5vw,3.5rem);
  --section-y:clamp(3.5rem,9vw,7rem);
  --shell:1200px;
  --r-sm:8px;
  --r-md:14px;
  --r-lg:22px;
  --r-pill:999px;
  --nav-h:64px;
  /* clearance between the fixed navbar and whatever an anchor scrolled to */
  --anchor-gap:20px;

  --ease:cubic-bezier(.19,1,.22,1);

  color-scheme:dark;
}

/* ── RESET ────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

html{
  -webkit-text-size-adjust:100%;
  background:var(--void);
}
@media (prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}
}

body{
  font-family:var(--body);
  font-size:var(--fs-body);
  line-height:1.65;
  color:var(--muted);
  background:var(--void);
  overflow-x:clip;          /* clip, not hidden — no scroll container side effects */
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  -webkit-tap-highlight-color:transparent;
}

img,svg,video{display:block;max-width:100%}
img{height:auto}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;tap-highlight-color:transparent}
a{color:inherit;text-decoration:none}
ul,ol{list-style:none}
h1,h2,h3,h4{font-family:var(--display);color:var(--ink);font-weight:800;line-height:1.08;letter-spacing:-.01em;text-wrap:balance}
p{text-wrap:pretty}
strong{color:var(--ink);font-weight:700}
kbd{font-family:var(--mono)}

:where(a,button,[tabindex]):focus-visible{
  outline:2px solid var(--red);
  outline-offset:3px;
  border-radius:4px;
}

.sprite{position:absolute;width:0;height:0;overflow:hidden}
svg{width:1.15em;height:1.15em;flex:none}

.skip-link{
  position:fixed;top:8px;left:8px;z-index:400;
  transform:translateY(-160%);
  background:var(--red-solid);color:#fff;
  padding:.7rem 1.1rem;border-radius:var(--r-sm);
  font-family:var(--mono);font-size:var(--fs-small);letter-spacing:.08em;
}
.skip-link:focus{transform:none}

.shell{width:min(var(--shell),100% - var(--pad-x) * 2);margin-inline:auto}

/* Anchor targets stop exactly one navbar-height + gap below the viewport top.
   script.js overrides this with a computed scroll for in-page links so the
   landing position is exact even while content-visibility is resolving. */
section[id],[id]{scroll-margin-top:calc(var(--nav-h) + var(--anchor-gap))}

/* =====================================================================
   NAVBAR
   ===================================================================== */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:100;
  height:var(--nav-h);
  display:flex;align-items:center;gap:clamp(.6rem,1.6vw,1.25rem);
  padding-inline:clamp(.75rem,3vw,1.75rem);
  background:rgba(5,7,14,.82);
  border-bottom:1px solid var(--line);
}
html[data-fx="full"] .nav{backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%)}
html[data-fx="lite"] .nav{background:rgba(5,7,14,.96)}

/* scroll progress: one composited scaleX, written from a passive listener */
.nav__progress{position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--line);overflow:hidden}
.nav__progress i{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,var(--red),#a855f7 55%,var(--cyan));
  transform:scaleX(0);transform-origin:0 50%;
  will-change:transform;
}

.nav__toggle{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  width:44px;height:44px;flex:none;
  border:1px solid rgba(255,45,85,.32);border-radius:var(--r-sm);
  transition:border-color .2s,background-color .2s;
}
.nav__toggle span{display:block;width:20px;height:2px;background:var(--ink);transition:transform .25s var(--ease),opacity .18s}
.nav__toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav__toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.nav__toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* The Laymon Games portfolio link — back where it started: top-left on
   desktop, immediately after the hamburger on mobile. */
.brand{
  display:flex;align-items:center;gap:.55rem;
  margin-right:auto;
  padding:.25rem .7rem .25rem .3rem;
  border:1px solid rgba(255, 255, 255, 0.178);
  border-radius:var(--r-md);
  text-decoration:none;
  transition:transform .3s var(--ease),border-color .25s,box-shadow .3s;
}
.brand img{
  width:38px;height:38px;flex:none;
  image-rendering:pixelated;
  filter:drop-shadow(0 0 7px rgba(168,85,247,.45));
  transition:transform .3s var(--ease);
}
.brand__word{
  font-family:var(--display);font-weight:900;font-size:.74rem;letter-spacing:.14em;
  color:var(--lemon);white-space:nowrap;
}
@media (hover:hover){html[data-fx="full"] .brand:hover{transform:translateY(-2px);border-color:var(--lemon);box-shadow:0 0 20px rgba(240,208,48,.35)}}
@media (hover:none){.brand:active{transform:scale(.98)}}

.nav nav{display:flex;align-items:center;gap:.1rem}
.nav nav a{
  position:relative;
  padding:.6rem .8rem;
  font-family:var(--mono);font-size:.78rem;letter-spacing:.13em;
  color:var(--muted);
  transition:color .2s;
}
.nav nav a::after{
  content:'';position:absolute;left:.8rem;right:.8rem;bottom:.34rem;height:2px;
  background:var(--red);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .3s var(--ease);
}
.nav nav a:hover,.nav nav a:focus-visible{color:var(--ink)}
.nav nav a:hover::after,.nav nav a:focus-visible::after{transform:scaleX(1)}

/* mobile drawer */
@media (max-width:899px){
  .nav{gap:.5rem}
  .nav__toggle{display:flex}
  .brand{margin-right:0}
  .nav nav{
    position:absolute;top:100%;left:0;right:0;
    flex-direction:column;align-items:stretch;gap:0;
    padding:6px clamp(.75rem,3vw,1.75rem) 12px;
    background:rgba(5,7,14,.97);
    border-bottom:1px solid var(--line);
    transform:translateY(-8px);
    opacity:0;visibility:hidden;
    transition:opacity .2s ease,transform .28s var(--ease),visibility 0s linear .24s;
  }
  .nav nav.open{opacity:1;visibility:visible;transform:none;transition:opacity .2s ease,transform .28s var(--ease),visibility 0s}
  .nav nav a{
    padding:13px 10px;margin:0;font-size:.82rem;
    border-bottom:1px solid var(--line);
  }
  .nav nav a::after{display:none}
  .nav nav.open a{animation:navIn .3s var(--ease) both}
  .nav nav.open a:nth-child(1){animation-delay:.03s}
  .nav nav.open a:nth-child(2){animation-delay:.06s}
  .nav nav.open a:nth-child(3){animation-delay:.09s}
  .nav nav.open a:nth-child(4){animation-delay:.12s}
  .nav nav.open a:nth-child(5){animation-delay:.15s}
  .nav nav.open a:nth-child(6){animation-delay:.18s}
  .nav nav a:active{background:var(--red-soft);color:var(--ink)}
}
@keyframes navIn{from{opacity:0;transform:translate3d(0,-8px,0)}to{opacity:1;transform:none}}

@media (min-width:900px){.nav__toggle{display:none}}

/* =====================================================================
   BUTTONS
   ===================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  min-height:48px;padding:.85rem 1.6rem;
  font-family:var(--display);font-weight:700;font-size:.82rem;letter-spacing:.12em;
  border-radius:var(--r-pill);
  border:1px solid transparent;
  transition:transform .3s var(--ease),background-color .25s,border-color .25s,color .25s;
}
.btn svg{width:1.05em;height:1.05em}
.btn--primary{background:var(--red-solid);color:#fff}
.btn--ghost{border-color:rgba(255,45,85,.6);color:var(--red);background:rgba(255,45,85,.05)}
.btn--wide{width:100%}
/* Heart on each side of the word, as it was. */
.btn--donate{gap:.7rem}
.btn--donate svg{width:1rem;height:1rem}

@media (hover:hover) and (pointer:fine){
  html[data-fx="full"] .btn--primary:hover{transform:translateY(-2px);box-shadow:0 10px 30px rgba(255,45,85,.45)}
  html[data-fx="full"] .btn--ghost:hover{transform:translateY(-2px);background:rgba(255,45,85,.12);border-color:var(--red);box-shadow:0 10px 30px rgba(255,45,85,.25)}
}
@media (hover:none){.btn:active{transform:scale(.97)}}

/* =====================================================================
   HERO — the intro clip is the background layer, not a 120vh block
   ===================================================================== */
.hero{
  position:relative;
  min-height:100vh;
  min-height:100svh;
  display:grid;
  align-items:center;
  gap:clamp(1rem,3vw,2rem);
  padding:calc(var(--nav-h) + clamp(2rem,7vh,4rem)) var(--pad-x) clamp(3.5rem,9vh,5.5rem);
  isolation:isolate;
  overflow:clip;
  background:var(--void);
}
@media (min-width:900px){
  .hero{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr)}
}

.hero__bg{position:absolute;inset:0;z-index:-2;background:var(--void)}
.hero__bg video{width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .9s ease}
/* the class is added by script.js once real frames are on screen */
.hero__bg video.ready{opacity:.62}

/* Permanent backdrop: the intended look before, or entirely without, the
   video. Painted once — nothing here animates. */
.hero__bg::before{
  content:'';position:absolute;inset:0;
  background:
    radial-gradient(56% 46% at 68% 32%,rgba(255,45,85,.34),transparent 70%),
    radial-gradient(50% 44% at 20% 78%,rgba(34,224,255,.20),transparent 72%),
    radial-gradient(95% 75% at 50% 46%,#0b1223,#05070e 76%);
}
/* Legibility layer over whatever is behind it. */
.hero__scrim{
  position:absolute;inset:0;
  background:
    linear-gradient(to top,rgba(5,7,14,.94) 0%,rgba(5,7,14,.62) 38%,rgba(5,7,14,.34) 100%),
    radial-gradient(75% 65% at 32% 52%,rgba(5,7,14,.6),transparent 70%);
}
/* faint technical grid, masked so it dissolves at the edges */
.hero__grid{
  position:absolute;inset:0;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(75% 60% at 50% 45%,#000,transparent 78%);
  mask-image:radial-gradient(75% 60% at 50% 45%,#000,transparent 78%);
}

.hero__inner{
  position:relative;z-index:2;
  width:100%;max-width:640px;margin-inline:0;
  /* lets the display type scale to its column instead of to the viewport —
     "PARALLOX" is eight very wide glyphs and will not fit on a phone */
  container-type:inline-size;
}

.hero__kicker{
  font-size:clamp(.72rem,2.4vw,.85rem);
  letter-spacing:.3em;
  color:var(--red);
  margin-bottom:1.1rem;
}

.hero__title{
  font-size:clamp(2.05rem,11.5vw,5.5rem);
  font-weight:900;
  letter-spacing:-.02em;
  line-height:.92;
  margin-bottom:1.4rem;
}
.hero__title .blue{color:#2f8bff;text-shadow:0 0 34px rgba(47,139,255,.45)}
.hero__title .red{color:var(--red);text-shadow:0 0 34px rgba(255,45,85,.5)}
@supports (container-type:inline-size){
  .hero__title{font-size:min(clamp(1.5rem,11vw,5.5rem),11.5cqi)}
}

.hero__lede{font-size:var(--fs-lede);max-width:46ch;margin-bottom:2rem}
.hero__cta{display:flex;flex-wrap:wrap;gap:.75rem}

/* ── The floating LL ────────────────────────────────────────────────
   assets/hero.webp is 640x672 and fully transparent outside the artwork
   (measured: corners alpha 0, artwork spans rows 0-646). So there is
   nothing to crop and nothing to mask — an earlier `overflow:hidden` crop
   box was clipping the top of the character on every frame of the float.

   The image is simply placed whole, and the ring is sized from the same
   token so the two are concentric at any viewport. Overlapping the ring a
   little is intentional. */
.hero__art{
  position:relative;
  display:grid;place-items:center;
  --art:clamp(170px,23vw,290px);
}
.hero__char{
  position:relative;z-index:2;
  width:var(--art);
  line-height:0;
}
.hero__char img{
  width:100%;height:auto;
  image-rendering:pixelated;
  filter:drop-shadow(0 22px 40px rgba(0,0,0,.75));
}
html[data-fx="full"] .hero__char img{animation:float 4s ease-in-out infinite;will-change:transform}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-15px)}}

.hero__glow{
  position:absolute;z-index:0;
  width:calc(var(--art) + clamp(70px,16vw,180px));aspect-ratio:1;
  background:radial-gradient(circle,rgba(255,45,85,.5),transparent 68%);
}
html[data-fx="full"] .hero__glow{animation:breathe 7s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:.55;transform:scale(.96)}50%{opacity:.95;transform:scale(1.04)}}

/* The ring is sized off the same --art token, so it is guaranteed to be
   concentric with the character no matter the viewport. The artwork is
   646/640 of its width tall, so 1.13x leaves an even margin all round. */
.hero__ring{
  position:absolute;z-index:1;
  width:calc(var(--art) * 1.13);aspect-ratio:1;
  border:2px dashed var(--red);
  border-radius:50%;
  opacity:.55;
}
html[data-fx="full"] .hero__ring{animation:spin 26s linear infinite;will-change:transform}
@keyframes spin{to{transform:rotate(360deg)}}

.hero__cue{
  position:absolute;left:50%;bottom:1.1rem;
  transform:translateX(-50%);
  display:none;flex-direction:column;align-items:center;gap:.2rem;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.28em;color:var(--faint);
}
.hero__cue svg{width:1rem;height:1rem}
@media (min-width:900px){.hero__cue{display:flex}}
@media (hover:hover){html[data-fx="full"] .hero__cue svg{animation:nudge 2.2s ease-in-out infinite}}
@keyframes nudge{0%,100%{transform:translateY(0);opacity:.55}50%{transform:translateY(4px);opacity:1}}

/* Stacked hero: tighten it so the character still peeks above the fold. */
@media (max-width:899px){
  .hero{
    padding-top:calc(var(--nav-h) + clamp(1.5rem,5vh,2.75rem));
    padding-bottom:clamp(2.5rem,7vh,4rem);
  }
  .hero__art{--art:clamp(160px,40vw,230px)}
}

/* =====================================================================
   SECTION SCAFFOLD
   One rhythm everywhere, so the page reads as one ordered document
   rather than a stack of unrelated blocks.
   ===================================================================== */
.section{position:relative;padding-block:var(--section-y);background:var(--void)}
/* hairline between stacked sections — 1px, painted once */
.section + .section::before{
  content:'';position:absolute;inset-inline:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line-strong) 20%,var(--line-strong) 80%,transparent);
}
.section--dark{background:var(--void-deep)}

.section__head{
  text-align:center;
  max-width:64ch;
  margin:0 auto clamp(2rem,5vw,3.25rem);
}
.section__title{font-size:var(--fs-h2);letter-spacing:-.015em}
.section__title .red{color:var(--red)}
.section__title .blue{color:#2f8bff}
.section__sub{margin-top:1.1rem;font-size:var(--fs-lede)}
.section__foot{margin-top:2.25rem;text-align:center;font-size:var(--fs-small);color:var(--faint)}

/* =====================================================================
   SCREENSHOT CAROUSEL
   Coverflow on capable pointers, native scroll-snap filmstrip everywhere
   else. Same markup, no JS required for the fallback.
   ===================================================================== */
.section--cinema{
  position:relative;
  /* The coverflow cards at ±2 sit well outside the viewport on purpose.
     `clip` contains them without creating a scroll container, so the page
     still has no horizontal overflow. */
  overflow:clip;
}

.carousel__stage{
  display:flex;
  gap:clamp(.75rem,2vw,1.25rem);
  overflow-x:auto;
  overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  scrollbar-width:none;
  /* Equal inset on both sides is what lets the FIRST and LAST card reach
     the centre. Without it a scroll container can only ever scroll so far,
     so those two cards were pinned to the edges and unreachable. */
  padding-block:.5rem;
  padding-inline:max(1rem, calc((100% - min(86vw,620px)) / 2));
  -webkit-overflow-scrolling:touch;
}
.carousel__stage::-webkit-scrollbar{display:none}

.shot{
  position:relative;
  flex:0 0 min(86vw,620px);
  scroll-snap-align:center;
  aspect-ratio:16/9;
  border-radius:var(--r-lg);
  overflow:hidden;
  background:var(--surface);
  border:1px solid var(--line);
  transition:transform .4s var(--ease),border-color .3s;
}
@media (hover:hover){html[data-fx="full"] .shot:hover{transform:translateY(-4px);border-color:rgba(255,45,85,.4)}}
.shot[role="button"]{cursor:pointer}
.shot[role="button"]:focus-visible{outline:2px solid var(--red);outline-offset:3px}
.shot__img{width:100%;height:100%;object-fit:cover}
.shot__top{position:absolute;z-index:3;top:14px;left:18px}
.shot__top img{height:24px;width:auto;image-rendering:pixelated;filter:drop-shadow(0 2px 2px rgba(0,0,0,.8))}

.shot::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(to top,rgba(3,5,11,.94) 0%,rgba(3,5,11,.5) 32%,transparent 58%);
  opacity:.85;
}
.shot__body{
  position:absolute;z-index:2;left:0;right:0;bottom:0;
  padding:clamp(1rem,2.5vw,1.5rem);
}
.shot__title{
  display:block;
  font-family:var(--display);font-weight:800;
  font-size:clamp(1rem,2.6vw,1.4rem);letter-spacing:.02em;color:var(--ink);
  margin-bottom:.2rem;
}
.shot__info{display:block;font-family:var(--mono);font-size:var(--fs-small);color:#c6cee0}

/* controls only exist in coverflow mode */
.carousel__nav{display:none}

/* --- coverflow: full-fx + fine pointer + enough width to spread out --- */
@media (min-width:760px) and (hover:hover) and (pointer:fine){
  html[data-fx="full"] .carousel__stage{
    display:block;
    /* exactly the active card's height plus breathing room */
    height:calc(min(52vw,660px) * 9 / 16 + 2rem);
    overflow:visible;
    padding:0;
    perspective:1400px;
    touch-action:pan-y;
  }
  html[data-fx="full"] .shot{
    position:absolute;
    top:50%;left:50%;
    width:min(52vw,660px);
    height:auto;
    border-radius:var(--r-lg);
    transition:transform .7s var(--ease),opacity .6s var(--ease);
    cursor:pointer;
  }
  html[data-fx="full"] .shot__body{opacity:0;transform:translate3d(0,14px,0);transition:opacity .45s ease .08s,transform .5s var(--ease) .08s}

  /* only the active card paints a glow; the rest are flat */
  html[data-fx="full"] .shot[data-pos="0"]{
    z-index:10;
    transform:translate3d(-50%,-50%,0) scale(1);
    opacity:1;
    box-shadow:0 30px 70px rgba(0,0,0,.75),0 0 0 2px var(--red);
  }
  html[data-fx="full"] .shot[data-pos="0"] .shot__body{opacity:1;transform:none}

  html[data-fx="full"] .shot[data-pos="1"],
  html[data-fx="full"] .shot[data-pos="-1"]{
    z-index:6;opacity:.55;
    filter:saturate(.7) brightness(.75);
  }
  html[data-fx="full"] .shot[data-pos="1"]{transform:translate3d(calc(-50% + 58%),-50%,-220px) scale(.78) rotateY(-16deg)}
  html[data-fx="full"] .shot[data-pos="-1"]{transform:translate3d(calc(-50% - 58%),-50%,-220px) scale(.78) rotateY(16deg)}

  html[data-fx="full"] .shot[data-pos="2"],
  html[data-fx="full"] .shot[data-pos="-2"]{
    z-index:3;opacity:.22;
    filter:saturate(.4) brightness(.5);
  }
  html[data-fx="full"] .shot[data-pos="2"]{transform:translate3d(calc(-50% + 88%),-50%,-420px) scale(.6) rotateY(-24deg)}
  html[data-fx="full"] .shot[data-pos="-2"]{transform:translate3d(calc(-50% - 88%),-50%,-420px) scale(.6) rotateY(24deg)}

  /* offscreen slots: transform + opacity only, nothing to repaint */
  html[data-fx="full"] .shot[data-pos="hidden"]{z-index:1;opacity:0;pointer-events:none}
  html[data-fx="full"] .shot[data-pos="hidden"]:nth-child(even){transform:translate3d(calc(-50% + 120%),-50%,-600px) scale(.5)}
  html[data-fx="full"] .shot[data-pos="hidden"]:nth-child(odd){transform:translate3d(calc(-50% - 120%),-50%,-600px) scale(.5)}

  html[data-fx="full"] .carousel__nav{
    display:flex;align-items:center;justify-content:center;gap:clamp(1rem,3vw,2rem);
    margin-top:clamp(1.5rem,4vw,2.5rem);
  }
}
.carousel__arrow{
  display:grid;place-items:center;
  width:46px;height:46px;flex:none;
  border:1px solid var(--line-strong);border-radius:50%;
  color:var(--ink);background:rgba(255,255,255,.03);
  transition:transform .25s var(--ease),border-color .25s,color .25s,background-color .25s;
}
.carousel__arrow svg{width:1.15rem;height:1.15rem}
.carousel__arrow:disabled{opacity:.3;cursor:default;transform:none}
@media (hover:hover){html[data-fx="full"] .carousel__arrow:not(:disabled):hover{border-color:var(--red);color:var(--red);background:var(--red-soft)}}
@media (hover:none){.carousel__arrow:not(:disabled):active{transform:scale(.94)}}

.carousel__dots{display:flex;gap:.35rem;flex-wrap:wrap;justify-content:center}
/* 26px tall hit area with a 4px bar drawn inside it */
.carousel__dots button{position:relative;width:30px;height:26px;background:none}
.carousel__dots button::after{
  content:'';position:absolute;left:4px;right:4px;top:50%;
  height:4px;margin-top:-2px;border-radius:var(--r-pill);
  background:var(--line-strong);
  transition:background-color .3s,transform .3s var(--ease);
}
.carousel__dots button[aria-current="true"]::after{background:var(--red);transform:scaleY(1.9)}

/* =====================================================================
   STATS
   ===================================================================== */
.stats{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:clamp(1rem,3vw,2rem);
  max-width:760px;margin-inline:auto;
}
.stat{
  padding:clamp(1.25rem,3vw,2rem) 1rem;
  background:linear-gradient(180deg,var(--surface),transparent);
  border:1px solid var(--line);border-radius:var(--r-lg);
  text-align:center;
}
.stat dt{font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.2em;color:var(--faint)}
.stat dd{font-family:var(--display);font-weight:900;font-size:clamp(2.2rem,7vw,3.4rem);line-height:1;color:var(--red)}

/* =====================================================================
   FEATURES
   ===================================================================== */
.features{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));
  gap:clamp(1rem,2.2vw,1.6rem);
}
.feature{
  padding:clamp(1.5rem,3vw,2rem);
  background:linear-gradient(180deg,var(--surface),rgba(11,16,24,.3));
  border:1px solid var(--line);border-radius:var(--r-lg);
  transition:transform .4s var(--ease),border-color .3s;
}
.feature__icon{
  display:grid;place-items:center;
  width:52px;height:52px;margin:0 auto 1.1rem;
  border-radius:var(--r-md);
  background:var(--red-soft);border:1px solid rgba(255,45,85,.28);
  color:var(--red);
}
.feature__icon svg{width:24px;height:24px}
.feature h3{
  font-size:var(--fs-h3);letter-spacing:.03em;text-align:center;
  text-transform:none;
}
@media (hover:hover){
  html[data-fx="full"] .feature:hover{transform:translateY(-5px);border-color:rgba(255,45,85,.4);box-shadow:0 18px 40px rgba(0,0,0,.45)}
}

/* =====================================================================
   CHARACTERS
   ===================================================================== */
.cast{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,265px),1fr));
  gap:clamp(1rem,2.2vw,1.6rem);
}
.character{
  position:relative;
  display:grid;
  grid-template-columns:clamp(96px,30%,128px) minmax(0,1fr);
  gap:clamp(.9rem,2.4vw,1.5rem);
  align-items:start;
  text-align:left;
  padding:clamp(1.1rem,2.8vw,1.6rem);
  background:linear-gradient(180deg,var(--surface),rgba(11,16,24,.3));
  border:1px solid var(--line);border-radius:var(--r-lg);
  transition:transform .4s var(--ease),border-color .3s,background-color .3s,box-shadow .3s;
}
/* Played = lit red. script.js removes aria-pressed when the clip ends. */
.character[aria-pressed="true"]{
  border-color:rgba(255,45,85,.55);
  background:linear-gradient(180deg,rgba(255,45,85,.12),rgba(11,16,24,.3));
  box-shadow:0 0 30px rgba(255,45,85,.22);
}
.character::after{
  content:'';position:absolute;left:clamp(1.1rem,2.8vw,1.6rem);right:clamp(1.1rem,2.8vw,1.6rem);bottom:0;height:2px;
  background:var(--red);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .45s var(--ease);
}
.character[aria-pressed="true"]::after{transform:scaleX(1)}
@media (hover:hover){html[data-fx="full"] .character:hover{transform:translateY(-5px);border-color:rgba(255,45,85,.35)}}
@media (hover:none){.character:active{transform:scale(.985)}}

.character__body{display:flex;flex-direction:column;min-width:0}

/* ── Portraits ──────────────────────────────────────────────────────
   The three sprites are 64x64 GIFs whose visible character only fills
   15-29% of the frame and sits well below centre. Measured opaque
   bounding boxes (read back from a canvas):

     sprite   bbox     origin    centre (x,y)
     mikie    18x34    (23,30)   (32,47)     → 15% of the frame visible
     mike     26x45    (19,19)   (32,41.5)   → 29%
     walter   19x39    (21,25)   (30.5,44.5) → 18%

   Each rule scales the frame so the visible art fills ~80% of the
   portrait, then re-centres it. Solved from "background-position P% puts
   P% of the image overhang past the edge":
   P = (0.5 - centre·scale) / (1 - scale).
   Total payload for all three: 3.9 KB. */
.character__portrait{
  aspect-ratio:4/5;
  overflow:hidden;
  border-radius:var(--r-md);
  background-color:rgba(255,45,85,.06);
  background-repeat:no-repeat;
  image-rendering:pixelated;
}
.character--mikie .character__portrait{
  background-image:url('assets/young_mike3-export.gif');
  background-size:auto 151%;
  background-position:50% 120%;
}
.character--mike .character__portrait{
  background-image:url('assets/mike.gif');
  background-size:auto 114%;
  background-position:50% 172%;
}
.character--walter .character__portrait{
  background-image:url('assets/walter.gif');
  background-size:auto 131%;
  background-position:44% 132%;
}

.character__name{font-family:var(--display);font-weight:900;font-size:clamp(1.25rem,4vw,1.6rem);letter-spacing:.06em;color:var(--ink)}
.character__desc{margin-top:.75rem;font-size:.94rem}
.character__cue{
  display:flex;align-items:center;
  margin-top:1.1rem;padding-top:.9rem;
  border-top:1px solid var(--line);
  color:var(--faint);
  transition:color .25s;
}
.character__cue svg{width:1.05rem;height:1.05rem}
.character:hover .character__cue{color:var(--muted)}
.character[aria-pressed="true"] .character__cue{color:var(--red)}

/* =====================================================================
   DEMO PORTAL — the original singularity, on the new cosmos backdrop
   ===================================================================== */
.omega{position:relative;background:#010104}
.omega__root{
  position:relative;
  min-height:100vh;min-height:100svh;
  display:grid;place-items:center;
  padding:clamp(3rem,9vh,6rem) var(--pad-x);
  overflow:clip;
  background:#010104;
  font-family:var(--mono);
  isolation:isolate;
  --primary:var(--cyan);
  --core-glow:rgba(34,224,255,.5);
}

/* Original layout: the readout is pinned to the top of the panel, the
   mechanism sits centred in the flow, and the status line is pinned to the
   bottom. Absolute edges are what made the original read as a HUD. */
.omega__readout{
  position:absolute;left:0;right:0;z-index:4;
  top:50px;
  text-align:center;
  text-shadow:0 0 20px var(--primary);
  transform:translateY(20px);
}
.omega__title{
  font-family:var(--display);font-weight:900;
  letter-spacing:10px;
  font-size:2.5rem;margin:0;
  color:#fff;
  background:linear-gradient(white,var(--primary));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
}
.omega__sub{font-family:var(--body);font-size:var(--fs-lede);margin-top:.6rem}
.omega__sub span{color:var(--muted)}
.omega__status{
  position:absolute;left:0;right:0;bottom:40px;
  z-index:4;
  text-align:center;
  font-family:var(--mono);font-size:12px;letter-spacing:2px;
  color:var(--primary);opacity:.6;min-height:1.4em;
  padding:0 1rem;
  transition:color .3s;
}

.cosmos{position:absolute;inset:0;z-index:0;overflow:clip;pointer-events:none}
/* No filter:blur() here. Radial gradients are already soft, and blurring a
   layer twice the viewport size was one of the heaviest rasters on the page. */
.cosmos__nebula{
  position:absolute;inset:0;
  background:
    radial-gradient(50% 45% at 50% 45%,rgba(0,229,255,.13),transparent 68%),
    radial-gradient(38% 34% at 82% 18%,rgba(255,0,85,.10),transparent 70%),
    radial-gradient(40% 36% at 16% 84%,rgba(168,85,247,.10),transparent 72%);
}
html[data-fx="full"] .cosmos__nebula{animation:nebula 24s ease-in-out infinite alternate}
@keyframes nebula{from{opacity:.55;transform:scale(1)}to{opacity:1;transform:scale(1.06)}}

/* Oversized + transform drift instead of background-position, so the whole
   thing stays on the compositor. */
.cosmos__stars{
  position:absolute;inset:-35%;
  background-image:
    radial-gradient(1.5px 1.5px at 50% 50%,rgba(255,255,255,.9),transparent),
    radial-gradient(1px 1px at 20% 80%,rgba(255,255,255,.45),transparent),
    radial-gradient(2px 2px at 74% 24%,rgba(190,230,255,.6),transparent);
  background-size:120px 120px,220px 220px,320px 320px;
  opacity:.32;
}
html[data-fx="full"] .cosmos__stars{animation:drift 90s linear infinite;will-change:transform}
@keyframes drift{to{transform:translate3d(0,320px,0)}}

/* 120vmax, not 200vmax: the old size needed a ~1690px square layer (≈11 MB of
   RGBA) just to hold a conic gradient. */
.cosmos__rays{
  position:absolute;top:50%;left:50%;
  width:120vmax;height:120vmax;
  margin:-60vmax 0 0 -60vmax;
  background:conic-gradient(from 0deg at 50% 50%,
    transparent 0deg,rgba(0,229,255,.07) 18deg,transparent 34deg,
    rgba(0,229,255,.045) 62deg,transparent 78deg,
    rgba(168,85,247,.05) 150deg,transparent 168deg,
    transparent 360deg);
}
html[data-fx="full"] .cosmos__rays{animation:spin 120s linear infinite;will-change:transform}

.hud-frame{
  position:absolute;inset:30px;z-index:10;pointer-events:none;
  border:1px solid rgba(0,243,255,.05);
  background:
    linear-gradient(to right,var(--primary) 2px,transparent 2px) 0 0,
    linear-gradient(to bottom,var(--primary) 2px,transparent 2px) 0 0,
    linear-gradient(to left,var(--primary) 2px,transparent 2px) 100% 100%,
    linear-gradient(to top,var(--primary) 2px,transparent 2px) 100% 100%;
  background-size:20px 20px;background-repeat:no-repeat;
  opacity:.5;
  transition:opacity .4s;
}
.omega__root.is-charging .hud-frame{opacity:.8}

/* ── The mechanism ────────────────────────────────────────────────────
   Geometry, colours and keyframes reproduced from the original stylesheet
   verbatim: a 400px square, rings inset 30px / 60px, a 100px vortex, and
   the whole core dropped 40px. The cosmos layers above are the only new
   part. */
.artifact{
  position:relative;
  width:400px;height:400px;
  transform-style:preserve-3d;
  transition:transform .1s ease-out;
  z-index:5;
  max-width:88vw;max-height:60vh;
  aspect-ratio:1;
}
.core{
  position:absolute;inset:0;
  transform-style:preserve-3d;
  cursor:pointer;
  transform:translateY(40px);
  border-radius:50%;
  background:none;
}

.energy-ring{
  position:absolute;inset:0;
  border-radius:50%;
  transform-style:preserve-3d;
  box-shadow:0 0 30px rgba(0,243,255,.05),inset 0 0 30px rgba(0,243,255,.05);
  transition:opacity .5s;
}
.ring-outer{
  border:1px solid rgba(0,243,255,.3);
  border-top:4px solid var(--primary);
  border-bottom:4px solid var(--primary);
}
.ring-mid{
  inset:30px;
  border:2px dashed rgba(0,243,255,.5);
  filter:drop-shadow(0 0 5px var(--primary));
}
.ring-inner{
  inset:60px;
  border-left:8px double var(--primary);
  border-right:8px double var(--primary);
}
html[data-fx="full"] .ring-outer{animation:gyroSpinA 12s linear infinite;will-change:transform}
html[data-fx="full"] .ring-mid{animation:gyroSpinB 8s linear infinite reverse;will-change:transform}
html[data-fx="full"] .ring-inner{animation:gyroSpinC 6s cubic-bezier(.4,0,.2,1) infinite alternate;will-change:transform}
@keyframes gyroSpinA{from{transform:rotateX(0) rotateY(0) rotateZ(0)}to{transform:rotateX(360deg) rotateY(180deg) rotateZ(360deg)}}
@keyframes gyroSpinB{from{transform:rotateX(0) rotateY(0)}to{transform:rotateX(-360deg) rotateY(360deg)}}
@keyframes gyroSpinC{from{transform:rotateY(0) rotateZ(-20deg)}to{transform:rotateY(360deg) rotateZ(20deg)}}

.singularity-vortex{
  position:absolute;inset:100px;
  border-radius:50%;
  background:#000;
  overflow:hidden;
  display:grid;place-items:center;
  transform:translateZ(20px);
  box-shadow:inset 0 0 60px rgba(0,0,0,1),0 0 50px var(--core-glow),0 0 100px var(--primary),inset 0 0 10px rgba(255,255,255,.8);
  transition:.5s cubic-bezier(.175,.885,.32,1.275);
}
.singularity-vortex i{
  position:absolute;inset:-50%;
  background:conic-gradient(from 180deg,transparent 0%,var(--primary) 30%,white 50%,transparent 80%);
  opacity:.7;
  filter:blur(10px);
}
html[data-fx="full"] .singularity-vortex i{animation:vortexSpin 2s linear infinite;will-change:transform}
@keyframes vortexSpin{to{transform:rotate(360deg)}}

/* Dark lens so the readout stays legible whichever way the vortex points. */
.singularity-vortex::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(circle,rgba(0,0,0,.8) 20%,rgba(0,0,0,.3) 64%,transparent 84%);
}

.activation-label{
  position:absolute;z-index:3;
  top:50%;left:50%;
  transform:translate(-50%,-50%) translateZ(40px);
  font-family:var(--display);font-size:14px;
  letter-spacing:4px;color:#fff;
  text-shadow:0 0 10px var(--primary);
  pointer-events:none;white-space:nowrap;
  opacity:.8;
  transition:.3s;
}
@media (hover:hover){
  html[data-fx="full"] .core:hover .activation-label{opacity:1;letter-spacing:6px}
  html[data-fx="full"] .core:hover .singularity-vortex{box-shadow:inset 0 0 40px #000,0 0 80px var(--primary),0 0 150px var(--primary),inset 0 0 20px white;transform:translateZ(30px) scale(1.05)}
}
@media (hover:none){.core:active .singularity-vortex{box-shadow:inset 0 0 40px #000,0 0 80px var(--primary),0 0 150px var(--primary)}}

/* ══ LAUNCH SEQUENCE — reproduced from the original stylesheet ════════
   Press  -> `is-charging`: --primary turns red, the rings speed up, the
             vortex turns red and the core starts shaking.
   +1.5s  -> `is-breached`: the core collapses — it shrinks to nothing,
             blows out to pure white, then expands past the viewport while
             the event-horizon flash washes the screen. */
.omega__root.is-charging{--primary:#ff0055;--core-glow:rgba(255,0,85,.8)}
.omega__root.is-charging .core{animation:violentShake .2s linear infinite;will-change:transform}
.omega__root.is-charging .energy-ring{animation-duration:1s}
.omega__root.is-charging .singularity-vortex i{
  animation-duration:.5s;
  background:conic-gradient(from 180deg,transparent 0%,#ff0055 50%,white 70%,transparent 100%);
}
@keyframes violentShake{
  0%  { transform:translateY(40px) translate(2px,1px) rotate(0deg); }
  25% { transform:translateY(40px) translate(-3px,-2px) rotate(-1deg); }
  50% { transform:translateY(40px) translate(3px,1px) rotate(1deg); }
  75% { transform:translateY(40px) translate(-2px,3px) rotate(0deg); }
  100%{ transform:translateY(40px) translate(1px,-1px) rotate(-1deg); }
}
.omega__root.is-breached .energy-ring{opacity:0;transition:.5s}
.omega__root.is-breached .singularity-vortex{animation:coreCollapse 1.5s forwards cubic-bezier(.645,.045,.355,1)}
@keyframes coreCollapse{
  0%  { transform:translateZ(20px) scale(1);   filter:brightness(1);   }
  40% { transform:translateZ(20px) scale(.05); filter:brightness(5);   background:#fff; }
  70% { transform:translateZ(20px) scale(.01); filter:brightness(20);  opacity:1; }
  100%{ transform:translateZ(20px) scale(60);  filter:brightness(100); opacity:0; }
}
.omega__flash{position:fixed;inset:0;z-index:999;background:#fff;opacity:0;pointer-events:none;transition:opacity .1s ease-in}

/* =====================================================================
   GAME CONTROLS
   ===================================================================== */
/* Flex, not grid. With 10 tiles a grid leaves an orphan in the left column
   of the last row — which is exactly the "drifting off to the left" look.
   `justify-content:center` centres however many land on that row. */
.keys{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:clamp(.5rem,1.6vw,1rem);
  max-width:1000px;
  margin-inline:auto;
}
/* `flex-grow:0` keeps a lone tile in the last row from stretching across
   the whole row; it stays tile-sized and the row still centres. */
.key{
  flex:0 1 168px;
  max-width:186px;
}
@media (max-width:899px){.key{flex:0 1 140px;max-width:172px}}
@media (max-width:599px){.key{flex:0 1 30%}}
.key{
  display:grid;
  justify-items:center;      /* everything centred inside its tile */
  align-content:center;
  gap:.45rem;
  padding:clamp(1rem,2.4vw,1.5rem) .6rem;
  background:linear-gradient(180deg,var(--surface),rgba(11,16,24,.3));
  border:1px solid var(--line);border-radius:var(--r-md);
  text-align:center;
  transition:transform .3s var(--ease),border-color .3s;
}
.key svg{margin-inline:auto}
.key svg{width:22px;height:22px;color:var(--red);margin:0 auto}
.key__name{font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.18em;color:var(--ink);text-align:center}
.key kbd{font-size:var(--fs-small);color:var(--faint);text-align:center}
@media (hover:hover){html[data-fx="full"] .key:hover{transform:translateY(-3px);border-color:rgba(255,45,85,.35)}}

/* =====================================================================
   CHANNELS
   ===================================================================== */
.channels{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr));
  gap:clamp(.6rem,1.8vw,1.1rem);
  max-width:1000px;margin-inline:auto;
}
.channels__wide{grid-column:1/-1}
.channel{
  position:relative;
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-areas:"icon name go" "icon desc go";
  align-items:center;
  gap:.15rem 1rem;
  height:100%;
  padding:clamp(1.1rem,2.6vw,1.5rem);
  background:linear-gradient(180deg,var(--surface),rgba(11,16,24,.3));
  border:1px solid var(--line);border-radius:var(--r-lg);
  transition:transform .35s var(--ease),border-color .3s,background-color .3s;
}
.channel__icon{
  grid-area:icon;
  display:grid;place-items:center;
  width:46px;height:46px;
  border-radius:var(--r-md);
  background:var(--red-soft);border:1px solid rgba(255,45,85,.25);
  color:var(--red);
}
.channel__icon svg{width:22px;height:22px}
.channel__name{grid-area:name;font-family:var(--display);font-weight:800;font-size:.98rem;letter-spacing:.04em;color:var(--ink)}
.channel__desc{grid-area:desc;font-family:var(--mono);font-size:var(--fs-small);color:var(--faint)}
.channel__go{grid-area:go;color:var(--faint);transform:translateX(-4px);transition:transform .35s var(--ease),color .3s}
.channel__go svg{width:1.05rem;height:1.05rem}
@media (hover:hover){
  html[data-fx="full"] .channel:hover{transform:translateY(-4px);border-color:rgba(255,45,85,.4)}
  html[data-fx="full"] .channel:hover .channel__go{transform:none;color:var(--red)}
}
@media (hover:none){.channel:active{transform:scale(.985)}}

/* =====================================================================
   FAQ
   ===================================================================== */
.faq{max-width:820px;margin-inline:auto;display:grid;gap:.7rem}
.faq__item{
  background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-md);
  overflow:hidden;
  transition:border-color .3s,background-color .3s;
}
.faq__item.open{border-color:rgba(255,45,85,.38);background:var(--surface-2)}
.faq__q{font:inherit}
.faq__btn{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  width:100%;min-height:60px;
  padding:clamp(.9rem,2.2vw,1.35rem) clamp(1rem,2.6vw,1.5rem);
  text-align:left;
  font-family:var(--display);font-weight:700;font-size:clamp(.9rem,2vw,1rem);
  letter-spacing:.02em;color:var(--ink);
}
.faq__chev{flex:none;width:1.1rem;height:1.1rem;color:var(--red);transition:transform .35s var(--ease)}
.faq__item.open .faq__chev{transform:rotate(90deg)}
.faq__a{
  max-height:0;overflow:hidden;
  padding-inline:clamp(1rem,2.6vw,1.5rem);
  color:var(--muted);font-size:.95rem;
  opacity:0;
  transition:max-height .45s var(--ease),opacity .35s ease,padding-bottom .45s var(--ease);
}
.faq__item.open .faq__a{max-height:24rem;opacity:1;padding-bottom:clamp(1rem,2.2vw,1.35rem)}

/* =====================================================================
   CONTACT
   ===================================================================== */
.contacts{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));
  gap:clamp(.8rem,2vw,1.2rem);
  max-width:900px;margin-inline:auto;
}
.contact{
  position:relative;
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:1rem;
  padding:clamp(1.2rem,2.8vw,1.6rem);
  text-align:left;
  background:linear-gradient(180deg,var(--surface),rgba(11,16,24,.3));
  border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;
  transition:transform .35s var(--ease),border-color .3s,background-color .3s;
}
.contact__icon{
  display:grid;place-items:center;
  width:48px;height:48px;
  border-radius:var(--r-md);
  background:var(--red-soft);border:1px solid rgba(255,45,85,.25);
  color:var(--red);
}
.contact__icon svg{width:22px;height:22px}
.contact__body{min-width:0}
.contact__who{display:block;font-family:var(--mono);font-size:var(--fs-label);letter-spacing:.2em;color:var(--red)}
.contact__addr{
  display:block;margin-top:.2rem;
  font-family:var(--mono);font-size:clamp(.82rem,2vw,.95rem);
  color:var(--ink);
  overflow-wrap:anywhere;
}
.contact__light{
  width:8px;height:8px;border-radius:50%;
  background:var(--green);box-shadow:0 0 10px var(--green);
}
html[data-fx="full"] .contact__light{animation:blip 2.6s ease-in-out infinite}
@media (hover:hover){html[data-fx="full"] .contact:hover{transform:translateY(-4px);border-color:rgba(255,45,85,.4)}}
@media (hover:none){.contact:active{transform:scale(.985)}}

.contact__copy{
  position:absolute;inset:0;z-index:2;
  display:flex;align-items:center;justify-content:center;gap:.5rem;
  background:rgba(3,5,11,.94);
  color:var(--green);
  font-family:var(--mono);font-size:var(--fs-small);letter-spacing:.2em;
  opacity:0;pointer-events:none;
  transition:opacity .28s ease;
}
.contact__copy svg{width:1rem;height:1rem}
.contact.copied .contact__copy{opacity:1}
.contact.copied{border-color:rgba(37,245,168,.45)}

.support{
  max-width:560px;margin:clamp(2.5rem,6vw,4rem) auto 0;
  text-align:center;
  padding:clamp(1.8rem,4vw,2.8rem);
  background:linear-gradient(180deg,var(--surface),rgba(11,16,24,.2));
  border:1px solid var(--line);border-radius:var(--r-lg);
}
.support h3{font-size:1.2rem;letter-spacing:.1em;margin-bottom:.8rem}
.support p{margin-bottom:1.8rem;font-size:.96rem}

/* =====================================================================
   FOOTER
   ===================================================================== */
.footer{background:var(--void-deep);border-top:1px solid var(--line);padding-block:clamp(2.5rem,6vw,3.5rem);text-align:center}
.footer p{font-size:var(--fs-small);color:var(--faint);line-height:1.9}

/* =====================================================================
   MODALS
   ===================================================================== */
.modal{
  position:fixed;inset:0;z-index:200;
  display:grid;place-items:center;
  padding:var(--pad-x);
  background:rgba(2,3,8,.86);
}
.modal[hidden]{display:none}
.modal__box{
  position:relative;
  width:min(440px,100%);
  max-height:88vh;overflow:auto;
  /* The close button is 44px tall and sits 0.6rem from the corner, so it
     occupies the first 53.6px of the box. 3.6rem (57.6px) reserves that
     band with a little to spare, otherwise the heading runs underneath it
     as soon as the text is wide enough to reach the right edge. */
  padding:3.6rem clamp(1.1rem,4vw,2.6rem) clamp(1.5rem,4vw,2.6rem);
  text-align:center;
  background:var(--surface);
  border:1px solid rgba(255,45,85,.35);
  border-radius:var(--r-lg);
  box-shadow:0 30px 80px rgba(0,0,0,.7);
  animation:modalIn .3s var(--ease);
}
.modal__box--video{width:min(920px,100%);padding:0;overflow:hidden;aspect-ratio:16/9;background:#000}
@keyframes modalIn{from{opacity:0;transform:translate3d(0,14px,0) scale(.97)}to{opacity:1;transform:none}}
.modal__box h2{font-size:1.3rem;letter-spacing:.08em;color:var(--red);margin-bottom:.9rem}
.modal__box p{font-size:.94rem;margin-bottom:1.6rem}
.modal__note{margin:1.2rem 0 0;font-size:var(--fs-small);color:var(--faint)}
.modal__video{width:100%;height:100%}
.modal__video iframe{width:100%;height:100%;border:0}
.modal__close{
  position:absolute;top:.6rem;right:.6rem;z-index:3;
  display:grid;place-items:center;
  width:44px;height:44px;
  border-radius:50%;
  background:rgba(255,45,85,.18);
  border:1px solid rgba(255,45,85,.5);
  color:var(--red);
  transition:background-color .25s,color .25s,transform .25s var(--ease);
}
.modal__close svg{width:1.1rem;height:1.1rem}
@media (hover:hover){.modal__close:hover{background:var(--red);color:#fff;transform:scale(1.06)}}
body.modal-open{overflow:hidden}

/* =====================================================================
   CONTAINMENT
   `content-visibility: auto` is used on exactly two elements: the demo
   portal and the footer. Both are full-height, self-contained blocks whose
   real height barely changes with the viewport, so a single honest
   placeholder is safe and the scrollbar never lurches.

   It is deliberately NOT used on the content sections. Their height swings
   by several hundred pixels between a 360px phone and a wide desktop, and
   any placeholder that is wrong makes the page grow under the reader as
   they scroll — far worse than the layout it would have saved. Off-screen
   sections are already effectively free: nothing in them animates
   (script.js gates that) and every image is `loading="lazy"`.
   ===================================================================== */
.omega{contain-intrinsic-size:auto 780px}
.footer{contain-intrinsic-size:auto 240px}

@supports (content-visibility:auto){
  .omega,.footer{content-visibility:auto}
}

/* Ambient decoration is only composited while it can actually be seen. */
.hero:not(.in-view) .hero__char img,
.hero:not(.in-view) .hero__glow,
.hero:not(.in-view) .hero__ring,
.omega:not(.in-view) .cosmos__nebula,
.omega:not(.in-view) .cosmos__stars,
.omega:not(.in-view) .cosmos__rays,
.omega:not(.in-view) .energy-ring,
.omega:not(.in-view) .singularity-vortex i{animation:none}

/* =====================================================================
   NARROW SCREENS
   One column, one rhythm, one centre line. This is where the page has to
   feel like a single ordered document rather than a stack of cards.
   ===================================================================== */
@media (max-width:699px){
  :root{
    --section-y:3.25rem;
    --anchor-gap:16px;
    --pad-x:1.15rem;
  }

  /* one shared rhythm: nav clearance, section padding and the gap under
     every heading are all tied to the same scale */
  .section__head{margin-bottom:1.6rem}
  .section__title{font-size:clamp(1.4rem,6.2vw,1.85rem)}
  .section__sub{font-size:.94rem;line-height:1.6;margin-top:.85rem}
  /* the original copy carries hard line breaks; let them re-wrap on a phone */
  .section__sub br{content:none}

  /* section edges read as deliberate bands rather than bleeding together */
  .section{box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}

  .stats{gap:.55rem}
  .stat{padding:1rem .3rem}
  .stat dt{font-size:.62rem;letter-spacing:.14em}

  .features,.cast,.channels,.contacts{grid-template-columns:1fr}
  .feature{padding:1.15rem;text-align:center}
  .feature__icon{margin-bottom:.8rem;width:46px;height:46px}
  .feature h3{font-size:1rem}

  .cast{gap:.7rem}
  .character{grid-template-columns:84px minmax(0,1fr);gap:.85rem;padding:.9rem}
  .character__portrait{aspect-ratio:1}
  .character__name{font-size:1.15rem}
  .character__desc{font-size:.88rem;margin-top:.55rem}
  .character__cue{margin-top:.8rem;padding-top:.7rem}

  .keys{gap:.45rem}
  .key{flex:0 1 30%;padding:.8rem .25rem;gap:.3rem}
  .key svg{width:19px;height:19px}
  .key__name{font-size:.62rem;letter-spacing:.1em}
  .key kbd{font-size:.68rem;line-height:1.3}

  /* the filmstrip must be able to reach both ends, so keep the equal
     inset that lets the first and last card centre themselves */
  .carousel__stage{padding-inline:max(.6rem, calc((100% - 86vw) / 2))}

  .contact{grid-template-columns:auto minmax(0,1fr);gap:.8rem;padding:.9rem}
  .contact__icon{width:42px;height:42px}
  .contact__light{display:none}

  .faq{gap:.5rem}
  .faq__btn{min-height:52px;padding:.85rem 1rem;font-size:.88rem}

  .support{padding:1.4rem 1.1rem}
  .support h3{font-size:1.05rem;letter-spacing:.06em}
  .support p{font-size:.9rem}

  .footer p{font-size:.76rem;line-height:1.8}

  .modal__box{padding:3.6rem 1.1rem 1.5rem}
  .modal__box--video{aspect-ratio:16/9;padding:0}
  .modal__note{font-size:.75rem}
}

@media (max-width:480px){
  .artifact{width:min(240px,80vw);height:auto}
  .ring-mid{inset:18px}
  .ring-inner{inset:36px}
  .singularity-vortex{inset:58px}
  .omega__title{font-size:1.35rem;letter-spacing:3px}
  .omega__sub{font-size:.9rem}
}

@media (max-width:380px){
  .brand__word{font-size:.68rem}
  .keys{grid-template-columns:repeat(2,1fr)}
  .omega__title{font-size:1.15rem;letter-spacing:2px}
}

/* =====================================================================
   PREFERENCES
   ===================================================================== */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

@media (prefers-reduced-transparency:reduce){
  html[data-fx] .nav{backdrop-filter:none;-webkit-backdrop-filter:none}
}

@media print{
  .nav,.modal,.hero__cue{display:none}
  body{background:#fff;color:#000}
}