/* ==========================================================================
   The Freedom Games
   Palette sampled from the client's own footage. Ember accent = re entry fire.
   ========================================================================== */

:root{
  --canvas:#05050c;
  --panel:#0a0d1c;
  --panel-2:#111634;
  --line:#232b5e;
  --accent:#6f9bff;
  --accent-hover:#9dbcff;
  --accent-muted:rgba(111,155,255,.16);
  --glow:#1f54f0;
  --violet:#a97cff;
  --steel:#93a4d6;
  --text-primary:#f0f3ff;
  --text-secondary:#a3b0d8;

  --display:"Agency FB","Big Shoulders Display","Saira Condensed",system-ui,sans-serif;
  --body:"Manrope",system-ui,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,monospace;

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --tshadow:0 1px 2px rgba(2,2,8,.95),0 3px 12px rgba(2,2,8,.78),0 10px 44px rgba(2,2,8,.8);
  --cut:14px;
  --pad:clamp(20px,5vw,72px);
  --maxw:1240px;
  /* how the hero dissolves into the page: solid, then away over the last quarter */
  --hero-fade:linear-gradient(to bottom,#000 0%,#000 74%,rgba(0,0,0,.72) 85%,rgba(0,0,0,.28) 94%,transparent 100%);
}

*,*::before,*::after{box-sizing:border-box}

html,body{
  overflow-x:hidden;
  overflow-x:clip;
  margin:0;
  padding:0;
}

html{scroll-behavior:smooth}

body{
  background:var(--canvas);
  color:var(--text-primary);
  font-family:var(--body);
  font-size:clamp(15px,.4vw + 14px,17px);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  animation:page-in 1s var(--ease-out) both;
}
@keyframes page-in{from{opacity:0}to{opacity:1}}

h1,h2,h3{font-family:var(--display);font-weight:700;line-height:1.02;letter-spacing:.005em;margin:0}
p{margin:0}
a{color:inherit}
img{max-width:100%;height:auto;display:block}

.skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--accent);color:#050a1c;padding:12px 18px;font-weight:700;border-radius:0 0 var(--cut) 0;
}
.skip:focus{left:0}

:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

/* ============ the environment: the room the whole site sits in ========== */
.env{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
body.hero-lock .env-lit,body.hero-lock .env-grain,body.hero-lock .env-scan{display:none}

/* deep colour fields, slowly breathing */
.env-glow{
  position:absolute;inset:-12%;
  background:
    radial-gradient(52% 40% at 12% 4%,rgba(31,84,240,.30),transparent 66%),
    radial-gradient(46% 36% at 90% 26%,rgba(124,67,232,.26),transparent 68%),
    radial-gradient(58% 42% at 66% 96%,rgba(0,150,210,.22),transparent 70%),
    radial-gradient(38% 32% at 32% 60%,rgba(31,84,240,.20),transparent 72%);
  animation:glow-breathe 84s ease-in-out -20s infinite;
}
@keyframes glow-breathe{0%,100%{opacity:.85;transform:scale(1)}50%{opacity:1;transform:scale(1.07)}}

/* stadium light shafts crossing the page */
.env-beams{
  position:absolute;inset:-40% -20%;
  background:
    linear-gradient(104deg,transparent 30%,rgba(31,84,240,.14) 36%,rgba(31,84,240,.02) 41%,transparent 46%),
    linear-gradient(104deg,transparent 52%,rgba(124,67,232,.12) 58%,rgba(124,67,232,.02) 63%,transparent 68%),
    linear-gradient(104deg,transparent 74%,rgba(145,217,254,.10) 79%,transparent 86%);
  animation:beam-drift 48s ease-in-out -12s infinite;
}
@keyframes beam-drift{0%,100%{transform:translate3d(-6%,0,0)}50%{transform:translate3d(6%,0,0)}}

/* the field grid: a heads up display you are standing inside */
.env-grid{
  position:absolute;inset:-20%;
  background-image:
    linear-gradient(rgba(31,84,240,.07) 1px,transparent 1px),
    linear-gradient(90deg,rgba(31,84,240,.07) 1px,transparent 1px);
  background-size:120px 120px,120px 120px;
  -webkit-mask-image:radial-gradient(105% 72% at 50% 42%,transparent 4%,#000 88%);
  mask-image:radial-gradient(105% 72% at 50% 42%,transparent 4%,#000 88%);
  animation:grid-drift 110s linear -30s infinite;
}
@keyframes grid-drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(120px,120px,0)}}

/* ---- the board: circuit traces in the crest's own colours ---- */
.env-circuit{
  position:absolute;inset:-10%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27240%27%20height%3D%27240%27%20viewBox%3D%270%200%20240%20240%27%3E%3Cg%20fill%3D%27none%27%20stroke%3D%27rgba(43%2C110%2C255%2C.20)%27%20stroke-width%3D%271.4%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M0%2048%20H72%20L96%2072%20H168%20M168%2072%20V144%20H240%27%2F%3E%3Cpath%20d%3D%27M48%200%20V96%20L72%20120%20V240%27%2F%3E%3Cpath%20d%3D%27M240%20192%20H144%20L120%20168%20H24%20V240%27%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%27none%27%20stroke%3D%27rgba(139%2C92%2C246%2C.16)%27%20stroke-width%3D%271.4%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M96%200%20V24%20H144%20V96%20H216%20V0%27%2F%3E%3Cpath%20d%3D%27M0%20120%20H24%20L48%20144%20H96%20V216%20H168%27%2F%3E%3Cpath%20d%3D%27M192%20240%20V204%20L216%20180%20H240%27%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%27rgba(77%2C150%2C255%2C.30)%27%3E%3Ccircle%20cx%3D%2772%27%20cy%3D%2748%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27168%27%20cy%3D%2772%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%2748%27%20cy%3D%2796%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27120%27%20cy%3D%27168%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27144%27%20cy%3D%2724%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%27216%27%20cy%3D%2796%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%2796%27%20cy%3D%27216%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%2724%27%20cy%3D%27120%27%20r%3D%273%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  background-size:300px 300px;
  animation:board-drift 150s linear -40s infinite;
}
@keyframes board-drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(-300px,300px,0)}}

/* the same board, lit, revealed in patches: power moving around it */
.env-lit{
  position:absolute;inset:-10%;will-change:opacity;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27240%27%20height%3D%27240%27%20viewBox%3D%270%200%20240%20240%27%3E%3Cg%20fill%3D%27none%27%20stroke%3D%27rgba(90%2C150%2C255%2C.85)%27%20stroke-width%3D%271.6%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M0%2048%20H72%20L96%2072%20H168%20M168%2072%20V144%20H240%27%2F%3E%3Cpath%20d%3D%27M48%200%20V96%20L72%20120%20V240%27%2F%3E%3Cpath%20d%3D%27M240%20192%20H144%20L120%20168%20H24%20V240%27%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%27none%27%20stroke%3D%27rgba(167%2C124%2C255%2C.75)%27%20stroke-width%3D%271.6%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M96%200%20V24%20H144%20V96%20H216%20V0%27%2F%3E%3Cpath%20d%3D%27M0%20120%20H24%20L48%20144%20H96%20V216%20H168%27%2F%3E%3Cpath%20d%3D%27M192%20240%20V204%20L216%20180%20H240%27%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%27rgba(150%2C200%2C255%2C1)%27%3E%3Ccircle%20cx%3D%2772%27%20cy%3D%2748%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27168%27%20cy%3D%2772%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%2748%27%20cy%3D%2796%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27120%27%20cy%3D%27168%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27144%27%20cy%3D%2724%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%27216%27%20cy%3D%2796%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%2796%27%20cy%3D%27216%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%2724%27%20cy%3D%27120%27%20r%3D%273%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  background-size:300px 300px;
  opacity:0;
  animation:board-drift 150s linear -40s infinite,lit-pulse 14s ease-in-out infinite;
}
.env-lit-a{
  -webkit-mask-image:radial-gradient(circle 30% at 18% 26%,#000 0%,transparent 62%);
  mask-image:radial-gradient(circle 30% at 18% 26%,#000 0%,transparent 62%);
  animation-delay:-40s,0s;
}
.env-lit-b{
  -webkit-mask-image:radial-gradient(circle 26% at 76% 58%,#000 0%,transparent 60%);
  mask-image:radial-gradient(circle 26% at 76% 58%,#000 0%,transparent 60%);
  animation-delay:-40s,-4.7s;
}
.env-lit-c{
  -webkit-mask-image:radial-gradient(circle 28% at 44% 88%,#000 0%,transparent 62%);
  mask-image:radial-gradient(circle 28% at 44% 88%,#000 0%,transparent 62%);
  animation-delay:-40s,-9.3s;
}
@keyframes lit-pulse{
  0%,72%,100%{opacity:0}
  14%{opacity:.5}
  34%{opacity:.32}
  52%{opacity:.46}
}

.env-stars{
  position:absolute;inset:-10%;
  background-image:
    radial-gradient(1.5px 1.5px at 12% 22%,rgba(214,240,255,.62),transparent 60%),
    radial-gradient(1.2px 1.2px at 78% 12%,rgba(214,240,255,.48),transparent 60%),
    radial-gradient(1.6px 1.6px at 34% 68%,rgba(190,225,245,.42),transparent 60%),
    radial-gradient(1.1px 1.1px at 62% 82%,rgba(214,240,255,.44),transparent 60%),
    radial-gradient(1.3px 1.3px at 88% 54%,rgba(190,225,245,.38),transparent 60%),
    radial-gradient(1.1px 1.1px at 22% 88%,rgba(214,240,255,.34),transparent 60%),
    radial-gradient(1.4px 1.4px at 52% 34%,rgba(190,225,245,.34),transparent 60%),
    radial-gradient(1.2px 1.2px at 6% 52%,rgba(214,240,255,.3),transparent 60%),
    radial-gradient(1.3px 1.3px at 94% 74%,rgba(190,225,245,.3),transparent 60%);
  animation:star-drift 140s linear -40s infinite;
}
@keyframes star-drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(-2%,3%,0)}}

/* motes lifting through the field */
.env-motes{
  position:absolute;inset:0;
  background-image:
    radial-gradient(2px 2px at 20% 100%,rgba(111,155,255,.6),transparent 60%),
    radial-gradient(1.6px 1.6px at 66% 100%,rgba(157,188,255,.5),transparent 60%),
    radial-gradient(1.8px 1.8px at 44% 100%,rgba(31,84,240,.45),transparent 60%),
    radial-gradient(1.5px 1.5px at 84% 100%,rgba(169,124,255,.4),transparent 60%);
  animation:mote-rise 90s linear -30s infinite;
}
@keyframes mote-rise{from{transform:translate3d(0,0,0)}to{transform:translate3d(3%,-120vh,0)}}

/* screen lines and grain, so it reads as a display rather than paper */
.env-scan{
  position:absolute;inset:0;
  background:repeating-linear-gradient(to bottom,rgba(111,155,255,.05) 0 1px,transparent 1px 4px);
  opacity:.55;
}
.env-grain{
  position:absolute;inset:-50%;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity:.05;
  animation:grain 6s steps(3) infinite;
}
@keyframes grain{
  0%{transform:translate3d(0,0,0)}33%{transform:translate3d(-2%,1%,0)}66%{transform:translate3d(1%,-2%,0)}100%{transform:translate3d(0,0,0)}
}

/* the edges fall away, so the middle reads as the lit part of the room */
.env-vig{
  position:absolute;inset:0;
  background:radial-gradient(ellipse 92% 76% at 50% 42%,transparent 32%,rgba(2,2,7,.66) 100%);
}

/* corner brackets, the way a game overlays its own screen */
.hud{position:fixed;inset:0;z-index:2;pointer-events:none}
.hud-c{position:absolute;width:26px;height:26px;opacity:.5}
.hud-tl{top:12px;left:12px;border-top:2px solid var(--accent);border-left:2px solid var(--accent)}
.hud-tr{top:12px;right:12px;border-top:2px solid var(--accent);border-right:2px solid var(--accent)}
.hud-bl{bottom:12px;left:12px;border-bottom:2px solid var(--accent);border-left:2px solid var(--accent)}
.hud-br{bottom:12px;right:12px;border-bottom:2px solid var(--accent);border-right:2px solid var(--accent)}
@media (max-width:720px){.hud-c{width:16px;height:16px;opacity:.4}}

/* ============ nav ============ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:60;
  display:flex;align-items:center;gap:24px;
  padding:14px var(--pad);
  background:linear-gradient(to bottom,rgba(5,5,12,.86),rgba(5,5,12,0));
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;flex:0 0 auto}
.brand-mark{width:auto;height:34px;flex:0 0 auto;filter:drop-shadow(0 0 12px rgba(31,84,240,.55))}
.bm-shield{fill:rgba(31,84,240,.10);stroke:var(--glow);stroke-width:3.4}
.bm-wing-l,.bm-wing-r{stroke:var(--violet);stroke-width:3;fill:none;stroke-linecap:round}
.bm-t,.bm-f{stroke:var(--accent);stroke-width:4.4;stroke-linecap:round}
.brand-name{font-family:var(--display);font-weight:700;font-size:1.18rem;letter-spacing:.03em;white-space:nowrap}
.nav-links{display:flex;gap:26px;margin-left:auto;font-size:.88rem;color:var(--text-secondary)}
.nav-links a{text-decoration:none;transition:color .3s var(--ease)}
.nav-links a:hover{color:var(--text-primary)}
.nav-cta{margin-left:8px}
.wa{width:17px;height:17px;fill:currentColor;flex:0 0 auto}

/* ============ buttons ============ */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-family:var(--display);font-weight:700;font-size:1.05rem;letter-spacing:.03em;
  padding:13px 22px;text-decoration:none;cursor:pointer;border:0;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
  transition:background-color .35s var(--ease),color .35s var(--ease),transform .35s var(--ease),box-shadow .35s var(--ease);
  text-shadow:none;
}
.btn-accent{background:var(--accent);color:#050a1c;box-shadow:0 10px 34px rgba(111,155,255,.24)}
.btn-accent:hover{background:var(--accent-hover);transform:translateY(-2px);box-shadow:0 14px 40px rgba(111,155,255,.32)}
.btn-ghost{background:rgba(143,163,200,.07);color:var(--text-primary);box-shadow:inset 0 0 0 1px rgba(143,163,200,.34)}
.btn-ghost:hover{background:rgba(143,163,200,.14);transform:translateY(-2px)}

/* ============ HERO ============ */
.hero{position:relative;height:620vh;z-index:1}
.stage{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;background:var(--canvas)}
.poster{
  position:absolute;inset:0;background-size:cover;background-position:center;
  transform:scale(1.02);
  transition:opacity .8s var(--ease-out);
}
#hero-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .7s var(--ease-out);
  will-change:transform;transform:translateZ(0);
}
.stage.video-ready #hero-video{opacity:1}
.stage.video-ready .poster{opacity:0}
.stage.video-failed #hero-video{display:none}
.scrim{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 120% 90% at 50% 45%,rgba(5,18,23,0) 34%,rgba(5,18,23,.64) 100%);
}

/* the curve the hero dissolves on, and a little light where it meets the page */
.stage::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:30%;pointer-events:none;z-index:3;
  background:
    linear-gradient(to bottom,rgba(31,84,240,0) 0%,rgba(31,84,240,.06) 55%,rgba(31,84,240,0) 100%),
    linear-gradient(to bottom,rgba(5,5,12,0) 0%,rgba(5,5,12,.35) 46%,rgba(5,5,12,.82) 76%,var(--canvas) 100%);
}

/* the loading ring */
.ring{position:absolute;right:26px;bottom:26px;width:34px;height:34px;color:var(--accent);transform:rotate(-90deg);transition:opacity .5s var(--ease)}
.ring-track{stroke:rgba(238,242,251,.16)}
.stage.video-ready .ring{opacity:0}
.cue{position:absolute;left:50%;bottom:22px;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:7px;color:var(--text-secondary);font-family:var(--mono);font-size:.66rem;letter-spacing:.22em;text-transform:uppercase;text-shadow:var(--tshadow);transition:opacity .55s var(--ease)}
.cue.cue-off{opacity:0}
.cue i{display:block;width:1px;height:26px;background:linear-gradient(to bottom,var(--accent),transparent);animation:cue-fall 2.6s var(--ease) -.6s infinite}
@keyframes cue-fall{0%{transform:scaleY(.2);transform-origin:top;opacity:0}40%{opacity:1}100%{transform:scaleY(1);transform-origin:top;opacity:0}}

/* ---- caption bands ---- */
.bands{position:absolute;inset:0}
.band{
  position:absolute;inset:0;opacity:0;pointer-events:none;
  display:flex;flex-direction:column;justify-content:center;
  padding:0 var(--pad);
  text-shadow:var(--tshadow);
}
/* The reading lane. Text lives on the left, the controller keeps the centre,
   so the scrim is directional: deep where the words are, gone by mid frame. */
.band::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  opacity:calc(.3 + .7*var(--k,1));
  background:linear-gradient(100deg,
    rgba(3,14,18,var(--sa,.86)) 0%,
    rgba(3,14,18,calc(var(--sa,.86) * .94)) 24%,
    rgba(3,14,18,calc(var(--sa,.86) * .58)) 41%,
    rgba(3,14,18,0) 63%);
}
.band>*{position:relative;z-index:1}
.band .btn{text-shadow:none}
.band.ll{justify-content:flex-end;padding-bottom:clamp(64px,13vh,140px);align-items:flex-start}
.band.ul{justify-content:flex-start;padding-top:clamp(90px,15vh,170px);align-items:flex-start}
.band.cl{justify-content:center;align-items:flex-start}
/* the lane concentrates vertically around each band's own words */
.band.ll::before{-webkit-mask-image:linear-gradient(to bottom,transparent 6%,#000 44%,#000 100%);mask-image:linear-gradient(to bottom,transparent 6%,#000 44%,#000 100%)}
.band.ul::before{-webkit-mask-image:linear-gradient(to top,transparent 6%,#000 44%,#000 100%);mask-image:linear-gradient(to top,transparent 6%,#000 44%,#000 100%)}
.band.cl::before{-webkit-mask-image:linear-gradient(to bottom,transparent 0%,#000 20%,#000 82%,transparent 100%);mask-image:linear-gradient(to bottom,transparent 0%,#000 20%,#000 82%,transparent 100%)}

.line{
  font-family:var(--display);font-weight:700;line-height:1.06;letter-spacing:-.015em;
  font-size:clamp(2rem,4vw,3.4rem);
  max-width:17ch;
}
.line.big{font-size:clamp(2.5rem,5.4vw,4.5rem);max-width:13ch}
.line.huge{font-size:clamp(2.9rem,6.4vw,5.3rem);max-width:11ch}
.line.trip{font-size:clamp(1.8rem,3.3vw,2.7rem);max-width:16ch}
.kicker{font-family:var(--mono);font-size:.7rem;letter-spacing:.3em;color:var(--steel);margin-bottom:18px}
.chip{
  display:inline-block;padding:7px 13px;
  background:rgba(5,5,12,.55);border:1px solid rgba(143,163,200,.3);border-radius:10px;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  text-shadow:0 1px 3px rgba(2,2,8,.85);
}
.band.settle{--ks:clamp(0,(var(--k,0) - .55)*3,1);--kb:clamp(0,(var(--k,0) - .72)*4,1)}
.settle .sub{margin-top:20px;font-size:clamp(.95rem,1.1vw,1.05rem);color:var(--text-primary);opacity:var(--ks,0);max-width:33ch}
.settle .row{margin-top:26px;opacity:var(--kb,0);transform:translateY(calc((1 - var(--kb,0)) * 12px))}
.row{display:flex;flex-wrap:wrap;gap:12px}

/* split spans */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.vis{display:block}
.w{display:inline-block;white-space:pre}
.c{display:inline-block;white-space:pre}

/* entrance: approach from depth (words grow in) */
[data-entrance="depth"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.6,1);
  opacity:var(--kc);
  transform:scale(calc(.8 + .2*var(--kc))) translateY(calc((1 - var(--kc))*14px));
}
/* entrance: word punch with overshoot */
[data-entrance="punch"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*3,1);
  --ks2:clamp(0,(var(--k,0) - var(--th,0) - var(--sd,.1))*var(--ss,3.2),1);
  opacity:var(--kc);
  transform:scale(calc(.6 + (.4 + var(--ov,.12))*var(--kc) - var(--ov,.12)*var(--ks2)));
}
[data-entrance="punch"] .w.em{--ov:.24;--sd:.16;--ss:2.6}
/* entrance: grid snap align (chars slide in horizontally, in reading order) */
[data-entrance="grid"] .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);
  opacity:var(--kc);
  transform:translateX(calc((1 - var(--kc))*var(--jx,0px)));
}
/* entrance: scatter (chars fly in from seeded offsets) */
[data-entrance="scatter"] .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.6,1);
  opacity:var(--kc);
  transform:translate(calc((1 - var(--kc))*var(--jx,0px)),calc((1 - var(--kc))*var(--jy,0px)))
            rotate(calc((1 - var(--kc))*var(--jr,0deg)));
}
/* entrance: word by word rise into a staged settle */
[data-entrance="rise"] .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.6,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc))*26px));
}
[data-entrance="rise"] .kicker{opacity:clamp(0,var(--k,0)*3,1)}

