/* =====================================================================
   FX layer (Fable 5.2 edition). Motion only. Remove fx.css + fx.js and
   the inline "fx" script in <head> to return to the calm version.
   Everything here is off when the visitor prefers reduced motion,
   because the "fx" class is never added.
   ===================================================================== */
:root { --ease-out:cubic-bezier(.16,1,.3,1); --ease-snap:cubic-bezier(.7,0,.2,1); --xhair:#81C0EA; }

/* ---------- Intro curtain ---------- */
html.fx-intro body::before { content:""; position:fixed; inset:0; z-index:9998; background:#090f16; }
.fx-curtain { position:fixed; inset:0; z-index:9999; display:grid; place-items:center; overflow:hidden; cursor:pointer; }
.fx-curtain .fx-panels { position:absolute; inset:-10% -12%; display:flex; transform:skewX(-17deg); }
.fx-curtain .fx-panels i { flex:1; background:#0a1017; border-right:1px solid #ffffff10; transform-origin:top; }
.fx-curtain .fx-panels i:nth-child(3) { background:var(--red); }
.fx-curtain .fx-panels i:nth-child(4) { background:#b7263c; flex:.35; }
.fx-curtain .fx-mark { position:relative; text-align:center; color:#f4f0e8; }
.fx-curtain .fx-mark b { display:block; font:700 clamp(54px,11vw,150px)/.9 var(--font-display); letter-spacing:.02em; overflow:hidden; padding:.1em .04em 0; }
.fx-curtain .fx-mark b span { display:inline-block; animation:fxCharUp .7s var(--ease-out) both; animation-delay:calc(var(--i)*38ms + 80ms); }
.fx-curtain .fx-mark small { display:block; margin-top:14px; font:12px var(--font-mono); letter-spacing:.42em; color:#ffd9dd; animation:fxFade .5s .45s both; }
.fx-curtain .fx-load { display:block; width:min(320px,60vw); height:2px; margin:26px auto 0; background:#ffffff26; overflow:hidden; }
.fx-curtain .fx-load::after { content:""; display:block; height:100%; background:#fff; transform-origin:left; animation:fxLoad 1s .1s var(--ease-snap) both; }
.fx-curtain.fx-out .fx-panels i { animation:fxPanelOut .75s var(--ease-snap) both; animation-delay:calc(var(--i)*55ms); }
.fx-curtain.fx-out .fx-mark { animation:fxMarkOut .4s var(--ease-snap) both; }
@keyframes fxCharUp { from { transform:translateY(115%) rotate(7deg); } to { transform:none; } }
@keyframes fxFade { from { opacity:0; } to { opacity:1; } }
@keyframes fxLoad { from { transform:scaleX(0); } to { transform:scaleX(1); } }
@keyframes fxPanelOut { to { transform:translateY(-108%); } }
@keyframes fxMarkOut { to { opacity:0; transform:translateY(-40px) scale(1.06); } }

/* ---------- Hero sequence ---------- */
html.fx:not(.fx-hero-go) .cinematic-hero :is(.hero-eyebrow,.hero-title,.hero-desc,.hero-actions,.hero-art-label,.hero-scroll,.hero-char-img),
html.fx:not(.fx-hero-go) .hero-stage { opacity:0; }
html.fx .cinematic-hero .hero-char-img { animation:none; }
.fx-hero-go .hero-stage::before { animation:fxSlab .95s var(--ease-snap) both; }
.fx-hero-go .hero-stage::after { animation:fxFade .8s .7s both, stage-breathe 7s 1.5s ease-in-out infinite alternate; }
.fx-hero-go .stage-word { animation:fxFade 1.2s .6s both; }
.fx-hero-go .cinematic-hero .hero-char-img { animation:fxChar 1.05s .22s var(--ease-out) both, fxFloat 6s 1.4s ease-in-out infinite alternate; }
.fx-hero-go .cinematic-hero .hero-eyebrow { animation:fxWipeX .7s .35s var(--ease-snap) both; }
.fx-hero-go .hero-title .hero-identity { animation:fxTrack .9s .4s var(--ease-out) both; }
.cinematic-hero .hero-title .fx-line { display:block; overflow:hidden; padding:.16em .04em .08em; margin:-.16em -.04em -.08em; }
.cinematic-hero .hero-title .fx-line { color:inherit; text-shadow:inherit; }
.cinematic-hero .hero-title .fx-ch { display:inline-block; color:inherit; margin:0; text-shadow:inherit; }
.fx-hero-go .fx-ch { animation:fxCharUp .8s var(--ease-out) both; animation-delay:calc(var(--i)*34ms + 520ms); }
.fx-hero-go .cinematic-hero .hero-desc { animation:fxUp .8s 1.05s var(--ease-out) both; }
.fx-hero-go .cinematic-hero .hero-actions { animation:fxUp .8s 1.18s var(--ease-out) both; }
.fx-hero-go .cinematic-hero .hero-art-label { animation:fxWipeX .7s 1.3s var(--ease-snap) both; }
.fx-hero-go .cinematic-hero .hero-scroll { animation:fxUp .7s 1.45s var(--ease-out) both; }
.fx-hero-go .hero-scroll span { animation:fxBob 1.6s 2.4s ease-in-out infinite; }
@keyframes fxSlab { from { clip-path:inset(100% 0 0 0); } to { clip-path:inset(0); } }
@keyframes fxChar { from { opacity:0; transform:translate(70px,36px) scale(1.07); filter:brightness(2.2); } 60% { opacity:1; } to { opacity:1; transform:none; } }
@keyframes fxFloat { from { transform:translateY(0); } to { transform:translateY(-9px); } }
@keyframes fxWipeX { from { clip-path:inset(0 100% 0 0); opacity:1; } to { clip-path:inset(0); opacity:1; } }
@keyframes fxTrack { from { opacity:0; letter-spacing:.9em; } to { opacity:1; letter-spacing:.23em; } }
@keyframes fxUp { from { opacity:0; transform:translateY(26px); } to { opacity:1; transform:none; } }
@keyframes fxBob { 50% { transform:translateY(5px); } }
/* Glitch hit on PURPOSE. */
.fx-hero-go .hero-title > span:last-child { animation:fxGlitch 6.5s 2.6s steps(1) infinite; }
@keyframes fxGlitch {
  0%,91%,100% { transform:none; text-shadow:0 4px 40px #ff465515; clip-path:none; }
  92% { transform:translateX(-5px) skewX(-8deg); text-shadow:5px 0 #42e1dc, -5px 0 #fff; clip-path:inset(0 0 55% 0); }
  94% { transform:translateX(6px) skewX(6deg); text-shadow:-6px 0 #42e1dc, 4px 0 #fff; clip-path:inset(45% 0 0 0); }
  96% { transform:translateX(-2px); text-shadow:2px 0 #42e1dc; clip-path:none; }
}
/* Pointer and scroll parallax (values set by fx.js). */
@media (min-width:769px) {
  html.fx .cinematic-hero { --px:0; --py:0; --sy:0; }
  html.fx .cinematic-hero .hero-char-wrap { translate:calc(var(--px)*-16px) calc(var(--py)*-9px + var(--sy)*70px); }
  html.fx .hero-stage { translate:calc(var(--px)*9px) calc(var(--py)*5px + var(--sy)*-30px); }
  html.fx .cinematic-hero .hero-content { translate:0 calc(var(--sy)*-46px); opacity:calc(1 - var(--sy)*1.15); }
  html.fx .stage-word { translate:0 calc(var(--sy)*-160px); }
}
.fx-embers { position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }

/* ---------- Crosshair cursor follower (mouse only) ---------- */
.fx-cursor { position:fixed; left:0; top:0; z-index:10001; width:34px; height:34px; margin:-17px 0 0 -17px; pointer-events:none; opacity:0; transition:opacity .25s; }
.fx-cursor.on { opacity:1; }
.fx-cursor i { position:absolute; inset:0; border:1px solid var(--xhair); border-radius:50%; transition:scale .22s var(--ease-out), border-color .2s, rotate .4s var(--ease-out); }
.fx-cursor i::before, .fx-cursor i::after { content:""; position:absolute; background:var(--xhair); transition:background .2s; }
.fx-cursor i::before { left:50%; top:-5px; bottom:-5px; width:1px; translate:-50% 0; mask:linear-gradient(#000 0 8px,transparent 8px calc(100% - 8px),#000 calc(100% - 8px)); }
.fx-cursor i::after { top:50%; left:-5px; right:-5px; height:1px; translate:0 -50%; mask:linear-gradient(90deg,#000 0 8px,transparent 8px calc(100% - 8px),#000 calc(100% - 8px)); }
.fx-cursor.hot i { scale:1.55; rotate:45deg; border-color:var(--red); }
.fx-cursor.hot i::before, .fx-cursor.hot i::after { background:var(--red); }
.fx-cursor.down i { scale:.7; }

/* ---------- Scroll reveals ---------- */
html.fx .fx-pre { opacity:0; }
html.fx .fx-title { width:fit-content; max-width:100%; align-self:flex-start; background:linear-gradient(var(--red),var(--red)) no-repeat right center / 0% 100%; }
html.fx .fx-title.fx-center { margin-inline:auto; align-self:center; }
html.fx .fx-title.fx-in { animation:fxTitle 1.05s var(--ease-snap) both, fxHideText .5s linear backwards; }
@keyframes fxTitle {
  0% { clip-path:inset(0 100% 0 0); background-size:100% 100%; }
  44% { clip-path:inset(0 0 0 0); background-size:100% 100%; }
  100% { clip-path:inset(0 0 0 0); background-size:0% 100%; }
}
@keyframes fxHideText { from, to { -webkit-text-fill-color:transparent; } }

/* ---------- Cards: tilt and glare ---------- */
.fx-tilt { }
.fx-glare { position:absolute; inset:0; z-index:5; pointer-events:none; border-radius:inherit; opacity:0; transition:opacity .3s; background:radial-gradient(420px circle at var(--gx,50%) var(--gy,50%), #ffffff1c, transparent 55%); }
.fx-glare::after { content:""; position:absolute; inset:0; border-radius:inherit; padding:1px; background:radial-gradient(260px circle at var(--gx,50%) var(--gy,50%), var(--red), transparent 60%); -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite:xor; mask-composite:exclude; }
.fx-has-glare { position:relative; }
.fx-has-glare:hover > .fx-glare { opacity:1; }

/* ---------- Ticker bands ---------- */
.fx-ticker { position:relative; z-index:2; overflow:hidden; padding:20px 0; margin:-6px 0; pointer-events:none; }
.fx-ticker .fx-band { background:var(--red); color:#0a1017; transform:rotate(-1.2deg) scale(1.03); padding:12px 0 8px; box-shadow:0 12px 40px #ff465530; }
.fx-ticker.alt .fx-band { background:#0a1017; color:transparent; -webkit-text-stroke:1px var(--red); transform:rotate(1.2deg) scale(1.03); border-block:1px solid #ff465566; box-shadow:none; }
.fx-ticker .fx-track { display:flex; width:max-content; font:700 30px/1 var(--font-display); letter-spacing:.06em; white-space:nowrap; }
.fx-ticker .fx-track span { padding-right:.6em; }
.fx-ticker .fx-track span::after { content:"✦"; padding-left:.6em; font-size:.6em; vertical-align:.2em; }

/* ---------- Section rail (desktop) ---------- */
.fx-rail { position:fixed; right:16px; top:50%; z-index:60; translate:0 -50%; display:none; flex-direction:column; gap:9px; align-items:flex-end; opacity:0; transition:opacity .4s; }
.fx-rail.on { opacity:1; }
.fx-rail a { display:flex; align-items:center; gap:8px; height:14px; color:#acb8c5; text-decoration:none; font:12px var(--font-mono); letter-spacing:.1em; }
.fx-rail a::after { content:""; width:14px; height:2px; background:#526171; transition:width .35s var(--ease-out), background .2s; }
.fx-rail a span { opacity:0; translate:8px 0; transition:opacity .25s, translate .35s var(--ease-out); white-space:nowrap; background:#0a1017e6; padding:2px 6px; }
.fx-rail a:hover span, .fx-rail a:focus-visible span { opacity:1; translate:0; }
.fx-rail a.cur { color:#f1eee8; }
.fx-rail a.cur::after { width:34px; background:var(--red); }
.fx-rail a.cur b { color:var(--red); }
.fx-rail a b { font-weight:400; }
@media (min-width:1280px) { html.fx .fx-rail { display:flex; } }

/* ---------- Sticky nav (desktop) ---------- */
@media (min-width:901px) {
  html.fx .glitch-nav { position:sticky; top:0; z-index:90; transition:translate .45s var(--ease-out), background .3s, box-shadow .3s; }
  /* No size change when stuck: a sticky bar that changes height mid scroll crashed Chrome, Brave and Edge (crash log, 11 Nov 2026). */
  html.fx .glitch-nav.fx-stuck { background:#0a1017f5; box-shadow:0 10px 30px #0008; }
  html.fx .glitch-nav.fx-hide { translate:0 -105%; }
  html.fx main > section { scroll-margin-top:76px; }
}

/* ---------- Buttons ---------- */
html.fx :is(.btn-primary,.glitch-nav .nav-links .cta-button) { background-image:linear-gradient(110deg,transparent 42%,#ffffff8c 50%,transparent 58%); background-size:260% 100%; background-position:130% 0; background-repeat:no-repeat; transition:background-position .7s var(--ease-out), translate .25s var(--ease-out), box-shadow .2s; }
html.fx :is(.btn-primary,.glitch-nav .nav-links .cta-button):hover { background-position:-30% 0; }
@keyframes fxPulse { 0% { filter:drop-shadow(0 0 0 #ff4655aa); } 60%,100% { filter:drop-shadow(0 0 22px #ff465500); } }

/* ---------- Small hits ---------- */
html.fx .champ-card h3 { background:linear-gradient(100deg,var(--gold) 0 40%,#fff6d8 50%,var(--gold) 60% 100%) 0 0 / 250% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; animation:fxShimmer 4.5s linear infinite; }
@keyframes fxShimmer { from { background-position:120% 0; } to { background-position:-130% 0; } }
html.fx .agent-token.dead .kill-mark { transform-box:fill-box; transform-origin:center; animation:fxKill .4s var(--ease-out) both; }
@keyframes fxKill { from { transform:scale(3.2) rotate(-40deg); opacity:0; } to { transform:none; opacity:1; } }
.crosshair-preview.fx-fire { animation:fxFire .32s var(--ease-out); }
@keyframes fxFire { 0% { transform:scale(1.35) translateY(-5px); filter:brightness(2.2); } 100% { transform:none; filter:none; } }
html.fx .player-card img, html.fx .player-initial { transition:box-shadow .3s, scale .35s var(--ease-out); }
html.fx .player-card:hover :is(img,.player-initial) { scale:1.08; box-shadow:0 0 0 2px #0d141c, 0 0 0 4px var(--red), 0 0 26px #ff465588; }
html.fx .status-dot.pulse { box-shadow:0 0 0 0 #42e1dc; }

/* ---------- Lite level (after one crash): keep the cheap CSS motion, drop the heavy parts ---------- */
html.fx-lite .hero-title > span:last-child { animation:none; }
html.fx-lite .cinematic-hero .hero-char-img { animation:fxUp .9s .22s var(--ease-out) both; }
html.fx-lite .champ-card h3 { animation:none; background:none; color:var(--gold); }
html.fx-lite .fx-title.fx-in { animation:fxUp .7s var(--ease-out) both; }
html.fx-lite .fx-title { background:none; }
html.fx-lite .cinematic-hero .hero-char-wrap, html.fx-lite .hero-stage, html.fx-lite .cinematic-hero .hero-content, html.fx-lite .stage-word { translate:none; opacity:1; }

/* Crash test steps 5 to 7: switch full mode pieces to their lite form, one group at a time. */
html.fx-t5 .fx-title.fx-in { animation:fxUp .7s var(--ease-out) both; }
html.fx-t5 .fx-title { background:none; }
html.fx-t6 .cinematic-hero .hero-char-wrap, html.fx-t6 .hero-stage, html.fx-t6 .cinematic-hero .hero-content, html.fx-t6 .stage-word { translate:none; opacity:1; }
html.fx-t7 .hero-title > span:last-child { animation:none; }
html.fx-t7 .cinematic-hero .hero-char-img { animation:fxUp .9s .22s var(--ease-out) both; }
html.fx-t7 .champ-card h3 { animation:none; background:none; color:var(--gold); }