/* ---- the static hero (five gates) ---- */
.static{display:none}
@media (prefers-reduced-motion: reduce){
  .hero{height:auto;min-height:100svh}
  .stage{display:none}
  .static{
    display:flex;flex-direction:column;justify-content:flex-start;
    min-height:100svh;position:relative;background:var(--canvas);
  }
  .static-media{
    position:relative;width:100%;height:min(74vw,52svh);flex:0 0 auto;
    background-image:url("hero-ending.jpg");background-size:cover;background-position:50% 46%;
  }
  .static-media::after{
    content:"";position:absolute;inset:0;
    background:linear-gradient(to bottom,rgba(5,5,12,.55) 0%,rgba(5,5,12,.12) 30%,rgba(5,5,12,.72) 74%,rgba(5,5,12,.94) 92%,var(--canvas) 100%);
  }
  .static-inner{position:relative;padding:clamp(18px,3vh,30px) var(--pad) clamp(40px,8vh,72px);width:100%;max-width:var(--maxw);margin:-8vw auto 0}
  .static-h{font-size:clamp(2.8rem,12.5vw,4.2rem);margin:16px 0 0;text-shadow:var(--tshadow)}
  .static-sub{margin-top:16px;color:var(--text-primary);max-width:34ch;text-shadow:0 1px 8px rgba(2,2,8,.9)}
  .static .row{margin-top:26px}
  .static-foot{margin-top:18px;font-family:var(--mono);font-size:.72rem;letter-spacing:.06em;color:var(--steel)}
}

/* ============ the body of the site ============ */
.body-wrap{position:relative;z-index:1;background:linear-gradient(to bottom,var(--canvas) 0%,rgba(5,5,12,.72) 3%,rgba(5,5,12,.44) 9%,rgba(5,5,12,.4) 46%,rgba(5,5,12,.46) 100%)}

/* signature: the entry trail, running the gutter and threading every section node */
.trail{
  position:absolute;top:0;height:100%;width:9px;z-index:0;pointer-events:none;opacity:.85;
  left:calc(50% - min(var(--maxw),100%) / 2 + var(--pad) * .6);
}
.trail-path{
  stroke:var(--accent);stroke-width:1.4px;vector-effect:non-scaling-stroke;
  stroke-dasharray:var(--len,2400);stroke-dashoffset:var(--off,2400);
  filter:drop-shadow(0 0 7px rgba(111,155,255,.55));
  transition:stroke-dashoffset .28s linear;
}

.body-wrap section{position:relative;z-index:1;max-width:var(--maxw);margin:0 auto;padding:clamp(58px,8vh,104px) var(--pad)}
/* anchor links must not park a heading under the fixed nav */
[id]{scroll-margin-top:100px}

.sec-head{position:relative;margin-bottom:clamp(30px,5vh,54px);max-width:70ch}
.sec-head::after{content:"";position:absolute;inset:-18px -26px -14px -26px;z-index:-1;background:radial-gradient(ellipse 78% 120% at 22% 50%,rgba(5,5,12,.82),rgba(5,5,12,0) 78%)}
/* the trail's nodes: one per section, lighting as the descent reaches it */
.sec-head::before{
  content:"";position:absolute;left:calc(var(--pad) * -.4);top:.55em;width:9px;height:9px;border-radius:50%;
  background:var(--panel-2);box-shadow:0 0 0 1px var(--line);
  transition:background-color .7s var(--ease) calc(var(--d,0s) + .25s),box-shadow .7s var(--ease) calc(var(--d,0s) + .25s);
}
.sec-head.in::before{background:var(--accent);box-shadow:0 0 0 1px rgba(111,155,255,.45),0 0 16px rgba(111,155,255,.6)}
.eyebrow{font-family:var(--mono);font-size:.7rem;letter-spacing:.26em;color:var(--accent);margin-bottom:14px}
.sec-h{font-size:clamp(2rem,4.2vw,3.4rem)}
.sec-sub{margin-top:14px;color:var(--text-secondary);max-width:56ch}

/* reveal choreography */
.reveal{transition:opacity .8s var(--ease-out) var(--d,0s),transform .8s var(--ease-out) var(--d,0s)}
.js .reveal{opacity:0;transform:translateY(20px)}
.reveal.in{opacity:1;transform:none}
.reveal.done{--d:0s !important}

/* A. promises */
.promises{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.4vw,32px);padding-top:clamp(60px,9vh,110px)}
.promise{
  background:linear-gradient(160deg,rgba(10,13,28,.95) 0%,rgba(17,22,52,.95) 100%);backdrop-filter:blur(7px);
  border:1px solid var(--line);padding:clamp(22px,2.4vw,32px);
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
}
.promise h2{font-size:1.15rem;margin:16px 0 9px}
.promise p{color:var(--text-secondary);font-size:.94rem}
.mark{width:38px;height:38px}
.mark .d{stroke:var(--accent);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:var(--dl,140);stroke-dashoffset:var(--dl,140);
  transition:stroke-dashoffset 1.1s var(--ease-out) calc(var(--d,0s) + .18s)}
.reveal.in .mark .d{stroke-dashoffset:0}

/* B. steps */
.step-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.4vw,34px);counter-reset:s}
.step{position:relative;padding-top:26px;border-top:1px solid var(--line)}
.step::after{content:"";position:absolute;top:-1px;left:0;height:1px;width:0;background:var(--accent);transition:width 1s var(--ease-out) calc(var(--d,0s) + .1s)}
.step.in::after{width:42px}
.step-n{font-family:var(--mono);font-size:.74rem;letter-spacing:.2em;color:var(--accent)}
.step h3{font-size:1.24rem;margin:12px 0 10px}
.step p{color:var(--text-secondary);font-size:.94rem}
.step-list .step:nth-child(2){--d:.1s}
.step-list .step:nth-child(3){--d:.2s}

/* C. games */
.cur{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:22px}
/* what the row of buttons is for, said out loud rather than left to guess */
.cur-lab{font-family:var(--mono);font-size:.68rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--steel);margin-right:4px}
/* Each button carries its country's flag and the code, big enough to read
   from a normal distance. The row used to be dark pills on a dark page; now
   it is lit like the rest of the shelf's controls. */
.cur-btn{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:.94rem;font-weight:600;letter-spacing:.08em;
  background:rgba(111,155,255,.13);color:#fff;
  border:1px solid rgba(147,164,214,.85);padding:9px 14px 9px 11px;cursor:pointer;border-radius:9px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08);
  transition:color .25s var(--ease),background-color .25s var(--ease),
             border-color .25s var(--ease),box-shadow .25s var(--ease),transform .25s var(--ease);
}
.cur-btn:hover{border-color:#fff;background:rgba(111,155,255,.24);transform:translateY(-1px)}
/* the flag: a small rounded rectangle with a hairline round it so a white
   flag edge still reads on a light button */
.cur-flag{width:24px;height:16px;border-radius:3px;flex:0 0 auto;display:block;
  box-shadow:0 0 0 1px rgba(0,0,0,.35),0 1px 3px rgba(0,0,0,.4)}
.cur-btn.is-on .cur-flag{box-shadow:0 0 0 1px rgba(0,0,0,.25)}
/* the currency being shown: filled, not merely outlined, so it is obvious at a
   glance which one you are reading prices in */
.cur-btn.is-on{background:var(--accent);border-color:#fff;color:#050a1c;
  font-weight:800;box-shadow:0 8px 24px rgba(111,155,255,.55),0 0 0 3px rgba(111,155,255,.25)}
.cur-btn:focus-visible{outline:2px solid #fff;outline-offset:2px}
.cur-note{margin-top:12px;font-size:.8rem;color:var(--text-secondary)}

.game-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(16px,2vw,26px)}
/* The cards used to be skipped until they were nearly scrolled to
   (content-visibility:auto). It saved a little work at the cost of the very
   thing the shelf is judged on: a cover that was already downloaded still had
   to be laid out and decoded on the way past, so it appeared a beat late. One
   console is at most a couple of hundred cards, which is nothing to lay out in
   one go, and they are all simply there. */
.game-grid .game{contain:layout paint}
.game{
  position:relative;overflow:hidden;
  background:linear-gradient(165deg,rgba(10,13,28,.96) 0%,rgba(17,22,52,.96) 100%);
  border:1px solid var(--line);
  display:flex;flex-direction:column;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
  transition:transform .45s var(--ease),border-color .45s var(--ease),box-shadow .45s var(--ease);
}
.game:hover{transform:translateY(-4px);border-color:rgba(111,155,255,.55);box-shadow:0 18px 50px rgba(2,2,7,.7)}
.game-art{position:relative;overflow:hidden;flex:0 0 auto;background:var(--panel-2)}
.game-art img{width:100%;aspect-ratio:4 / 5;object-fit:cover;transition:transform .6s var(--ease)}
.game:hover .game-art img{transform:scale(1.035)}
.game-art::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom,rgba(5,5,12,0) 55%,rgba(5,5,12,.7) 100%)}
.game-off{
  position:absolute;top:12px;left:12px;z-index:2;
  font-family:var(--mono);font-size:.76rem;letter-spacing:.06em;
  background:var(--accent);color:#050a1c;padding:6px 10px;
  clip-path:polygon(8px 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%,0 8px);
}
.game-body{display:flex;flex-direction:column;gap:8px;padding:clamp(18px,2vw,24px);flex:1 1 auto}
.game-tag{font-family:var(--mono);font-size:.64rem;letter-spacing:.18em;color:var(--steel)}
.game-title{font-size:1.42rem;line-height:1.1}
.game-ed{font-size:.86rem;color:var(--text-secondary)}
.game-price{font-family:var(--mono);font-size:1.42rem;color:var(--accent);margin-top:auto;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.game-price .was{font-size:.92rem;color:var(--text-secondary)}
.game-meta{font-family:var(--mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--text-secondary)}
.game .btn{width:100%;margin-top:10px}
/* the wide featured slot: the biggest saving on the shelf */
.game-big{grid-column:1 / -1;flex-direction:row;align-items:stretch}
.game-big .game-art{flex:0 0 36%;max-width:330px}
.game-big .game-art img{height:100%;aspect-ratio:auto;object-fit:cover}
.game-big .game-art::after{background:linear-gradient(to right,rgba(5,5,12,0) 62%,rgba(5,5,12,.55) 100%)}
.game-big .game-body{justify-content:center;gap:10px;padding:clamp(24px,3vw,44px)}
.game-big .game-price{margin-top:14px}
.game-big .game-title{font-size:clamp(1.5rem,2.6vw,2.1rem)}
.game-big .game-price{font-size:clamp(1.6rem,2.4vw,2rem)}
.game-big .btn{width:auto;align-self:flex-start;margin-top:16px}
.game-grid .game:nth-child(3n+2){--d:.08s}
.game-grid .game:nth-child(3n+3){--d:.16s}
.games-foot{margin-top:30px;color:var(--text-secondary);font-size:.92rem}
.games-foot a{color:var(--accent);text-underline-offset:4px}

/* D. the hold moment */
.hold-sec{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,64px);align-items:center}
.hold-stage{
  display:flex;flex-direction:column;align-items:center;gap:20px;
  background:linear-gradient(180deg,rgba(17,22,52,.72) 0%,rgba(7,25,31,.95) 100%);backdrop-filter:blur(7px);
  border:1px solid var(--line);padding:30px 26px 28px;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
}
.hold-why{margin-top:22px;padding-left:18px;border-left:2px solid var(--accent-muted);color:var(--text-secondary);font-size:.94rem;max-width:44ch}
.drop-track{position:relative;width:100%;height:236px;overflow:hidden}
.drop-track::before{
  content:"";position:absolute;left:50%;top:0;width:2px;height:calc(26px + var(--h,0) * 140px);
  transform:translateX(-50%);
  background:linear-gradient(to bottom,transparent,rgba(111,155,255,.55));
  opacity:calc(.25 + var(--h,0) * .75);
}
.capsule{
  position:absolute;left:50%;top:6px;width:112px;height:auto;
  transform:translate(-50%,calc(var(--h,0) * 118px)) rotate(calc(var(--h,0) * 7deg));
  filter:drop-shadow(0 0 calc(8px + var(--h,0) * 30px) rgba(111,155,255,calc(.18 + var(--h,0)*.62)));
}
.capsule svg{width:100%;height:100%}
.capsule img{width:100%;height:auto}
.dust{
  position:absolute;left:50%;bottom:30px;width:min(300px,86%);height:84px;
  transform:translateX(-50%) scale(calc(.55 + var(--h,0)*.55));
  background:radial-gradient(ellipse 50% 62% at 50% 100%,rgba(198,186,176,.42),transparent 72%);
  opacity:calc(var(--h,0) * var(--h,0));
}
.ground{
  position:absolute;left:0;right:0;bottom:26px;height:30px;
  background:radial-gradient(ellipse 46% 120% at 50% 0%,rgba(143,163,200,.16),transparent 72%);
  border-top:1px solid rgba(143,163,200,.22);
}
.ground::after{
  content:"";position:absolute;left:50%;top:-1px;width:calc(70px + var(--h,0)*190px);height:1px;transform:translateX(-50%);
  background:linear-gradient(to right,transparent,var(--accent),transparent);opacity:var(--h,0);
  box-shadow:0 0 14px rgba(111,155,255,calc(var(--h,0)*.7));
}
.hold-btn{
  position:relative;width:104px;height:104px;border-radius:50%;border:0;cursor:pointer;
  background:rgba(17,22,52,.9);color:var(--text-primary);
  font-family:var(--display);font-weight:600;font-size:.92rem;
  display:flex;align-items:center;justify-content:center;
  box-shadow:inset 0 0 0 1px rgba(143,163,200,.3);
  transition:box-shadow .4s var(--ease),transform .3s var(--ease);
  touch-action:none;
}
.hold-btn:hover{box-shadow:inset 0 0 0 1px rgba(111,155,255,.55)}
.hold-btn:active{transform:scale(.97)}
.hold-arc{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
.ha-track{stroke:rgba(143,163,200,.2)}
.ha-fill{stroke:var(--accent)}
.hold-label{position:relative}
.hold-status{
  font-family:var(--mono);font-size:.78rem;letter-spacing:.1em;color:var(--accent);text-align:center;
  opacity:0;transform:translateY(6px);transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.hold-status.on{opacity:1;transform:none}

/* E. what you get */
.get{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(28px,4vw,64px);align-items:center}
.get-media img{
  width:100%;aspect-ratio:4 / 5;object-fit:cover;object-position:52% 45%;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
  border:1px solid var(--line);
}
.lede{color:var(--text-secondary);max-width:56ch}
.get-cards{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:26px}
.gcard{background:rgba(10,13,28,.94);backdrop-filter:blur(7px);border:1px solid var(--line);padding:20px;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut))}
.gcard p{color:var(--text-secondary);font-size:.9rem;margin-top:10px}
.tag{font-family:var(--mono);font-size:.68rem;letter-spacing:.2em;color:var(--accent)}
.get-cards .gcard:nth-child(2){--d:.09s}
.get-close{margin-top:22px;font-family:var(--display);font-weight:600;font-size:1.02rem}

/* F. faq */
.faq-list{display:grid;gap:10px;max-width:76ch}
.qa{border:1px solid var(--line);background:rgba(10,13,28,.92);backdrop-filter:blur(7px);
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut))}
.qa summary{
  list-style:none;cursor:pointer;padding:17px 22px;font-family:var(--display);font-weight:600;font-size:1.02rem;
  display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  transition:color .3s var(--ease);
}
.qa summary::-webkit-details-marker{display:none}
.qa summary::after{content:"+";font-family:var(--mono);color:var(--accent);font-size:1.1rem;flex:0 0 auto;transition:transform .35s var(--ease)}
.qa[open] summary::after{transform:rotate(45deg)}
.qa summary:hover{color:var(--violet)}
.qa-body{padding:0 22px 20px;color:var(--text-secondary);font-size:.94rem;max-width:62ch}
.faq-list .qa:nth-child(even){--d:.06s}

/* G. composer */
.cta-inner{max-width:720px}
.composer{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.field{display:flex;flex-direction:column;gap:8px}
.field-wide{grid-column:1 / -1}
label{font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;color:var(--steel);text-transform:uppercase}
.opt{text-transform:none;letter-spacing:.02em;opacity:.7}
input,textarea{
  font-family:var(--body);font-size:.98rem;color:var(--text-primary);
  background:rgba(10,13,28,.94);border:1px solid rgba(143,163,200,.34);padding:13px 15px;
  transition:border-color .3s var(--ease),background-color .3s var(--ease);
  border-radius:2px;
}
input:hover,textarea:hover{border-color:var(--steel)}
input:focus-visible,textarea:focus-visible{border-color:var(--accent);outline:2px solid var(--accent);outline-offset:1px}
textarea{resize:vertical;min-height:92px}
.btn-send{grid-column:1 / -1;justify-self:start}
.micro{grid-column:1 / -1;font-size:.8rem;color:var(--text-secondary)}
.micro.err{color:var(--accent)}

/* footer */
.foot{position:relative;z-index:1;border-top:1px solid var(--line);background:rgba(7,25,31,.7);padding:clamp(40px,6vh,64px) var(--pad) 26px}
.foot-top{max-width:var(--maxw);margin:0 auto;display:flex;flex-wrap:wrap;align-items:center;gap:18px 30px}
.foot-line{color:var(--text-secondary);font-size:.92rem}
.foot-wa{margin-left:auto;font-family:var(--mono);font-size:.95rem;color:var(--accent);text-decoration:none;transition:color .3s var(--ease)}
.foot-wa:hover{color:var(--accent-hover)}
.foot-bot{max-width:var(--maxw);margin:26px auto 0;padding-top:18px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:10px 26px;font-size:.78rem;color:var(--text-secondary)}
.foot-bot p:last-child{margin-left:auto}

/* ============ responsive ============ */
@media (max-width:1024px){
  .nav-links{display:none}
  .nav-cta{margin-left:auto}
  .promises,.step-list,.game-grid{grid-template-columns:1fr 1fr}
  .hold-sec,.get{grid-template-columns:1fr}
  .get-media{order:2}
}
@media (max-width:640px){
  .promises,.step-list,.game-grid,.composer,.get-cards{grid-template-columns:1fr}
  .nav{gap:12px}
  .brand-name{font-size:.82rem}
  .brand-mark{height:28px}
  .nav-cta{padding:11px 15px;font-size:.86rem;gap:7px}
  .static-h{font-size:clamp(2.2rem,10.5vw,3.2rem)}
  .foot-wa{margin-left:0;width:100%}
  .foot-bot p:last-child{margin-left:0}
}
@media (max-height:560px){
  .cue,.ring{display:none}
}
@media (pointer:coarse){
  .btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .cur-btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .qa summary{min-height:44px}
}

/* ============ reduced motion, honoured completely ============ */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;transition-delay:0s !important;
  }
  .reveal{opacity:1;transform:none}
  .env-grain,.env-scan{display:none}
  .env-lit{opacity:.28}
  .mark .d{stroke-dashoffset:0}
  .step::after{width:42px}
  .trail-path{stroke-dashoffset:0}
  .hold-status{opacity:1;transform:none}
  .capsule{transform:translate(-50%,150px)}
  .dust{opacity:1;transform:translateX(-50%) scale(1.1)}
  .settle .sub{opacity:1}
  .settle .row{opacity:1;transform:none}
}

/* pause every loop when the tab is hidden or the layer is off screen */
body.paused *,body.paused *::before,body.paused *::after{animation-play-state:paused !important}

/* the whole card is one link, so it must not inherit link underlines */
.game-link{display:flex;flex-direction:column;text-decoration:none;color:inherit;flex:1 1 auto}
.game-link *{text-decoration:none}
.game-link .was{text-decoration:line-through;text-decoration-thickness:1px}
.game-body{display:flex;flex-direction:column;gap:8px;padding:clamp(18px,2vw,24px);flex:1 1 auto}
.game-title,.game-tag,.game-ed,.game-meta,.game-more{display:block}
.game-price{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.game-title{font-family:var(--display);font-weight:700;letter-spacing:-.01em}
.game-more{margin-top:6px;font-size:.84rem;color:var(--accent);transition:color .3s var(--ease)}
.game-more::after{content:" \2192"}
.game:hover .game-more{color:var(--accent-hover)}
.game-cta{margin:0 clamp(18px,2vw,24px) clamp(18px,2vw,24px)}


/* ==========================================================================
   The game page
   ========================================================================== */
.page-game .body-wrap{background:linear-gradient(to bottom,rgba(5,5,12,.38),rgba(5,5,12,.48));min-height:100vh}
.page-game .body-wrap section{padding-top:clamp(96px,13vh,150px)}
.page-game .body-wrap section ~ section{padding-top:clamp(40px,6vh,72px)}

.crumb{margin-bottom:clamp(20px,3vh,34px);font-family:var(--mono);font-size:.74rem;letter-spacing:.12em}
.crumb a{color:var(--text-secondary);text-decoration:none;transition:color .3s var(--ease)}
.crumb a:hover{color:var(--accent)}
.crumb a::before{content:"\2190  "}

.gp-top{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(26px,4vw,60px);align-items:start}
.gp-art{position:relative;overflow:hidden;border:1px solid var(--line);
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut))}
.gp-art img{width:100%;aspect-ratio:4 / 5;object-fit:cover;display:block}

.gp-title{font-size:clamp(2.2rem,4.6vw,3.6rem);line-height:1;margin:6px 0 0}
.gp-ed{margin-top:8px;font-family:var(--mono);font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;color:var(--steel)}
.gp-price{display:flex;align-items:baseline;flex-wrap:wrap;gap:12px;margin-top:22px;font-family:var(--mono)}
.gp-price .now{font-size:clamp(1.9rem,3.2vw,2.6rem);color:var(--accent)}
.gp-price .was{font-size:1rem;color:var(--text-secondary);text-decoration:line-through;text-decoration-thickness:1px}
.gp-price .save{font-size:.74rem;letter-spacing:.1em;text-transform:uppercase;color:#050a1c;background:var(--accent);padding:5px 9px;
  clip-path:polygon(7px 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%,0 7px)}
.gp-buy .cur{margin-top:18px}
.gp-when{margin-top:18px;color:var(--text-primary);font-size:1rem}
.gp-cta{margin-top:20px}
.gp-buy .micro{margin-top:10px;font-size:.82rem;color:var(--text-secondary)}

.gp-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 20px;margin:30px 0 0;
  padding-top:24px;border-top:1px solid var(--line)}
.gp-facts dt{font-family:var(--mono);font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:var(--steel)}
.gp-facts dd{margin:5px 0 0;font-size:.95rem}

.gp-read{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,.65fr);gap:clamp(26px,4vw,56px);
  margin-top:clamp(44px,7vh,84px);padding-top:clamp(34px,5vh,58px);border-top:1px solid var(--line)}
.gp-feats{margin:22px 0 0;padding:0;list-style:none;display:grid;gap:12px}
.gp-feats li{position:relative;padding-left:22px;color:var(--text-secondary);font-size:.95rem}
.gp-feats li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:1px;background:var(--accent)}

.gp-get{background:rgba(10,13,28,.94);backdrop-filter:blur(7px);border:1px solid var(--line);padding:clamp(22px,2.4vw,30px);align-self:start;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut))}
.gp-get-h{font-size:1.2rem;margin-bottom:12px}
.gp-get p{color:var(--text-secondary);font-size:.92rem}
/* two paragraphs of explanation ran together as one wall; give them air */
.gp-get p + p{margin-top:10px}
.gp-get-line{margin-top:12px}
.gp-get .btn{margin-top:18px;width:100%}

.gp-missing{text-align:left}
.gp-missing .row{margin-top:26px}

@media (max-width:900px){
  .gp-top,.gp-read{grid-template-columns:1fr}
  .gp-art{max-width:420px}
}
@media (max-width:520px){
  .gp-facts{grid-template-columns:1fr}
}


/* ==========================================================================
   Section choreography: each one announces itself differently
   ========================================================================== */

/* every heading draws its own charge line */
.sec-h{position:relative}
.sec-head .sec-h::after{
  content:"";position:absolute;left:0;bottom:-12px;height:2px;width:min(180px,60%);
  background:linear-gradient(to right,var(--accent),rgba(111,155,255,0));
  transform:scaleX(0);transform-origin:left;
  transition:transform .9s var(--ease-out) calc(var(--d,0s) + .18s);
}
.sec-head.in .sec-h::after{transform:scaleX(1)}

/* A. the promises rise and settle, one after the other */
.promises.in .promise{animation:card-rise .85s var(--ease-out) both}
.promises.in .promise:nth-child(2){animation-delay:.11s}
.promises.in .promise:nth-child(3){animation-delay:.22s}
@keyframes card-rise{
  from{opacity:0;transform:translateY(30px) scale(.975)}
  to{opacity:1;transform:none}
}

/* B. the steps slide in from the left, in order */
.step-list .step{transform:translateX(-22px)}
.step-list .step.in{transform:none}
.step.in .step-n{animation:num-in .7s var(--ease-out) calc(var(--d,0s) + .1s) both}
@keyframes num-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* C. the shelf: cards lift, and the cover art settles out of a slow push in */
.game.in .game-art{animation:art-settle 1.15s var(--ease-out) both}
@keyframes art-settle{from{transform:scale(1.07)}to{transform:scale(1)}}
.game.in .game-off{animation:badge-pop .6s var(--ease-out) .25s both}
@keyframes badge-pop{
  0%{opacity:0;transform:translateY(-6px) scale(.8)}
  70%{transform:translateY(0) scale(1.06)}
  100%{opacity:1;transform:none}
}
.game.in .game-price{animation:price-in .7s var(--ease-out) .3s both}
@keyframes price-in{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}

/* D. the hold panel breathes in from below */
.hold-stage{transition:opacity .9s var(--ease-out),transform .9s var(--ease-out)}
.hold-sec .hold-copy.in ~ .hold-stage,
.hold-sec .hold-stage{opacity:1}

/* E. what you get: the picture wipes open, the cards follow */
.get-media{transition:opacity .9s var(--ease-out),transform .9s var(--ease-out)}
.get-media.in{opacity:1;transform:none}
.get-cards .gcard{transform:translateY(22px) scale(.98)}
.get-cards .gcard.in{transform:none}

/* F. the questions deal themselves in from the left */
.faq-list .qa{transform:translateX(-24px)}
.faq-list .qa.in{transform:none}
.faq-list .qa:nth-child(3n+2){--d:.07s}
.faq-list .qa:nth-child(3n+3){--d:.14s}
.qa-body p{animation:qa-open .45s var(--ease-out) both}
@keyframes qa-open{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

/* G. the composer fields arrive in reading order */
.composer.in .field{animation:card-rise .7s var(--ease-out) both}
.composer.in .field:nth-child(2){animation-delay:.09s}
.composer.in .field:nth-child(3){animation-delay:.18s}
.composer.in .btn-send{animation:card-rise .7s var(--ease-out) .27s both}

/* the game page joins in */
.gp-art{transition:opacity .9s var(--ease-out),transform .9s var(--ease-out)}
.gp-art.in{opacity:1;transform:none}
.gp-about.in .gp-feats li{animation:card-rise .6s var(--ease-out) both}
.gp-about.in .gp-feats li:nth-child(2){animation-delay:.07s}
.gp-about.in .gp-feats li:nth-child(3){animation-delay:.14s}
.gp-about.in .gp-feats li:nth-child(4){animation-delay:.21s}
.gp-about.in .gp-feats li:nth-child(5){animation-delay:.28s}

/* reduced motion keeps every one of these in its finished state */
@media (prefers-reduced-motion: reduce){
  .sec-head .sec-h::after{transform:scaleX(1)}
  .promises .promise,.composer .field,.composer .btn-send,
  .gp-about .gp-feats li,.game .game-art,.game .game-off,.game .game-price{animation:none !important}
  .step-list .step,.faq-list .qa,.get-cards .gcard{transform:none}
  .get-media,.gp-art{opacity:1;transform:none}
}


/* ==========================================================================
   The promise strip: three cards that charge up, then keep breathing
   ========================================================================== */
.promise{position:relative;isolation:isolate}

/* a pulse of charge sweeps the card as it arrives */
.promise::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:linear-gradient(115deg,transparent 34%,rgba(111,155,255,.20) 47%,rgba(169,124,255,.10) 54%,transparent 64%);
  transform:translateX(-130%);
}
.promises.in .promise::before{animation:charge-sweep 1.6s var(--ease-out) .15s both}
.promises.in .promise:nth-child(2)::before{animation-delay:.29s}
.promises.in .promise:nth-child(3)::before{animation-delay:.43s}
@keyframes charge-sweep{
  0%{transform:translateX(-130%)}
  100%{transform:translateX(130%)}
}

/* the top edge draws itself like a live wire */
.promise::after{
  content:"";position:absolute;left:0;top:0;height:2px;width:100%;z-index:1;
  background:linear-gradient(to right,var(--accent),rgba(111,155,255,.35) 45%,rgba(111,155,255,0));
  transform:scaleX(0);transform-origin:left;
}
.promises.in .promise::after{animation:edge-draw 1s var(--ease-out) both}
.promises.in .promise:nth-child(2)::after{animation-delay:.14s}
.promises.in .promise:nth-child(3)::after{animation-delay:.28s}
@keyframes edge-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* the living element: a soft glow behind the mark, breathing slowly */
.p-glow{
  position:absolute;top:clamp(14px,1.8vw,26px);left:clamp(16px,1.9vw,28px);
  width:96px;height:96px;margin:-28px 0 0 -28px;z-index:0;pointer-events:none;
  background:radial-gradient(circle at 50% 50%,rgba(111,155,255,.42),rgba(111,155,255,0) 68%);
  opacity:0;
}
.promises.in .p-glow{animation:glow-in .9s var(--ease-out) .55s both,glow-breath 6s ease-in-out 1.5s infinite}
.promises.in .promise:nth-child(2) .p-glow{animation-delay:.69s,1.9s}
.promises.in .promise:nth-child(3) .p-glow{animation-delay:.83s,2.3s}
@keyframes glow-in{from{opacity:0;transform:scale(.6)}to{opacity:.55;transform:scale(1)}}
@keyframes glow-breath{0%,100%{opacity:.35;transform:scale(.94)}50%{opacity:.7;transform:scale(1.06)}}

.promise .mark,.promise h2,.promise p{position:relative;z-index:2}

/* the words arrive after the charge, in order */
.promises.in .promise h2{animation:copy-rise .7s var(--ease-out) .5s both}
.promises.in .promise p{animation:copy-rise .7s var(--ease-out) .62s both}
.promises.in .promise:nth-child(2) h2{animation-delay:.64s}
.promises.in .promise:nth-child(2) p{animation-delay:.76s}
.promises.in .promise:nth-child(3) h2{animation-delay:.78s}
.promises.in .promise:nth-child(3) p{animation-delay:.9s}
@keyframes copy-rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* hover lights the whole card */
.promise{transition:transform .45s var(--ease),border-color .45s var(--ease),box-shadow .45s var(--ease)}
.promise:hover{transform:translateY(-4px);border-color:rgba(111,155,255,.5);box-shadow:0 18px 46px rgba(2,2,7,.6)}
.promise:hover .p-glow{opacity:.8}

@media (prefers-reduced-motion: reduce){
  .promise::before{display:none}
  .promise::after{transform:scaleX(1)}
  .promises.in .p-glow,.promises.in .promise h2,.promises.in .promise p{animation:none !important;opacity:1;transform:none}
  .p-glow{opacity:.45}
}


/* the social buttons in the footer */
.foot-social{display:flex;gap:10px;align-items:center}
.soc{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;color:var(--text-secondary);
  border:1px solid var(--line);background:rgba(10,13,28,.7);
  clip-path:polygon(9px 0,100% 0,100% calc(100% - 9px),calc(100% - 9px) 100%,0 100%,0 9px);
  transition:color .3s var(--ease),border-color .3s var(--ease),transform .3s var(--ease),background-color .3s var(--ease);
}
.soc svg{width:19px;height:19px;fill:currentColor}
.soc:hover{color:var(--accent);border-color:var(--accent);transform:translateY(-2px);background:rgba(111,155,255,.10)}
@media (pointer:coarse){.soc{width:44px;height:44px}}


/* ==========================================================================
   The game description: set like a page of a magazine, not a dump of text
   ========================================================================== */
.gp-copy{max-width:68ch}
.gp-copy .lede{
  font-size:clamp(1.02rem,1.25vw,1.18rem);line-height:1.6;color:var(--text-primary);
  margin-bottom:4px;
}
.gp-copy .gp-p{margin-top:14px;color:var(--text-secondary);font-size:.97rem;line-height:1.72}

.gp-h{
  font-family:var(--display);font-weight:700;font-size:1.12rem;letter-spacing:.04em;
  text-transform:uppercase;color:var(--text-primary);
  margin:34px 0 14px;padding-left:16px;position:relative;
}
.gp-h::before{
  content:"";position:absolute;left:0;top:.18em;bottom:.18em;width:3px;
  background:linear-gradient(to bottom,var(--accent),rgba(111,155,255,.15));
}

/* features: the name leads, the line explains */
.gp-feats{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:16px}
.gp-feats li{position:relative;padding-left:22px}
.gp-feats li::before{
  content:"";position:absolute;left:0;top:.55em;width:10px;height:2px;
  background:var(--accent);opacity:.85;
}
.gp-feat-n{
  display:block;font-family:var(--display);font-weight:700;font-size:1.02rem;
  letter-spacing:.02em;color:var(--text-primary);margin-bottom:3px;
}
.gp-feat-s{display:block;color:var(--text-secondary);font-size:.95rem;line-height:1.66}

/* plain lists: what is in the box */
.gp-list{
  list-style:none;margin:16px 0 0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 24px;
}
.gp-list li{
  position:relative;padding-left:20px;color:var(--text-secondary);font-size:.94rem;line-height:1.5;
}
.gp-list li::before{
  content:"";position:absolute;left:0;top:.62em;width:7px;height:7px;
  border:1px solid var(--accent);transform:rotate(45deg);opacity:.8;
}

@media (max-width:640px){
  .gp-list{grid-template-columns:1fr}
  .gp-h{margin-top:28px}
}

/* the arrival, one element after another */
.gp-about.in .gp-copy > *{animation:copy-rise .6s var(--ease-out) both}
.gp-about.in .gp-copy > *:nth-child(2){animation-delay:.06s}
.gp-about.in .gp-copy > *:nth-child(3){animation-delay:.12s}
.gp-about.in .gp-copy > *:nth-child(4){animation-delay:.18s}
.gp-about.in .gp-copy > *:nth-child(n+5){animation-delay:.24s}

@media (prefers-reduced-motion: reduce){
  .gp-about.in .gp-copy > *{animation:none !important}
}


/* the description sits on its own quiet surface, so the board behind it
   never competes with the words */
.gp-about{
  position:relative;
  background:linear-gradient(160deg,rgba(10,13,28,.86) 0%,rgba(7,25,31,.90) 100%);
  backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);
  border:1px solid var(--line);
  padding:clamp(24px,3vw,40px);
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
}
.gp-about > .sec-h{margin-bottom:20px}
.gp-copy{max-width:64ch}

/* the first heading should not push away from the lede too hard */
.gp-copy > .gp-h:first-child{margin-top:6px}


/* ==========================================================================
   Section choreography, second pass
   ========================================================================== */

/* ---- A. the three promises: power arrives, card by card ---- */
.promises .promise:nth-child(1){--d:0s}
.promises .promise:nth-child(2){--d:.22s}
.promises .promise:nth-child(3){--d:.44s}

/* the left edge lights after the top edge, so the corner reads as drawn */
.promise{border-left-color:transparent}
.promises.in .promise{animation:edge-left 1.1s var(--ease-out) calc(var(--d) + .25s) both}
@keyframes edge-left{
  from{border-left-color:transparent}
  to{border-left-color:rgba(111,155,255,.45)}
}

/* the mark draws itself, then flares once and settles into a slow breath */
.promise .mark{overflow:visible}
.promise .mark .d{
  stroke-dasharray:var(--dl,150);stroke-dashoffset:var(--dl,150);
  transition:stroke-dashoffset .95s var(--ease-out) calc(var(--d) + .28s);
}
.promises.in .promise .mark .d{stroke-dashoffset:0}
.promises.in .promise .mark{animation:mark-arrive .9s var(--ease-out) calc(var(--d) + .28s) both}
@keyframes mark-arrive{
  from{opacity:0;transform:translateY(8px) scale(.9)}
  to{opacity:1;transform:none}
}

/* the glow behind the mark: a flare as the line closes, then breathing */
.promises.in .p-glow{
  animation:glow-flare 1.5s var(--ease-out) calc(var(--d) + .55s) both,
            glow-breath 6s ease-in-out calc(var(--d) + 2.1s) infinite;
}
@keyframes glow-flare{
  0%{opacity:0;transform:scale(.5)}
  55%{opacity:.95;transform:scale(1.18)}
  100%{opacity:.42;transform:scale(1)}
}

/* ---- B. the hold panel: it breathes, and the button invites a press ---- */
.hold-stage{position:relative}
.hold-sec .hold-stage::after{
  content:"";position:absolute;left:0;top:0;height:2px;width:100%;
  background:linear-gradient(to right,var(--accent),rgba(111,155,255,0));
  transform:scaleX(0);transform-origin:left;
  transition:transform 1s var(--ease-out) .2s;
}
.hold-sec .hold-copy.in ~ .hold-stage::after{transform:scaleX(1)}

/* the capsule keeps its scroll driven transform, so the float rides the image */
.capsule img{animation:capsule-float 5.5s ease-in-out -1.4s infinite}
@keyframes capsule-float{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(-7px)}
}

/* a ring that pulses out of the button, so it reads as pressable */
.hold-btn::after{
  content:"";position:absolute;inset:-6px;border-radius:50%;pointer-events:none;
  border:1px solid rgba(111,155,255,.5);
  animation:btn-ping 3.4s ease-out -1s infinite;
}
@keyframes btn-ping{
  0%{opacity:.7;transform:scale(.9)}
  60%{opacity:0;transform:scale(1.18)}
  100%{opacity:0;transform:scale(1.18)}
}
.hold-btn:hover::after,.hold-btn:active::after{animation-play-state:paused;opacity:.9;transform:scale(1)}

/* the ground shimmers very faintly, so the bay never looks frozen */
.ground::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;
  background:linear-gradient(to right,transparent,rgba(111,155,255,.5),transparent);
  animation:ground-sweep 7s ease-in-out -2s infinite;
}
@keyframes ground-sweep{
  0%,100%{transform:translateX(-40%);opacity:0}
  50%{transform:translateX(40%);opacity:.8}
}

/* ---- C. the explainer: the picture is scanned in, the cards deal out ---- */
.get-media{position:relative;overflow:hidden}
.get-media::after{
  content:"";position:absolute;left:0;right:0;top:0;height:38%;pointer-events:none;
  background:linear-gradient(to bottom,rgba(111,155,255,0),rgba(111,155,255,.22),rgba(111,155,255,0));
  transform:translateY(-140%);
}
.get-media.in::after{animation:scan-down 1.6s var(--ease-out) .25s both}
@keyframes scan-down{
  0%{transform:translateY(-140%);opacity:0}
  15%{opacity:1}
  85%{opacity:1}
  100%{transform:translateY(300%);opacity:0}
}
.get-media.in img{animation:media-settle 1.4s var(--ease-out) both}
@keyframes media-settle{from{transform:scale(1.06)}to{transform:scale(1)}}

.get-cards .gcard{transition:transform .8s var(--ease-out) var(--d,0s),opacity .8s var(--ease-out) var(--d,0s),border-color .4s var(--ease)}
.get-cards .gcard:nth-child(1){--d:.05s}
.get-cards .gcard:nth-child(2){--d:.16s}
.get-cards .gcard.in .tag{animation:copy-rise .6s var(--ease-out) calc(var(--d) + .2s) both}
.get-cards .gcard.in p{animation:copy-rise .6s var(--ease-out) calc(var(--d) + .3s) both}
.get-cards .gcard:hover{border-color:rgba(111,155,255,.5)}

/* ---- D. the steps: a line runs between them as they land ---- */
.step{position:relative}
.step.in .step-n{animation:num-drop .75s var(--ease-out) calc(var(--d,0s) + .12s) both}
@keyframes num-drop{
  0%{opacity:0;transform:translateY(-14px)}
  70%{transform:translateY(2px)}
  100%{opacity:1;transform:none}
}
.step.in h3{animation:copy-rise .7s var(--ease-out) calc(var(--d,0s) + .22s) both}
.step.in p{animation:copy-rise .7s var(--ease-out) calc(var(--d,0s) + .32s) both}
.step.in::after{width:42px;transition:width 1s var(--ease-out) calc(var(--d,0s) + .1s)}

/* ---- E. the questions: each row is dealt, with a light passing along it ---- */
.qa{position:relative;overflow:hidden}
.qa::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,rgba(111,155,255,.14) 48%,transparent 58%);
  transform:translateX(-120%);
}
.qa.in::after{animation:charge-sweep 1.4s var(--ease-out) calc(var(--d,0s) + .1s) both}
.qa summary{transition:color .3s var(--ease),background-color .3s var(--ease)}
.qa[open] summary{color:var(--accent)}

/* ---- F. the composer: the send button breathes until it is used ---- */
.composer.in .btn-send{position:relative}
.btn-send::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),calc(100% - var(--cut)) 100%,0 100%,0 var(--cut));
  box-shadow:0 0 0 0 rgba(111,155,255,.5);
  animation:send-pulse 4.5s ease-out -1s infinite;
}
@keyframes send-pulse{
  0%{box-shadow:0 0 0 0 rgba(111,155,255,.45)}
  60%{box-shadow:0 0 0 14px rgba(111,155,255,0)}
  100%{box-shadow:0 0 0 0 rgba(111,155,255,0)}
}

/* everything above stops for anyone who asked for less motion */
@media (prefers-reduced-motion: reduce){
  .promises.in .promise,
  .promises.in .promise .mark,
  .promises.in .p-glow,
  .capsule img,.hold-btn::after,.ground::before,
  .get-media.in::after,.get-media.in img,
  .get-cards .gcard.in .tag,.get-cards .gcard.in p,
  .step.in .step-n,.step.in h3,.step.in p,
  .qa.in::after,.btn-send::after{animation:none !important}
  .promise{border-left-color:rgba(111,155,255,.45)}
  .promise .mark .d{stroke-dashoffset:0}
  .hold-sec .hold-stage::after{transform:scaleX(1)}
  .p-glow{opacity:.45}
}


/* ==========================================================================
   Phones and tablets: the same design, without the expensive parts
   A live blur costs a full screen re-render every frame. Thirty one of them
   is why the page flickered. Below 1024px the panels become solid instead.
   ========================================================================== */
@media (max-width:1024px), (pointer:coarse){

  /* 1. no live blur anywhere. The panels keep their look, painted flat. */
  .nav,.chip,.promise,.game,.qa,.gcard,.gp-get,.gp-about,.hold-stage,.soc,
  input,textarea{
    backdrop-filter:none !important;
    -webkit-backdrop-filter:none !important;
  }
  .nav{background:linear-gradient(to bottom,rgba(5,5,12,.94),rgba(5,5,12,.72) 70%,rgba(5,5,12,0))}
  .promise,.game{background:linear-gradient(165deg,#0b2129 0%,#111634 100%)}
  .qa,.gcard,.gp-get,.gp-about{background:#0b2129}
  .hold-stage{background:linear-gradient(180deg,#122d37 0%,#08202899 100%)}
  .chip{background:rgba(5,5,12,.82)}
  input,textarea{background:#0b2129}
  .soc{background:#0b2129}

  /* 2. the room keeps its character with a third of the layers */
  .env-lit,.env-grain,.env-scan,.env-beams{display:none}
  .env-circuit{background-size:220px 220px;animation-duration:190s}
  .env-motes{display:none}

  /* 3. the page body sits calmer over it, so text never fights the board */
  .body-wrap{background:linear-gradient(to bottom,rgba(5,5,12,0) 0%,rgba(5,5,12,.62) 3%,rgba(5,5,12,.72) 100%)}
  .page-game .body-wrap{background:rgba(5,5,12,.72)}

  /* 4. one shadow layer, not three */
  .brand-mark{filter:none}
  .btn-accent{box-shadow:0 6px 20px rgba(111,155,255,.18)}
  .game:hover{box-shadow:none;transform:none}
  .promise:hover{box-shadow:none;transform:none}

  /* 5. the idle loops stop. Arrival animations stay, they are the nice part. */
  .hold-btn::after,.ground::before,.capsule img,.btn-send::after,
  .env-glow{animation:none !important}
  .env-glow{opacity:.9}
  .p-glow{animation:none !important;opacity:.45}
}

/* below 640px the board recedes further so the words carry the page */
@media (max-width:640px){
  .env-circuit{opacity:.55}
  .env-vig{background:radial-gradient(ellipse 100% 70% at 50% 40%,transparent 40%,rgba(2,2,7,.5) 100%)}
  .hud-c{display:none}
}


/* the phone hero's film */
.static-media{position:relative;overflow:hidden}
.static-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  display:block;background:var(--canvas);
}
.static-video.is-still{opacity:1}


/* ==========================================================================
   The scrolling hero on an upright phone
   Same journey, read bottom up, because a phone has height and not width.
   ========================================================================== */
@media (max-width:820px){

  /* a phone scrolls faster per flick, so the journey needs less distance */
  .hero{height:340vh}

  /* every beat sits in a lower third, full width, like a film subtitle */
  .band.ll,.band.ul,.band.cl{
    justify-content:flex-end;
    align-items:flex-start;
    padding-bottom:clamp(96px,17vh,170px);
    padding-left:var(--pad);padding-right:var(--pad);
  }

  /* and the scrim becomes a floor, not a side lane */
  .band::before{
    background:linear-gradient(to top,
      rgba(3,14,18,var(--sa,.86)) 0%,
      rgba(3,14,18,calc(var(--sa,.86) * .92)) 26%,
      rgba(3,14,18,calc(var(--sa,.86) * .5)) 52%,
      rgba(3,14,18,0) 74%);
    -webkit-mask-image:none;mask-image:none;
  }

  .line{font-size:clamp(1.9rem,8.4vw,3rem);max-width:14ch}
  .line.big{font-size:clamp(2.3rem,10.5vw,3.6rem);max-width:11ch}
  .line.huge{font-size:clamp(2.5rem,11.5vw,4rem);max-width:10ch}
  .line.trip{font-size:clamp(1.7rem,7.2vw,2.5rem);max-width:15ch}
  .settle .sub{max-width:30ch;font-size:.98rem}
  .settle .row{flex-direction:column;align-items:stretch;gap:10px}
  .settle .row .btn{width:100%}
  .kicker{margin-bottom:14px}

  /* the loading ring and the cue move out of the thumb's way */
  .ring{right:16px;bottom:auto;top:84px}
  .cue{bottom:14px}
}

/* a very short phone gets the beats tighter still */
@media (max-width:820px) and (max-height:700px){
  .band.ll,.band.ul,.band.cl{padding-bottom:clamp(72px,12vh,110px)}
  .line.huge{font-size:clamp(2.1rem,9.5vw,3rem)}
  .settle .sub{font-size:.92rem;max-width:28ch}
}

/* the settle is the tallest beat, and on a phone it reaches up into the
   fire, so its floor is deeper and climbs the whole frame */
@media (max-width:820px){
  .band.settle::before{
    background:linear-gradient(to top,
      rgba(3,14,18,.95) 0%,
      rgba(3,14,18,.93) 42%,
      rgba(3,14,18,.86) 70%,
      rgba(3,14,18,.58) 88%,
      rgba(3,14,18,0) 100%);
  }
}


/* two games to a row on a phone */
@media (max-width:640px){
  .game-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .game-body{padding:12px 12px 14px;gap:5px}
  .game-title{font-size:1.02rem;line-height:1.08}
  .game-ed{font-size:.74rem}
  .game-tag{font-size:.56rem;letter-spacing:.14em}
  .game-price{font-size:1.05rem;gap:7px}
  .game-price .was{font-size:.76rem}
  .game-meta{font-size:.58rem;letter-spacing:.08em}
  .game-more{font-size:.72rem;margin-top:3px}
  .game-off{top:8px;left:8px;font-size:.66rem;padding:4px 7px}
  .game-cta{margin:0 12px 12px;font-size:.86rem;padding:10px 12px}
  .games-foot{font-size:.88rem}
}

/* on the narrowest phones the two columns get a little more air */
@media (max-width:380px){
  .game-grid{gap:9px}
  .game-title{font-size:.95rem}
  .game-cta{font-size:.8rem;padding:9px 8px}
}


/* ==========================================================================
   A phone held sideways: the journey still runs, in a shorter frame
   ========================================================================== */
@media (orientation:landscape) and (pointer:coarse) and (max-height:560px){
  .hero{height:300vh}
  .band.ll,.band.ul,.band.cl{
    justify-content:flex-end;
    padding-bottom:clamp(28px,9vh,54px);
  }
  .line{font-size:clamp(1.3rem,4.2vw,2rem);max-width:22ch}
  .line.big{font-size:clamp(1.5rem,5vw,2.4rem);max-width:18ch}
  .line.huge{font-size:clamp(1.6rem,5.6vw,2.6rem);max-width:16ch}
  .line.trip{font-size:clamp(1.2rem,3.6vw,1.7rem);max-width:24ch}
  .settle .sub{font-size:.85rem;max-width:44ch;margin-top:10px}
  .settle .row{flex-direction:row;margin-top:12px;gap:8px}
  .settle .row .btn{width:auto;padding:9px 14px;font-size:.88rem}
  .kicker{margin-bottom:8px;font-size:.6rem}
  .band::before{
    background:linear-gradient(to top,
      rgba(3,14,18,.94) 0%,rgba(3,14,18,.9) 40%,
      rgba(3,14,18,.6) 72%,rgba(3,14,18,0) 100%);
    -webkit-mask-image:none;mask-image:none;
  }
  .cue,.ring{display:none}
}

/* ==========================================================================
   Flicker hardening for touch devices
   A phone repaints fixed layers as you scroll. Behind a full screen video
   none of them are visible anyway, so while the hero is running they stop
   existing entirely.
   ========================================================================== */
@media (max-width:1024px), (pointer:coarse){
  body.hero-lock .env,
  body.hero-lock .hud{display:none}

  /* the stage and the film each get their own layer, so neither is
     repainted by anything else moving on the page */
  .stage{
    transform:translateZ(0);
    -webkit-backface-visibility:hidden;backface-visibility:hidden;
    will-change:transform;
  }
  #hero-video{
    -webkit-backface-visibility:hidden;backface-visibility:hidden;
  }
  .poster{-webkit-backface-visibility:hidden;backface-visibility:hidden}

  /* iOS repaints a sticky element on every scroll tick when it carries a
     shadow or a filter, so the hero carries neither */
  .stage,.stage *{box-shadow:none}
}


/* ==========================================================================
   The phone hero, showing the whole frame
   The film is 16:9 and a phone is not, so instead of cropping into it the
   picture sits as a band near the top and the words take the room below.
   ========================================================================== */
@media (max-width:820px){

  /* nothing is cut off any more */
  #hero-video,.poster{
    object-fit:contain;
    background-size:contain;
    background-repeat:no-repeat;
    object-position:50% 30%;
    background-position:50% 30%;
  }

  /* the room behind the band is the same board the rest of the page sits on,
     so the hero reads as part of the page rather than a letterboxed video */
  .stage{background:var(--canvas)}
  .stage::before{
    content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
    background:
      radial-gradient(70% 40% at 50% 26%,rgba(31,84,240,.16),transparent 70%),
      radial-gradient(90% 50% at 50% 100%,rgba(5,5,12,.9),transparent 70%);
  }

  /* the captions sit under the picture, not over it */
  .band.ll,.band.ul,.band.cl{
    justify-content:flex-end;
    padding-bottom:clamp(64px,11vh,120px);
  }

  /* and their floor only has to cover the lower half now, so the picture
     itself stays bright and clear */
  .band::before{
    background:linear-gradient(to top,
      rgba(3,14,18,.96) 0%,
      rgba(3,14,18,.94) 30%,
      rgba(3,14,18,.72) 46%,
      rgba(3,14,18,0) 60%);
    -webkit-mask-image:none;mask-image:none;
  }

  /* the dissolve at the foot of the hero stays gentle */
  .stage::after{height:22%}
}

/* a short phone: the band gets a little higher so the words still fit */
@media (max-width:820px) and (max-height:720px){
  #hero-video,.poster{object-position:50% 24%;background-position:50% 24%}
  .band.ll,.band.ul,.band.cl{padding-bottom:clamp(48px,8vh,86px)}
}

/* the picture and the words should read as one composition, not three
   separate zones with gaps between them */
@media (max-width:820px){
  #hero-video,.poster{object-position:50% 33%;background-position:50% 33%}

  .band.ll,.band.ul,.band.cl{padding-bottom:clamp(120px,24vh,240px)}

  /* the settle carries a headline, a paragraph and two buttons, so it needs
     the lower half to itself */
  .band.settle{padding-bottom:clamp(48px,9vh,96px)}
  .band.settle::before{
    background:linear-gradient(to top,
      rgba(3,14,18,.97) 0%,
      rgba(3,14,18,.95) 40%,
      rgba(3,14,18,.8) 58%,
      rgba(3,14,18,0) 74%);
  }
}
@media (max-width:820px) and (max-height:720px){
  #hero-video,.poster{object-position:50% 26%;background-position:50% 26%}
  .band.ll,.band.ul,.band.cl{padding-bottom:clamp(90px,18vh,170px)}
  .band.settle{padding-bottom:clamp(36px,6vh,70px)}
}


/* ==========================================================================
   Touch screens: the shelf arrives calmly
   Three animations per card, running while its cover was still decoding, is
   what made the games flicker on the way past. One quiet fade instead.
   ========================================================================== */
@media (pointer:coarse), (max-width:820px){

  .game.in .game-art,
  .game.in .game-off,
  .game.in .game-price{animation:none !important}

  .game-art img{transition:none}
  .game:hover .game-art img{transform:none}

  /* hover states linger after a tap on a touch screen, which reads as a flash */
  .game:hover,.promise:hover,.gcard:hover{transform:none;box-shadow:none}
  .game:active{transform:scale(.985)}

  /* each card is its own layer, so scrolling never repaints its neighbours */
  .game{
    transition:opacity .55s var(--ease-out) var(--d,0s),transform .55s var(--ease-out) var(--d,0s);
    -webkit-backface-visibility:hidden;backface-visibility:hidden;
    transform:translateZ(0);
  }
  .js .game.reveal{opacity:0;transform:translateY(14px)}
  .game.reveal.in{opacity:1;transform:none}

  /* a picture that is still decoding should not flash its box */
  .game-art{background:var(--panel-2)}
  .game-art img{display:block}

  /* the section sweeps and light passes are the other repaint source */
  .qa.in::after,.promises.in .promise::before{animation:none !important;opacity:0}
}


/* ==========================================================================
   No loading icon, and a background that holds still on a phone
   ========================================================================== */
.ring{display:none !important}

@media (pointer:coarse), (max-width:820px){

  /* every full screen fixed layer stops animating. They still look the same,
     they just stop asking the phone to redraw them sixty times a second. */
  .env,.env *,
  .env-glow,.env-grid,.env-circuit,.env-stars,.env-motes,.env-beams,
  .env-lit,.env-scan,.env-grain{
    animation:none !important;
    will-change:auto !important;
  }

  /* the shelf simply appears. No fade, no movement, nothing to flicker. */
  .js .game.reveal,
  .js .game.reveal.in{opacity:1 !important;transform:none !important;animation:none !important}
  .game{transition:none}
  .game-art img{opacity:1}

  /* the covers reserve their space before they load, so nothing jumps. The
     box is the covers' own 2:3 (Nintendo's square for Switch): a 4:5 box left
     a black bar down each side of every cover on a phone. */
  .game-art{aspect-ratio:2 / 3;background:var(--panel-2)}
  .game[data-plat="switch"] .game-art{aspect-ratio:1 / 1}
  .game-art img{position:absolute;inset:0;width:100%;height:100%}

  /* the trail and the section marks stop redrawing mid scroll */
  .trail{display:none}
  .sec-head::before{transition:none}
}


/* ==========================================================================
   Phones: the last three causes of scroll flicker, removed
   --------------------------------------------------------------------------
   The card animations were already off, so they were never the problem. What
   remained was work the phone was doing behind the cards on every frame:

     1. A fixed, full height backdrop made of twelve stacked layers. A phone
        re-composites a fixed layer every time the page moves under it.
     2. A frosted glass blur on each card. The card is already ninety six per
        cent opaque, so the blur was invisible, but the phone still re-sampled
        everything behind all fifteen cards on every frame.
     3. Each card forced onto its own compositor layer, fifteen of them.

   None of this is visible. All of it is now gone on touch screens. The board
   pattern stays, it simply scrolls with the page instead of being pinned
   behind it.
   ========================================================================== */
@media (pointer:coarse), (max-width:820px){

  /* --- 1. the backdrop joins the page instead of being pinned behind it --- */
  /* the whole fixed stack goes. The board is painted onto the page itself, so
     it scrolls with the content, and the phone never re-composites a pinned
     layer underneath fifteen moving cards. */
  .env{display:none !important}
  html{background:var(--canvas)}
  body{
    background-color:var(--canvas);
    background-image:
      url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27240%27%20height%3D%27240%27%20viewBox%3D%270%200%20240%20240%27%3E%3Cg%20fill%3D%27none%27%20stroke%3D%27rgba(43%2C110%2C255%2C.20)%27%20stroke-width%3D%271.4%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M0%2048%20H72%20L96%2072%20H168%20M168%2072%20V144%20H240%27%2F%3E%3Cpath%20d%3D%27M48%200%20V96%20L72%20120%20V240%27%2F%3E%3Cpath%20d%3D%27M240%20192%20H144%20L120%20168%20H24%20V240%27%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%27none%27%20stroke%3D%27rgba(139%2C92%2C246%2C.16)%27%20stroke-width%3D%271.4%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M96%200%20V24%20H144%20V96%20H216%20V0%27%2F%3E%3Cpath%20d%3D%27M0%20120%20H24%20L48%20144%20H96%20V216%20H168%27%2F%3E%3Cpath%20d%3D%27M192%20240%20V204%20L216%20180%20H240%27%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%27rgba(77%2C150%2C255%2C.30)%27%3E%3Ccircle%20cx%3D%2772%27%20cy%3D%2748%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27168%27%20cy%3D%2772%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%2748%27%20cy%3D%2796%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27120%27%20cy%3D%27168%27%20r%3D%273.4%27%2F%3E%3Ccircle%20cx%3D%27144%27%20cy%3D%2724%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%27216%27%20cy%3D%2796%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%2796%27%20cy%3D%27216%27%20r%3D%273%27%2F%3E%3Ccircle%20cx%3D%2724%27%20cy%3D%27120%27%20r%3D%273%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"),
      radial-gradient(70% 26% at 12% 0%,rgba(31,84,240,.20),transparent 70%),
      radial-gradient(60% 20% at 88% 9%,rgba(124,67,232,.15),transparent 72%);
    background-repeat:repeat,no-repeat,no-repeat;
    background-size:300px 300px,100% 1400px,100% 1400px;
    background-position:0 0,50% 0,50% 0;
    background-attachment:scroll,scroll,scroll;
  }
  .hud{display:none !important}

  /* --- 2. no frosted glass anywhere. It cost a full re-sample per frame --- */
  *,*::before,*::after{
    -webkit-backdrop-filter:none !important;
    backdrop-filter:none !important;
  }
  /* the bar leaned on that blur to stay readable, so it gets a solid back */
  .nav{background:rgba(5,19,25,.94)}

  /* --- 3. the cards are ordinary boxes again: no layers, nothing moving --- */
  .game{
    transform:none !important;
    will-change:auto !important;
    -webkit-backface-visibility:visible;backface-visibility:visible;
    transition:none !important;
    animation:none !important;
    contain:paint;
  }
  .game *,.game *::before,.game *::after{
    animation:none !important;
    transition:none !important;
  }
  .game:hover,.game:hover .game-art img{transform:none !important}
  .js .game.reveal,.js .game.reveal.in,.game.reveal,.game.in{
    opacity:1 !important;transform:none !important;animation:none !important;
  }

  /* nothing else on the page animates itself into view either */
  .reveal,.reveal.in{opacity:1 !important;transform:none !important}
  .promise::before,.qa::after,.p-glow{display:none !important}
  .sec-head .sec-h::after{transform:scaleX(1)}
  .mark .d{stroke-dashoffset:0 !important;transition:none !important}
  .step::after{width:42px;transition:none}
}


/* The canvas is far darker now, so the board pattern reads much louder than it
   did on the old teal. Pulled back so the games stay the thing you look at. */
.env-circuit{opacity:.6}
.env-grid{opacity:.62}
.env-beams{opacity:.7}


/* ==========================================================================
   THE SHELF CARD, second pass.
   A red discount flag in the corner, Sony's PS5 mark under the art, and the
   before price struck through ahead of the price you actually pay.
   These rules come last on purpose, so they win over the originals above.
   ========================================================================== */

:root{ --deal:#e11d2e; }        /* the discount red: the flag and the price */

/* the covers are 2:3, so ask for 2:3 and nothing gets cropped */
.game-art img{aspect-ratio:2 / 3;object-fit:contain;background:#05060f}
.game-art::after{display:none}

/* ---------- Nintendo's covers are square ----------
   Sony, Microsoft and Steam all draw a tall 2:3 box for a game. Nintendo does
   not: its store shows one square tile per game, and that is the only art it
   publishes. Squeezing that square into a 2:3 slot leaves a third of the card
   empty, so a Switch card asks for the shape its picture actually is.

   The card itself is unchanged. The red Nintendo strip still runs under the
   art and the title, price and button still sit below it -- the same order the
   eShop uses, so a Switch card ends up looking like a Switch card. Cards in a
   row are stretched to a common height by the grid, and .game-body already
   takes up the slack with the price pinned to its bottom, so a shorter picture
   does not leave a card hanging. */
.game[data-plat="switch"] .game-art img{aspect-ratio:1 / 1}
.gp[data-plat="switch"] .gp-art img{aspect-ratio:1 / 1}

/* the flag sits in the corner of the art, squared off against the edges */
.game-off{
  top:0;left:0;z-index:2;
  display:flex;align-items:center;gap:8px;
  font-family:var(--body);font-size:1.25rem;font-weight:800;letter-spacing:.01em;
  background:var(--deal);color:#fff;padding:12px 19px 12px 15px;
  border-radius:0 0 12px 0;clip-path:none;
}
.game-off svg{width:20px;height:20px;fill:currentColor;display:block;flex:0 0 auto}

/* the platform strip, in Sony's own blue */
/* ---------- the console strip across the top of a card ----------
   One console: its own colour, its own logo. A game sold on more than one
   runs their colours into each other and shows every logo, so a customer can
   tell at a glance without opening the game. */
.plat-bar{display:flex;align-items:center;justify-content:center;gap:20px;
  background:#0070d1;padding:12px 0;line-height:0}
.plat-mark{display:inline-flex;align-items:center;gap:7px}
.plat-bar{color:#fff}   /* a product with its own ink sets it inline */
.plat-mark svg{height:19px;width:auto;fill:currentColor;display:block}
.plat-mark b{font-family:var(--display);font-size:1.05rem;font-weight:700;
  letter-spacing:.15em;line-height:1;color:inherit}
/* two consoles or more: the marks alone, evenly spaced, no names.
   Height is set and width follows, so Sony's wide logos keep their shape
   beside the square badges instead of being crushed into them. */
.plat-bar.is-many{gap:clamp(9px,3.5%,20px)}
.plat-bar.is-many .plat-mark svg{height:17px;width:auto}
/* four consoles or more on one card: everything a size down so they all fit */
.plat-bar.is-packed{gap:clamp(6px,2.5%,13px)}
.plat-bar.is-packed .plat-mark svg{height:13px}

/* ---------- Steam Offline Activation ----------
   The one question every PC customer asks first, answered on the card before
   it is opened. Worn in the PC tile's own violet so it reads as belonging to
   that shelf rather than as a second price or a warning.

   A bordered tag rather than another line of small caps: the card already has
   two of those above it, and a third would disappear into them.

   It runs the full width of the card body and wraps onto a second line rather
   than shrinking. Five cards to a row leaves about 150px of text width, and
   "Steam Offline Activation" set small enough to fit that on one line would be
   too small to read on a phone. Two lines, set at a size that can be read, is
   the better trade. */
.game-steam{
  display:flex;align-items:center;gap:7px;align-self:stretch;
  font-family:var(--mono);font-size:.62rem;letter-spacing:.09em;text-transform:uppercase;
  color:#c9bcff;background:rgba(138,107,255,.13);
  border:1px solid rgba(138,107,255,.4);border-radius:6px;
  padding:7px 10px;line-height:1.35;text-wrap:balance;
}
.game-steam svg{width:14px;height:14px;fill:currentColor;display:block;flex:0 0 auto}

/* the same note on a game page, given room to explain itself.
   The [hidden] rule has to be here: giving the class a display value beats the
   browser's own [hidden]{display:none}, and a console page was drawing an empty
   bordered bar where the line would have been. */
.gp-steam[hidden]{display:none}
.gp-steam{
  display:flex;align-items:flex-start;gap:10px;margin:14px 0 0;
  font-size:.95rem;line-height:1.5;color:var(--text-secondary);
  background:rgba(138,107,255,.1);border:1px solid rgba(138,107,255,.34);
  border-left-width:3px;border-radius:4px;padding:12px 14px;
}
.gp-steam b{color:#c9bcff;font-weight:700}
.gp-steam svg{width:19px;height:19px;fill:#8a6bff;flex:0 0 auto;margin-top:2px}

@media (max-width:640px){
  .game-steam{font-size:.55rem;letter-spacing:.07em;padding:4px 8px 4px 7px;gap:5px}
  .game-steam svg{width:11px;height:11px}
  .gp-steam{font-size:.88rem;padding:10px 12px}
}

/* ---------- choose your console ----------
   The first thing asked on the shelf, because it is the first thing a customer
   knows about themselves. Every button wears its own console's colour: Sony
   blue, Xbox green, Nintendo red, and a violet for PC. "Every console" runs
   all four across it.

   Not chosen, a button is that colour banked down into the dark, so five of
   them side by side read as a set rather than a fairground. Chosen, it comes
   up to full brand colour with a glow beneath it, and there is never any
   doubt which shelf you are looking at. */
.plat-pick{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:10px;margin:0 0 18px}
.plat-btn{
  --tint:var(--accent);
  --deep:#161c42;
  --face:var(--tint);   /* what it turns when chosen; PS Plus stays black */
  --ink:#fff;           /* the letters and the mark; PS Plus yellow, Game Pass lime */
  --wash:.6;            /* how much of the colour shows at rest; PS Plus keeps its black */
  position:relative;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:9px;min-height:112px;padding:18px 10px;
  background:var(--deep);
  background:linear-gradient(158deg,var(--deep) 0%,var(--deep) 45%,rgba(6,8,20,.86) 100%);
  border:1px solid rgba(255,255,255,.16);
  border-radius:0 0 var(--cut) 0;cursor:pointer;overflow:hidden;
  color:var(--text-secondary);font-family:var(--body);text-align:center;
  transition:transform .28s var(--ease),box-shadow .28s var(--ease),
             border-color .28s var(--ease),background .28s var(--ease);
}
/* a wash of the console's colour across the top, so the tile is unmistakably
   its brand even before it is chosen */
.plat-btn::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(158deg,var(--tint),transparent 70%);
  opacity:var(--wash);transition:opacity .28s var(--ease)}
.plat-btn>*{position:relative;z-index:1}

.plat-btn:hover{transform:translateY(-2px);border-color:rgba(255,255,255,.24)}
.plat-btn:hover::after{opacity:calc(var(--wash) + .18)}

.plat-ico{display:block;line-height:0}
.plat-ico svg{width:28px;height:28px;fill:var(--ink);display:block;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.5))}
/* Sony's logo is a wordmark, not a badge: give it its own height and let the
   width follow, or it comes out squashed into a square. It is doing the job
   of the name as well, so it stands a little taller than the icons. */
.plat-ico svg.wide{width:auto;height:27px;max-width:100%}

/* the name that the mark already says: kept for screen readers, off the tile */
.plat-name.is-said{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.plat-name{font-family:var(--display);font-size:1.2rem;font-weight:700;
  letter-spacing:.04em;line-height:1.05;color:var(--ink);
  text-shadow:0 1px 3px rgba(0,0,0,.55)}
.plat-n{font-family:var(--mono);font-size:.63rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);opacity:.92}

/* the console being shown: full brand colour, and lit from underneath */
.plat-btn.is-on{
  border-color:var(--tint);
  background:linear-gradient(158deg,var(--face),var(--deep) 88%);
  box-shadow:0 14px 40px -12px var(--tint),0 6px 20px rgba(0,0,0,.45);
  transform:translateY(-2px);
}
.plat-btn.is-on::after{opacity:0}
.plat-btn.is-on .plat-n{opacity:.95}
/* a bright edge along the top, the way a console lights up when it wakes.
   It takes the tile's own ink, so PS Plus wakes yellow and Game Pass lime. */
.plat-btn.is-on::before{content:"";position:absolute;inset:-1px -1px auto -1px;
  height:3px;background:var(--ink);opacity:.85;z-index:2}

/* ---------- the special bundles tile ----------
   Every other tile sits banked down until it is chosen. This one does not:
   a deal is meant to be seen, so it wears its pink-to-orange face all the
   time, with a slow breathing glow underneath. Chosen, it lifts and burns a
   little brighter; the top edge goes white so it still reads as "on". */
.plat-btn.is-flare{
  background:linear-gradient(135deg,#c02cc1 0%,#8b008c 52%,#57005a 100%);
  border-color:rgba(255,255,255,.34);
  box-shadow:0 10px 30px -10px rgba(192,44,193,.8),0 4px 14px rgba(0,0,0,.35);
  animation:flare-breathe 3.2s ease-in-out infinite;
}
.plat-btn.is-flare::after{
  background:linear-gradient(158deg,rgba(255,255,255,.28),transparent 58%);
  opacity:1}
.plat-btn.is-flare .plat-ico svg{filter:drop-shadow(0 2px 6px rgba(50,0,60,.6))}
.plat-btn.is-flare .plat-name{text-shadow:0 1px 3px rgba(50,0,60,.65)}
.plat-btn.is-flare .plat-n{opacity:.92}
.plat-btn.is-flare:hover{transform:translateY(-3px);border-color:rgba(255,255,255,.5)}
.plat-btn.is-flare.is-on{
  background:linear-gradient(135deg,#d63bd7 0%,#a010a1 50%,#6a006b 100%);
  border-color:#fff;
  box-shadow:0 16px 44px -10px rgba(214,59,215,.95),0 0 0 3px rgba(255,255,255,.18),0 6px 20px rgba(0,0,0,.45);
  animation:none}
.plat-btn.is-flare.is-on::before{background:#fff;opacity:1}
@keyframes flare-breathe{
  0%,100%{box-shadow:0 10px 30px -10px rgba(192,44,193,.6),0 4px 14px rgba(0,0,0,.35)}
  50%{box-shadow:0 14px 42px -8px rgba(214,59,215,1),0 4px 14px rgba(0,0,0,.35)}
}
@media (prefers-reduced-motion:reduce){ .plat-btn.is-flare{animation:none} }

/* a console we have nothing on the shelf for yet: offered, because we can
   order any title, but not dressed up as stock */
.plat-btn.is-none .plat-n{opacity:.78}

.plat-btn:focus-visible{outline:2px solid #fff;outline-offset:3px}

@media(max-width:620px){
  .plat-pick{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  /* icon on the left, name over the count beside it: a shorter tile, so all
     five consoles are on screen at once on a phone */
  .plat-btn{display:grid;grid-template-columns:auto 1fr;
    column-gap:11px;row-gap:1px;align-items:center;justify-content:start;
    min-height:0;padding:14px 13px;text-align:left}
  .plat-ico{grid-row:1/3;grid-column:1}
  .plat-name{grid-column:2;font-size:1.04rem}
  .plat-n{grid-column:2;font-size:.58rem;letter-spacing:.1em}
  .plat-ico svg{width:24px;height:24px}
  .plat-ico svg.wide{width:auto;height:21px}
  /* On the tile whose mark says the name, the mark takes the place of the
     name — logo on top, count under it, the same shape as every other
     button. Beside each other they are wider than a half-width tile and the
     count breaks across two lines. */
  .plat-btn:has(.plat-name.is-said){grid-template-columns:1fr;row-gap:3px}
  .plat-btn:has(.plat-name.is-said) .plat-ico{grid-row:1;grid-column:1}
  .plat-btn:has(.plat-name.is-said) .plat-n{grid-row:2;grid-column:1}
  .plat-btn::after{background:linear-gradient(100deg,var(--tint),transparent 76%)}
  .plat-btn.is-on{background:linear-gradient(100deg,var(--face),var(--deep) 92%)}
  .plat-btn.is-flare{background:linear-gradient(100deg,#c02cc1,#8b008c 55%,#57005a)}
  .plat-btn.is-flare.is-on{background:linear-gradient(100deg,#d63bd7,#a010a1 55%,#6a006b)}
}

/* ---------- a console with nothing on the shelf yet ---------- */
.plat-none{margin:clamp(26px,5vh,46px) auto 0;max-width:580px;text-align:center;
  background:var(--panel);border:1px solid var(--line);
  border-radius:0 0 var(--cut) 0;padding:clamp(26px,4vw,38px) clamp(20px,4vw,34px)}
.plat-none-h{margin:0 0 10px;font-family:var(--display);font-size:1.6rem;
  font-weight:700;color:var(--text-primary)}
.plat-none-p{margin:0 0 22px;color:var(--text-secondary);font-size:.95rem;line-height:1.6}
.plat-none .btn{display:inline-flex}

/* was, then now */
.game-price{font-family:var(--body);gap:12px;align-items:baseline}
.game-price .was{font-size:1.7rem;color:#fff;
  text-decoration:line-through;text-decoration-thickness:2px;font-weight:600}
.game-price .now{font-size:2.35rem;font-weight:800;color:var(--deal);letter-spacing:-.02em}

/* a game we have not put a price on yet */
.game-price.is-store{flex-direction:column;gap:2px}
/* the store price is the shop accent, so it never reads as our red deal price */
.is-store .store-was{font-size:1.75rem;font-weight:700;color:var(--accent);font-family:var(--mono)}
.is-store .store-now{font-size:1.75rem;font-weight:800;color:var(--deal)}
.is-store .store-note,.is-store .store-ask{
  font-family:var(--mono);font-size:.64rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-secondary);font-weight:500}

/* Below 760px the shelf runs two to a row, and a card is anything from 336px
   on a small tablet down to 160px on a phone — better than a two-to-one range.
   So these scale with the screen instead of taking one fixed size: as large as
   they were before at the top of the range, still on one line at the bottom.
   A phone-sized card only has about 136px of text under the cover. */
@media(max-width:760px){
  .game-off{
    font-size:clamp(.62rem,2.4vw,1.05rem);
    padding:clamp(5px,1.2vw,9px) clamp(8px,2vw,15px) clamp(5px,1.2vw,9px) clamp(6px,1.5vw,11px);
    gap:clamp(4px,.8vw,6px);
  }
  .game-off svg{width:clamp(11px,1.9vw,16px);height:clamp(11px,1.9vw,16px)}
  .game-price{gap:clamp(6px,1.4vw,11px)}
  .game-price .now{font-size:clamp(1.15rem,4.6vw,1.9rem)}
  .game-price .was{font-size:clamp(.9rem,3.4vw,1.4rem)}
  .is-store .store-was,.is-store .store-now{font-size:clamp(.95rem,3.6vw,1.5rem)}
}

/* the game page's own price line, matching the cards */
.gp-price{gap:14px}
.gp-price .was{font-size:1.7rem;color:#fff;font-weight:600;text-decoration-thickness:2px}
.gp-price .now{color:var(--deal);font-weight:800}
.gp-price .save{background:var(--deal);color:#fff}
.gp-store{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-top:22px}
.gp-store .store-was{font-family:var(--mono);font-size:clamp(1.7rem,3vw,2.4rem);color:var(--accent)}
.gp-store .store-now{font-family:var(--mono);font-size:clamp(1.7rem,3vw,2.4rem);color:var(--deal)}
.gp-store .store-ask{font-family:var(--mono);font-size:1.3rem;color:var(--text-secondary)}
.gp-store .store-note{font-family:var(--mono);font-size:.68rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-secondary)}

/* the flag on the game page's own artwork */
.gp-art .game-off{position:absolute}

/* hidden means hidden: the flag's display:flex was beating the attribute */
.game-off[hidden]{display:none}

/* the game page's own artwork is 2:3 like the covers */
.gp-art img{aspect-ratio:2 / 3;object-fit:contain;background:#05060f}
.cur[hidden]{display:none}


/* ==========================================================================
   PRICES, third pass: the old price in red and struck through, the price you
   pay in green, and a plain white price where there is no sale on at all.
   The strikethrough is kept heavy on purpose. Red and green are the pair
   colour-blind readers cannot separate, so the line through the old price,
   not its colour, is what carries the meaning.
   ========================================================================== */

:root{
  --was-red:#ff5468;   /* light enough to read on the dark panel */
  --pay-green:#2fd36b;
}

.game-price .was{color:var(--accent);text-decoration-line:line-through;
  text-decoration-color:var(--was-red);text-decoration-thickness:2.5px}
.game-price .now{color:var(--pay-green)}

/* nothing off: a plain near-white price, kept clear of the blue used for
   links and buttons so it never reads as something to click */
.game-price.no-sale .now{color:var(--accent)}

.gp-price .was{color:var(--accent);text-decoration-line:line-through;
  text-decoration-color:var(--was-red);text-decoration-thickness:2.5px}
.gp-price .now{color:var(--pay-green)}
.gp-price.no-sale .now{color:var(--accent)}


/* ==========================================================================
   FIVE TO A ROW on a desktop, two on a phone, stepping down in between so a
   card never gets narrower than its price line. The gap tightens as well:
   at five across, four wide gutters would eat most of a column.
   ========================================================================== */

.game-grid{grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(12px,1.4vw,20px)}

@media(max-width:1200px){ .game-grid{grid-template-columns:repeat(4,minmax(0,1fr))} }
@media(max-width:980px){  .game-grid{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media(max-width:760px){  .game-grid{grid-template-columns:repeat(2,minmax(0,1fr))} }

/* Five across leaves about 155px of text under each cover. At the sizes the
   wider layouts use, the price wrapped onto two and three lines there and the
   discount flag covered two thirds of the artwork, so both step down to suit
   the narrower card. They stay the largest thing on it. */
@media(min-width:1201px){
  .game-price{gap:8px}
  .game-price .now{font-size:1.5rem}
  .game-price .was{font-size:1.1rem}
  .is-store .store-was,.is-store .store-now{font-size:1.2rem}
  .game-off{font-size:.92rem;padding:8px 12px 8px 9px;gap:5px}
  .game-off svg{width:14px;height:14px}
  .game-title{font-size:1.16rem}
  .game-body{padding:15px 15px 17px;gap:6px}
  .game-cta{margin:0 15px 15px;font-size:.92rem;padding:11px 14px}
}

/* the game name, in plain white */
.game-title{color:#fff}
.gp-title{color:#fff}


/* ==========================================================================
   SEARCHING THE SHELF.
   With well over a hundred games on one page, a box to narrow it down.
   ========================================================================== */

.shelf-find{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin:0 0 clamp(20px,3vh,30px)}

/* The search was a dark box on a dark page and people could not find it, so it
   is dressed like the sort control beside it: a blue edge, a soft glow, a
   bright icon and a placeholder you can read. The text is 16px or more, or an
   iPhone zooms the whole page the moment the box is tapped. */
.find-box{position:relative;display:flex;align-items:center;flex:1 1 340px;max-width:560px}
.find-box .find-icon{position:absolute;left:15px;width:20px;height:20px;z-index:1;
  fill:var(--accent);pointer-events:none}
.find-box input{width:100%;
  background:linear-gradient(180deg,rgba(31,84,240,.22),rgba(31,84,240,.08)),var(--panel-2);
  color:var(--text-primary);
  border:1.5px solid var(--accent);border-radius:12px;
  padding:14px 44px 14px 47px;font-family:var(--body);font-size:1.05rem;font-weight:600;line-height:1.2;
  box-shadow:0 0 0 3px rgba(31,84,240,.14),0 0 24px rgba(31,84,240,.28)}
.find-box input::placeholder{color:rgba(238,242,251,.78);opacity:1;font-weight:500}
.find-box input:hover{border-color:#6f9bff;box-shadow:0 0 0 3px rgba(31,84,240,.2),0 0 30px rgba(31,84,240,.4)}
.find-box input:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent;
  box-shadow:0 0 0 3px rgba(31,84,240,.2),0 0 30px rgba(31,84,240,.4)}
.find-box input::-webkit-search-cancel-button{display:none}

.find-clear{position:absolute;right:8px;width:30px;height:30px;line-height:1;
  border:0;border-radius:50%;background:transparent;color:rgba(238,242,251,.78);
  font-size:1.4rem;cursor:pointer}
.find-clear:hover{color:var(--text-primary);background:rgba(255,255,255,.1)}

/* ---------- putting the shelf in an order ----------
   Built on a real <select>, so a phone opens its own wheel and a keyboard
   works without being taught to. The browser will not style the closed box
   the way the search field is styled, so the arrow is switched off and one of
   ours is drawn over the top. */
.find-sort{display:flex;align-items:center;gap:10px;flex:0 0 auto}
.find-sort-lab{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);white-space:nowrap;font-weight:700}

.find-sort-box{position:relative;display:inline-flex;align-items:center}
.find-sort-box select{
  appearance:none;-webkit-appearance:none;-moz-appearance:none;
  background:linear-gradient(180deg,rgba(31,84,240,.22),rgba(31,84,240,.08)),var(--panel-2);
  color:var(--text-primary);
  border:1.5px solid var(--accent);border-radius:12px;
  padding:13px 42px 13px 16px;font-family:var(--body);font-size:1rem;font-weight:700;
  line-height:1.2;cursor:pointer;
  box-shadow:0 0 0 3px rgba(31,84,240,.14),0 0 24px rgba(31,84,240,.28)}
.find-sort-box select:hover{border-color:#6f9bff;box-shadow:0 0 0 3px rgba(31,84,240,.2),0 0 30px rgba(31,84,240,.4)}
.find-sort-box select:focus-visible{outline:2px solid var(--accent);outline-offset:1px;
  border-color:transparent}
.find-sort-chev{position:absolute;right:13px;width:18px;height:18px;
  fill:var(--accent);pointer-events:none}

/* the open list is drawn by the operating system, so the most we can ask for
   is that its rows are not white on a dark page */
.find-sort-box select option{background:var(--panel);color:var(--text-primary)}

.find-count{margin:0;font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-secondary)}

.find-none{margin:clamp(24px,5vh,44px) 0 0;text-align:center;color:var(--text-secondary)}
.find-none a{color:var(--accent)}

.game[hidden]{display:none}

@media(max-width:560px){
  .shelf-find{gap:10px}
  .find-box{flex:1 1 100%}
  /* the search takes the first line to itself; the sort and the count share
     the second, so neither is squeezed into a strip */
  .find-sort{flex:1 1 auto}
  .find-sort-box,.find-sort-box select{width:100%}
}


/* ==========================================================================
   THE SHELF DOES NOT ANIMATE.
   The cards used to fade up as they came into view, which read as the games
   loading late on scroll. They are drawn once and they stay put. These rules
   sit last so they beat the reveal choreography further up the file.
   ========================================================================== */

.game,
.game.reveal,
.game.reveal.in,
.js .game,
.js .game.reveal,
.js .game.reveal.in{
  opacity:1 !important;
  transform:none !important;
  transition:none !important;
  animation:none !important;
}

/* the discount flag popped in with the card; it is simply on the cover now */
.game .game-off,
.game.in .game-off{animation:none !important;opacity:1}

/* the search box sits with the shelf, so it does not fade in either */
.shelf-find,.shelf-find.reveal,.plat-pick{opacity:1 !important;transform:none !important}

/* ==========================================================================
   THE POLICY PAGES
   Terms, refunds, warranty and privacy. They borrow the shop's chrome and
   its tokens; everything here is about reading a long document on a dark
   page — a measure that does not run away, a spine you can navigate from,
   and one box per page that says the thing in a sentence.
   ========================================================================== */
/* long prose needs a calmer ground than the shelf does: the circuitry stays,
   but it stops competing with the sentences */
.page-legal .body-wrap{background:linear-gradient(to bottom,rgba(5,5,12,.90),rgba(5,5,12,.94))}
.page-legal .body-wrap section{padding-bottom:clamp(56px,8vh,96px)}

.legal-head{max-width:64ch;margin-bottom:clamp(26px,4vh,40px)}
.legal-h{
  font-family:var(--display);font-weight:800;text-transform:uppercase;
  font-size:clamp(2.4rem,6.4vw,4.4rem);line-height:.92;letter-spacing:.01em;
  color:var(--text-primary);text-shadow:var(--tshadow);
}
.legal-meta{
  margin-top:16px;font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-secondary);
}
.legal-lede{margin-top:18px;font-size:1.1rem;line-height:1.68;color:var(--text-secondary)}

/* the four documents, one row — you are always one tap from the other three */
.legal-switch{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 clamp(26px,4vh,42px)}
.legal-switch a{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.15em;text-transform:uppercase;
  color:var(--text-secondary);text-decoration:none;padding:11px 17px;
  background:rgba(143,163,200,.06);box-shadow:inset 0 0 0 1px rgba(143,163,200,.22);
  transition:color .3s var(--ease),background .3s var(--ease),transform .3s var(--ease);
}
.legal-switch a:hover{color:var(--text-primary);background:rgba(143,163,200,.13);transform:translateY(-2px)}
.legal-switch a[aria-current="page"]{
  color:#050a1c;background:var(--accent);box-shadow:0 8px 26px rgba(111,155,255,.24);
}

.legal-grid{
  display:grid;grid-template-columns:minmax(190px,220px) minmax(0,1fr);
  gap:clamp(26px,4vw,64px);align-items:start;
}
.legal-toc{position:sticky;top:92px}
.legal-toc .toc-t{
  font-family:var(--mono);font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--accent);margin-bottom:12px;
}
.legal-toc ol{list-style:none;margin:0;padding:0}
.legal-toc a{
  display:block;padding:7px 0 7px 14px;border-left:2px solid var(--line);
  color:var(--text-secondary);text-decoration:none;font-size:.86rem;line-height:1.35;
  transition:color .3s var(--ease),border-color .3s var(--ease);
}
.legal-toc a:hover{color:var(--accent);border-left-color:var(--accent)}

/* on a phone the spine becomes a lid you can open, so it costs no scroll */
@media (max-width:900px){
  .legal-grid{grid-template-columns:1fr}
  .legal-toc{position:static;margin-bottom:26px}
  .legal-toc .toc-t{margin-bottom:0;cursor:pointer;padding:12px 14px;
    background:rgba(143,163,200,.06);box-shadow:inset 0 0 0 1px rgba(143,163,200,.22)}
  .legal-toc ol{margin-top:8px}
}

.legal-doc{max-width:70ch}
.legal-doc h2{
  font-family:var(--display);font-weight:800;text-transform:uppercase;
  font-size:clamp(1.45rem,2.7vw,2.05rem);line-height:1.04;color:var(--text-primary);
  margin:clamp(36px,5vh,56px) 0 15px;scroll-margin-top:100px;
}
.legal-doc h2:first-child{margin-top:0}
.legal-doc h2 .n{
  font-family:var(--mono);font-size:.72rem;font-weight:500;letter-spacing:.14em;
  color:var(--accent);display:block;margin-bottom:7px;
}
.legal-doc h3{
  font-family:var(--body);font-size:1rem;font-weight:700;color:var(--text-primary);
  margin:24px 0 9px;
}
.legal-doc p{margin:0 0 14px;line-height:1.74;color:var(--text-secondary)}
.legal-doc strong{color:var(--text-primary);font-weight:700}
.legal-doc a{color:var(--accent);text-underline-offset:3px}
.legal-doc a:hover{color:var(--accent-hover)}

.legal-doc ul{list-style:none;margin:0 0 16px;padding:0;display:grid;gap:9px}
.legal-doc li{position:relative;padding-left:25px;line-height:1.66;color:var(--text-secondary)}
.legal-doc li::before{
  content:"";position:absolute;left:4px;top:.64em;width:7px;height:7px;
  background:var(--accent);opacity:.75;transform:rotate(45deg);
}
/* what you get back, and what you do not: the mark carries it, not the colour */
.legal-doc ul.yes li::before{background:#2fd36b;opacity:.9;transform:none;
  clip-path:polygon(14% 44%,0 58%,42% 100%,100% 22%,86% 8%,42% 72%)}
.legal-doc ul.no li::before{background:var(--deal);opacity:.9;transform:none;
  clip-path:polygon(10% 0,50% 40%,90% 0,100% 10%,60% 50%,100% 90%,90% 100%,50% 60%,10% 100%,0 90%,40% 50%,0 10%)}
.legal-doc ul.yes li::before,.legal-doc ul.no li::before{width:11px;height:11px;left:2px;top:.5em}

/* the numbered walk-through: how a claim actually goes */
.legal-steps{list-style:none;margin:0 0 16px;padding:0;display:grid;gap:11px;counter-reset:st}
.legal-steps li{
  counter-increment:st;position:relative;padding-left:44px;line-height:1.66;
  color:var(--text-secondary);
}
.legal-steps li::before{
  content:counter(st,decimal-leading-zero);position:absolute;left:0;top:.06em;
  font-family:var(--mono);font-size:.78rem;color:var(--accent);
  background:rgba(111,155,255,.1);box-shadow:inset 0 0 0 1px rgba(111,155,255,.3);
  width:30px;height:26px;display:grid;place-items:center;
}

/* the one box a reader should not be able to miss */
.legal-note{
  margin:0 0 clamp(26px,4vh,38px);padding:22px 24px;
  background:linear-gradient(150deg,rgba(31,84,240,.16),rgba(169,124,255,.07));
  box-shadow:inset 0 0 0 1px rgba(111,155,255,.34);
  border-radius:var(--cut) 2px var(--cut) 2px;
}
.legal-note .t{
  display:block;font-family:var(--mono);font-size:.66rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent);margin-bottom:10px;
}
.legal-note p{margin:0;color:var(--text-primary);font-size:1.05rem;line-height:1.62}
.legal-note p + p{margin-top:10px}

/* primary and secondary, side by side, because that is how they are chosen */
.legal-cards{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:14px;margin:0 0 18px;
}
.legal-card{
  padding:19px 21px;background:var(--panel);box-shadow:inset 0 0 0 1px var(--line);
  border-radius:var(--cut) 2px var(--cut) 2px;
}
.legal-card h4{
  font-family:var(--display);font-weight:800;font-size:1.3rem;text-transform:uppercase;
  color:var(--text-primary);margin-bottom:8px;
}
.legal-card p{margin:0;font-size:.94rem;line-height:1.62}

.legal-end{
  margin-top:clamp(38px,6vh,60px);padding-top:22px;border-top:1px solid var(--line);
}
.legal-end p{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-secondary);margin:0 0 8px;line-height:1.7;
}
.legal-end a{color:var(--accent);text-decoration:none}
.legal-end a:hover{color:var(--accent-hover)}

/* the footer gains a policy row on every page of the shop */
.foot-legal{
  max-width:var(--maxw);margin:22px auto 0;display:flex;flex-wrap:wrap;gap:10px 22px;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;
}
.foot-legal a{color:var(--text-secondary);text-decoration:none;transition:color .3s var(--ease)}
.foot-legal a:hover{color:var(--accent)}
