@font-face{
  font-family:'Press Start 2P';
  src:url('../fonts/press-start-2p-latin.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
}

:root{
  --yellow:#fff200;
  --cyan:#00faff;
  --yellow-lt:#fff9a0;
  --green:#55c232;
  --orange:#ff7b00;
  --grey:#4d4d4d;
  --k:1;
  --font-pixel:'Press Start 2P',monospace;
  --font-body:"Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-ui:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",Arial,sans-serif;
  --font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
}

*{box-sizing:border-box}
html{background:#000}
body{
  margin:0;padding:0 0 44px;
  /* the star tile lives on the page, not inside the 1440 frame: past 1728px the frame
     stops growing, and without this the hero art ended in two dead black bands. It is
     also what keeps a phone from getting a flat black hero, since every positioned
     decoration is dropped below 1180. The flat gradient on top is the dimmer. */
  background:linear-gradient(rgba(0,0,0,.66),rgba(0,0,0,.66)),
             url('../img/star-tile.webp') 0 0/512px 512px repeat,#000;
  color:#fff;
  font-family:var(--font-body);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:none}
a{text-decoration:none;color:inherit}
p,h1,h2,ul{margin:0}
ul{padding:0;list-style:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0}

/* ------------------------------------------------------------- frame system
   Each section is one 1440px-wide Figma frame. Children sit at their exact
   design coordinates via --l/--t/--w/--h, and the frame is scaled by --k
   (set in main.js) so the composition never reflows on desktop. */
/* transparent, not black: the sky on <body> has to show through beside the frame */
.fr{position:relative;width:100%;height:calc(var(--fh) * 1px * var(--k));overflow:hidden}
.fr__in{
  position:absolute;top:0;left:50%;margin-left:-720px;
  width:1440px;height:calc(var(--fh) * 1px);
  transform:scale(var(--k));transform-origin:50% 0;
}
.a{position:absolute;left:var(--l);top:var(--t);width:var(--w);height:var(--h)}

.hero-mask{background:radial-gradient(70% 60% at 50% 42%,rgba(0,0,0,0) 0%,rgba(0,0,0,.8) 100%)}

/* the figma hero art is drawn 42px wider and 149px taller than the frame, so the
   sky can drift inside that bleed without ever exposing an edge */
.bg-drift{animation:bg-drift 54s ease-in-out infinite alternate}
@keyframes bg-drift{from{transform:translate3d(0,0,0)}to{transform:translate3d(-22px,-18px,0)}}

/* two parallax layers of the same seamless tile: the travel per cycle is exactly one
   tile in each axis, so the drift never shows a seam */
/* the layers travel by transform: animating background-position repainted the whole
   1440x1254 box on the main thread every frame */
/* the twinkle used to be an opacity animation on this box while both children
   animated their transform — that nests an animated surface inside an animated
   surface, so the whole 1440x1254 region was recomposited every frame. The fade
   now rides on one of the drifting layers instead, which costs nothing extra. */
/* wider than the frame it sits in, so the drifting layer keeps going on a 2560px
   screen instead of stopping at the frame edge. A repeating tile costs nothing to
   widen, unlike the hero photograph. */
.starfield{overflow:hidden;opacity:.55;left:-320px;width:2080px}
.starfield i{
  position:absolute;left:0;
  background-image:url(../img/star-tile.webp);background-repeat:repeat;
  animation:star-drift 48s linear infinite;
}
.starfield i:first-child{
  top:-512px;width:calc(100% + 512px);height:calc(100% + 512px);
  background-size:512px 512px;--travel:512px;
}
.starfield i:last-child{
  top:-320px;width:calc(100% + 320px);height:calc(100% + 320px);
  background-size:320px 320px;background-position:120px 60px;--travel:320px;
  animation:star-drift 48s linear infinite,star-twinkle 6s ease-in-out infinite;
}
@keyframes star-drift{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(calc(var(--travel) * -1),var(--travel),0)}
}
@keyframes star-twinkle{0%,100%{opacity:1}50%{opacity:.45}}
.twinkle{animation:twinkle 7s ease-in-out infinite}
#build .twinkle{animation-delay:-2.4s}
#motion .twinkle{animation-delay:-4.1s}
#start .twinkle{animation-delay:-5.6s}
@keyframes twinkle{0%,100%{opacity:1}50%{opacity:.55}}

/* a frame that is not on screen has nothing worth animating; main.js flags them */
.fr.is-off,.fr.is-off *{animation-play-state:paused}

/* ---------------------------------------------------------------------- header */
/* the bar rides along with the scroll; the padding keeps it aligned with the
   1440 frame's edges once the frame stops growing (--k caps at 1.2 = 1728px) */
.hdr{
  position:fixed;inset:0 0 auto 0;z-index:60;
  display:flex;align-items:flex-start;justify-content:space-between;
  padding:20px max(32px,calc((100vw - 1728px) / 2 + 38px)) 16px max(20px,calc((100vw - 1728px) / 2 + 24px));
  background:linear-gradient(180deg,rgba(0,0,0,.9),rgba(0,0,0,.55) 55%,rgba(0,0,0,0));
  transition:background .25s ease,border-color .25s ease;
  border-bottom:1px solid transparent;
}
/* no backdrop-filter here: at this alpha the blur is invisible, but it made the
   browser re-blur the strip behind a fixed bar on every frame — and over the hero
   the source is a moving starfield, so the result could never be reused */
.hdr.is-stuck{
  background:rgba(6,6,0,.96);
  border-bottom-color:rgba(255,242,0,.28);
}
.brand{display:flex;align-items:center;gap:8px;height:36px}
.brand__word{
  font-family:var(--font-pixel);font-size:14.4px;line-height:17.1px;color:var(--yellow);
  text-shadow:0 1px 0 var(--yellow),0 1px 4px rgba(254,247,113,.45),0 1px 12px #ff922d,0 1px 3px #f08000;
}
.hdr__nav{display:flex;align-items:center;gap:12px;height:28px;margin-top:4px}
.hdr__nav a{font-size:16px;line-height:20px;color:#fff;padding:4px}
.hdr__nav a:hover{color:var(--yellow)}

/* ----------------------------------------------------------------- typography */
.ttl-hero{
  font-family:var(--font-pixel);font-size:82.2px;line-height:109.6px;
  text-align:center;color:var(--yellow);white-space:nowrap;
  /* figma stacks four copies of the glyphs upward 2.88px apart, and only the
     backmost one carries the orange glow — blurring the steps themselves is what
     made this look out of focus */
  text-shadow:
    0 -2.6px 0 var(--yellow),0 -5.2px 0 var(--yellow),0 -7.7px 0 var(--yellow),0 -10.3px 0 var(--yellow),
    0 4px 18px #f08000,0 4px 26px rgba(254,247,113,.45),0 4px 78px #ff922d;
}
/* value proposition, between the wordmark and the tagline: pixel font like the
   headings but two weights of the palette, so it reads as a claim and not a
   second title competing with HOLY MOLLY */
.vprop{
  font-family:var(--font-pixel);font-size:19px;line-height:32px;
  text-align:center;white-space:nowrap;color:var(--cyan);
  text-shadow:0 0 3px rgba(0,250,255,.85),0 0 16px rgba(0,250,255,.4),0 2px 0 rgba(0,0,0,.9);
}
.vprop b{
  display:block;font-weight:400;font-size:23px;line-height:40px;color:var(--yellow-lt);
  text-shadow:0 0 3px var(--yellow),0 0 18px rgba(255,242,0,.5),0 2px 0 rgba(0,0,0,.9);
}
.ttl-42{
  font-family:var(--font-pixel);font-size:39.9px;line-height:50.4px;white-space:nowrap;
  color:#000;-webkit-text-stroke:1.2px var(--yellow);
  text-shadow:2px 3px 1px var(--yellow),0 0 10px rgba(255,242,0,.45);
}
.ttl-80{
  font-family:var(--font-pixel);font-size:78px;line-height:96px;text-align:center;white-space:nowrap;
  background:linear-gradient(180deg,#fffde8 0%,#fff200 36%,#ffa515 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(2px 3px 0 rgba(255,242,0,.5)) drop-shadow(0 0 14px rgba(255,146,45,.75));
}
/* figma gives this copy a 1px black OUTSIDE stroke, not a shadow — a 2px centred
   stroke painted under the fill reads as 1px outside */
.body-20{font-size:20px;line-height:24px;color:#fff;
  -webkit-text-stroke:2px #000;paint-order:stroke fill}
.body-20--c{text-align:center}
.ui-15{font-family:var(--font-ui);font-size:15px;line-height:18px;font-weight:500}
.c-green{color:var(--green)}
.mono-label{
  font-family:var(--font-mono);font-size:16px;line-height:20px;font-weight:600;letter-spacing:-.48px;
  color:var(--orange);white-space:nowrap;
  text-shadow:0 0 2px var(--orange),0 0 8px rgba(255,123,0,.6);
}
/* figma prototype: 7 frames at 300ms — single characters drop to near-black and come
   back; the glyphs never move, so the dimming is done per character, not by a mask */
.mono-label i{font-style:normal}
.mono-label i.is-dim{opacity:.18}

/* -------------------------------------------------------------------- buttons */
.btn{
  display:flex;align-items:center;border-radius:2000px;
  background:#000;border:1px solid var(--yellow);
  box-shadow:0 2.5px 1px var(--yellow),inset 0 0 9.5px var(--yellow),0 4px 14px rgba(0,0,0,.45);
  color:var(--yellow);cursor:pointer;
}
/* figma prototype: the button state change is a 300ms ease-out smart-animate */
.btn{transition:box-shadow .3s ease-out}
.btn:hover{box-shadow:0 2.5px 2px var(--yellow),inset 0 0 14px var(--yellow),0 0 22px rgba(255,242,0,.4)}
.btn:active{box-shadow:0 2.5px 3px var(--yellow),inset 0 0 20px var(--yellow),0 0 34px rgba(255,242,0,.65)}
.btn__label{font-size:20px;line-height:20px;font-weight:500;white-space:nowrap}
/* figma: agent at 8, label ink 95..221, chevron 233..241 inside a 266px pill —
   the 22px label used to run 15px long and push the chevron onto the border */
.btn--l{gap:0;padding:0 20px 0 8px}
.btn--l .btn__label{margin-left:16px}
.btn--l .chev{margin-left:12px}
.btn--m,.btn--m2{justify-content:center;gap:4px}
.chev{
  width:8px;height:14px;flex:0 0 auto;background:var(--yellow);margin-left:6px;
  clip-path:polygon(0 0,25% 0,25% 14%,50% 14%,50% 29%,75% 29%,75% 43%,100% 43%,100% 57%,75% 57%,75% 71%,50% 71%,50% 86%,25% 86%,25% 100%,0 100%);
}
.btn--m .chev,.btn--m2 .chev{margin-left:4px}

/* the mascot is a 6-frame kaomoji face in figma (cyan brows + yellow mouth glyphs);
   the frames are the rendered variants themselves, so nothing is re-drawn by hand */
.agent{
  display:block;flex:0 0 auto;width:69px;height:48px;
  background:url(../img/agent-sprite.webp) 0 0/600% 100% no-repeat;
  animation:agent-face 4.8s steps(1,end) infinite;
}
@keyframes agent-face{
  0%   {background-position:0 0}
  16.6%{background-position:20% 0}
  33.3%{background-position:40% 0}
  50%  {background-position:60% 0}
  66.6%{background-position:80% 0}
  83.3%{background-position:100% 0}
}
/* the message box uses the 5-frame 'ange' set — a different face cycle, 800ms too */
.agent--sm{
  width:64px;height:64px;
  background-image:url(../img/msgagent-sprite.webp);background-size:500% 100%;
  animation:msg-face 4s steps(1,end) infinite;
}
@keyframes msg-face{
  0% {background-position:0 0}
  20%{background-position:25% 0}
  40%{background-position:50% 0}
  60%{background-position:75% 0}
  80%{background-position:100% 0}
}

.btn-s{
  display:flex;align-items:center;justify-content:center;gap:6px;border-radius:999px;
  background:#2b2b2b;color:#fff;font-family:var(--font-ui);font-size:13px;font-weight:500;
}
.btn-s svg{width:14px;height:14px;fill:var(--yellow)}
.btn-s:hover{background:#3a3a3a}
.btn-s--go{
  background:#000;border:1px solid var(--yellow);color:var(--yellow);
  font-size:15px;box-shadow:0 0 8px rgba(255,242,0,.35),inset 0 0 6px rgba(255,242,0,.35);
}

/* decorative layers are often full-frame boxes; none of them should ever be a click
   target, whatever their position in the stacking order */
.deco{pointer-events:none}

/* ------------------------------------------------------------- hero card deck */
/* the deck box spans the whole hero, so it sat on top of the GO EXPLORE button and
   ate the click. Only the cards need to be hit-testable; the drag handlers on the
   deck still fire because the events bubble up from the cards. */
.deck{position:absolute;left:0;top:0;width:1440px;height:1254px;pointer-events:none}
.dcard{pointer-events:auto}
/* every card is laid out at the centre slot's size and only ever moved by a
   transform: animating left/top/width/height instead re-ran layout, re-clipped the
   silhouette and re-blurred four drop-shadows on every frame of the 800ms slide */
.dcard{
  left:536px;top:570px;width:368px;height:480px;
  transform-origin:0 0;transform:var(--tf,none);
  border-radius:40px;padding:3px;
  background:radial-gradient(circle at 22% 16%,var(--yellow-lt),var(--yellow));
  /* figma card silhouette: bevelled top-left + notched left/right shoulders */
  clip-path:url(#clip-card-deck);
  /* three shadows, not four: the fourth was a 42px blur, and a blur that wide has to
     be re-rasterised for every card that is on screen — it cost more than it showed */
  filter:drop-shadow(1px 1px 2px var(--yellow)) drop-shadow(-1px -1px 2px var(--yellow-lt))
         drop-shadow(0 14px 28px rgba(0,0,0,.85));
  /* figma prototype: the deck drag is an 800ms ease-out smart-animate */
  transition:transform .8s ease-out,opacity .5s ease-out;
  /* no will-change: it pinned all fourteen cards to their own composited layer for
     the whole life of the page, each one carrying a clip-path and a filter chain.
     A transform transition gets promoted while it runs and released afterwards. */
  cursor:pointer;
}
.dcard__in{position:relative;width:100%;height:100%;overflow:hidden;background:#000;clip-path:url(#clip-card-deck)}
/* the side slots are a narrower crop of the same artwork, not a squashed copy, so the
   picture cancels out the card's horizontal squeeze and gets clipped instead */
.dcard__in img{width:100%;height:100%;object-fit:cover;display:block;
  transform:scaleX(var(--isx,1));transition:transform .8s ease-out}
/* figma dims the artwork with a 60% black plate that sits inside the 3px border,
   so the cyan/yellow edge and the gradient title stay at full strength */
.dcard__dim{position:absolute;inset:3px;z-index:3;background:rgba(0,0,0,.62);
  clip-path:url(#clip-card-deck);opacity:1;transition:opacity .5s ease-out}
.dcard.is-active .dcard__dim{opacity:0}
/* figma dims the off-centre cards, ring included, to ~45% */

.dcard.is-active{z-index:5}
/* the deck holds more cards than it has slots — the surplus waits off-frame */
.dcard.is-parked{opacity:0;pointer-events:none}
/* the eight cards waiting at the right-hand park are not going anywhere this beat,
   so they are taken out of painting entirely — otherwise the hero was compositing
   fourteen clipped, shadowed cards to show five. The card sliding out to the left
   keeps its transition and stays visible while it fades. */
.dcard.no-anim{transition:none;visibility:hidden}

.cmeta{position:absolute;left:0;right:0;bottom:20px;z-index:4}
.cmeta__name{
  /* 7.2% is the horizontal inset of the card silhouette's bottom shoulder */
  padding:0 calc(7.2% + 20px);font-size:20px;line-height:24px;font-weight:500;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  /* figma: white -> yellow -> cyan radial fill with a 1px black outside stroke.
     the fill is transparent, so text-shadow would show straight through the glyph and
     text-stroke would eat into it — drop-shadow traces the painted gradient instead */
  background:radial-gradient(circle at 20% 20%,#fff 17%,var(--yellow) 54%,var(--cyan) 94%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(1px 0 0 #000) drop-shadow(-1px 0 0 #000)
         drop-shadow(0 1px 0 #000) drop-shadow(0 -1px 0 #000);
}
.cmeta__row{
  display:flex;align-items:center;justify-content:space-between;
  margin-top:4px;padding:0 calc(7.2% + 20px);font-size:16px;line-height:20px;color:#fff;text-shadow:0 1px 2px #000;
}
.fire{display:flex;align-items:center;gap:4px}
.fire svg{width:20px;height:20px;fill:#fff}
.cmeta--lg .cmeta__name{font-size:28px;line-height:33.6px}
.cmeta--lg .cmeta__row{font-size:18px;line-height:24px}
.cmeta--lg .fire svg{width:24px;height:24px}

.dnav{display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:8}
.dnav img{width:24px;height:40px;filter:drop-shadow(0 0 6px rgba(255,242,0,.6))}
.dnav:hover img{filter:drop-shadow(0 0 12px var(--yellow))}

/* ------------------------------------------------------------- prompt / input */
.inputbox{background:#121212;border:1px solid var(--grey);border-radius:20px}
.ptext{font-size:16px;line-height:24px;color:#fff}
.caret{display:inline-block;width:8px;height:15px;margin-left:2px;vertical-align:-2px;
  background:var(--yellow);box-shadow:0 0 8px rgba(255,242,0,.7);
  animation:caret-blink 1s steps(1,end) infinite}
@keyframes caret-blink{50%{opacity:0}}
.tok{color:var(--orange);font-family:var(--font-ui);font-weight:500}
.tok__ic{width:20px;height:20px;vertical-align:-4px;object-fit:contain}
.tools{display:flex;align-items:center;gap:16px}
.tools span{display:flex;align-items:center;justify-content:center;width:24px;height:24px}
.tools svg{width:22px;height:22px;fill:#fff}
.tools__3d svg{fill:var(--yellow);width:26px;height:26px}

/* --------------------------------------------------------- frame 7 · terminal */
.msgbox{background:#000;border:1px solid var(--yellow);border-radius:20px;box-shadow:0 0 14px rgba(255,242,0,.18)}
.tasklist li{color:#fff;font-family:var(--font-ui);font-size:15px;line-height:18px;font-weight:400}
.tasklist li.dim{color:#cfcfcf}
.plusgrid{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42'%3E%3Cpath d='M21 17v8M17 21h8' stroke='%23343434' stroke-width='1.6'/%3E%3C/svg%3E");
  -webkit-mask-image:radial-gradient(60% 60% at 50% 50%,#000 0%,transparent 100%);
  mask-image:radial-gradient(60% 60% at 50% 50%,#000 0%,transparent 100%);
}
.dots{
  background-image:radial-gradient(circle at 2.5px 2.5px,var(--grey) 2.5px,transparent 2.6px);
  background-size:8.5px 8.5px;background-position:2px 2px;
}
.flower{height:auto;filter:drop-shadow(0 0 5px rgba(85,194,50,.7))}

/* --------------------------------------------------------- generic game cards */
.dcard .cmeta__name,.cmeta--row .cmeta__name{
  background:radial-gradient(140% 260% at 18% 24%,#fff 0%,#fff 38%,var(--yellow) 74%,var(--cyan) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.dcard.is-active .cmeta__name{font-size:28px;line-height:33.6px}
.dcard.is-active .cmeta__row{font-size:18px;line-height:24px}
.dcard.is-active .fire svg{width:24px;height:24px}
.gcard{position:relative;
  border-radius:var(--r,32px);padding:var(--bw,2px);
  background:radial-gradient(circle at 22% 16%,var(--yellow-lt),var(--yellow));
  box-shadow:1px 1px 3px var(--yellow),-1px -1px 3px var(--yellow-lt),0 18px 46px rgba(0,0,0,.55);
}
.gcard__in{
  position:relative;width:100%;height:100%;overflow:hidden;background:#000;
  border-radius:calc(var(--r,32px) - var(--bw,2px));
}
.gcard__in img{width:100%;height:100%;object-fit:cover;display:block}
/* figma prototype gives this card a 200ms ease-out hover state (its target variant
   is still empty in the file, so this is the mildest reading of it) */
.gcard--crop7{clip-path:url(#clip-card-lg);transition:filter .2s ease-out}
.gcard--crop7:hover{filter:brightness(1.06)}
.gcard--crop7 .gcard__in{clip-path:url(#clip-card-lg)}
.gcard__vid{width:100%;height:100%;object-fit:cover;display:block;background:#000}

/* ------------------------------------------------------- frame 8 · asset panel */
.model{overflow:hidden}
.model img{position:absolute;left:0;top:0;width:642px;height:680px;object-fit:cover}
/* the still stays as the poster: it is what shows over file:// and until the glb lands */
.model model-viewer{position:absolute;inset:0;width:100%;height:100%;background:transparent;
  --poster-color:transparent;outline:none}
.model.is-live img{opacity:0}
.model__hint{
  position:absolute;left:50%;bottom:18px;transform:translateX(-50%);opacity:0;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;color:rgba(255,255,255,.72);
  background:rgba(0,0,0,.45);border:1px solid rgba(255,255,255,.18);border-radius:999px;
  padding:5px 12px;pointer-events:none;transition:opacity .4s ease-out;white-space:nowrap;
}
.model.is-live .model__hint{opacity:1}
.model.is-held .model__hint{opacity:0}
.panel{background:#121212;border:1px solid #333;border-radius:20px;box-shadow:0 20px 48px rgba(0,0,0,.6)}
.drop{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  background:#1f1f1f;border-radius:12px;color:#ccc;
}
.drop svg{fill:#ccc}
.drop span{font-family:var(--font-ui);font-size:15px;line-height:18px;font-weight:500}
.btn-3d{
  display:flex;align-items:center;justify-content:center;gap:2px;
  background:#000;border:1.2px solid var(--yellow);border-radius:2000px;color:var(--yellow);
  font-family:var(--font-ui);font-size:16px;font-weight:600;
  box-shadow:0 0 10px rgba(255,242,0,.3),inset 0 0 8px rgba(255,242,0,.28);
}
.btn-3d svg{fill:var(--yellow)}
.btn-3d:hover{box-shadow:0 0 20px rgba(255,242,0,.55),inset 0 0 12px rgba(255,242,0,.4)}
.thumb{
  border-radius:20px;background:rgba(255,255,255,.03);border:1px solid #333;
  transform:rotate(-8deg);overflow:hidden;
  box-shadow:0 5px 11px rgba(0,0,0,.25),1px 20px 20px rgba(0,0,0,.22),3px 45px 27px rgba(0,0,0,.13);
}
.thumb__bleed{position:absolute;left:-43px;top:-33px;width:324px;height:297px;object-fit:cover;filter:blur(15px)}
.thumb__in{position:absolute;left:9px;top:9px;width:226px;height:226px;border-radius:12px;overflow:hidden}
.thumb__in img{width:100%;height:100%;object-fit:cover;display:block}
/* figma prototype: 2-frame pixel walk cycle, 300ms per frame */
.turtle{
  background:url(../img/turtle-sprite.webp) 0 0/200% 100% no-repeat;
  animation:turtle-walk .6s steps(1,end) infinite;
}
@keyframes turtle-walk{50%{background-position:100% 0}}
.cursor{filter:drop-shadow(0 4px 6px rgba(0,0,0,.6))}

/* --------------------------------------------------------- frame 9 · hotspots */
/* the assembled hull and the five parts occupy the same stage; only one is opaque
   at a time, and the parts travel --dx/--dy on the way out */
/* the hull plate is the design's 860x425.84 box plus a 30px margin on every side, which
   is what holds the rim glow — so the box is 920x486 offset -30,-30 from the design box */
.split__whole{position:absolute;left:486px;top:152px;width:920px;height:486px;object-fit:fill;
  transition:opacity .55s ease-out}
.split__part{position:absolute;left:var(--l);top:var(--t);width:var(--w);height:var(--h);
  object-fit:fill;opacity:0;transform:translate(var(--dx),var(--dy)) scale(.94);
  transition:opacity .5s ease-out,transform .9s cubic-bezier(.22,.85,.25,1)}
.split.is-split .split__whole{opacity:0}
.split.is-split .split__part{opacity:1;transform:none}
/* the body barely moves, so it leads and the outer parts trail behind it */
.split__part:nth-of-type(4){transition-delay:0s}
.split__part:nth-of-type(6){transition-delay:.06s}
.split__part:nth-of-type(2){transition-delay:.10s}
.split__part:nth-of-type(5){transition-delay:.13s}
.split__part:nth-of-type(3){transition-delay:.16s}
.split .chip{transition:transform .9s cubic-bezier(.22,.85,.25,1)}
.split.is-split .chip{transform:translate(var(--dl),var(--dt))}
.chip{
  display:inline-flex;align-items:center;gap:8px;padding:6px 10px;width:auto;
  background:rgba(85,194,50,.34);border:1px solid rgba(85,194,50,.85);
  font-family:var(--font-mono);font-size:15px;line-height:18px;font-weight:600;letter-spacing:-.45px;
  color:var(--green);white-space:nowrap;
  box-shadow:0 2px 4px rgba(0,0,0,.3),0 6px 6px rgba(0,0,0,.26),0 15px 9px rgba(0,0,0,.15);
  text-shadow:0 0 5px rgba(85,194,50,.8);
}
.chip::before{content:"";width:8px;height:8px;flex:0 0 auto;background:var(--green);box-shadow:0 0 8px var(--green)}
.chip--y{background:rgba(255,242,0,.3);border-color:rgba(255,242,0,.85);color:var(--yellow);text-shadow:0 0 5px rgba(255,242,0,.8)}
.chip--y::before{background:var(--yellow);box-shadow:0 0 8px var(--yellow)}

/* ---------------------------------------------------------- frame 5 · closing */
.crad{overflow:hidden}
.crad{z-index:1}
/* figma prototype: one 372px card pitch per 10s linear, so 9 cards take 90s */
.crad__row{position:absolute;left:-391px;top:0;display:flex;animation:marquee 90s linear infinite;will-change:transform}
.gcard--row{flex:0 0 auto;width:372px;height:480px;--r:0px;--bw:0px;background:none;box-shadow:none}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-5208px)}}
.cmeta--row{bottom:60px}
.cmeta--row .cmeta__name,.cmeta--row .cmeta__row{padding:0 20px}
.lift{z-index:8}
.cmeta--row .cmeta__name{display:flex;align-items:center;gap:10px}
.badge{
  flex:0 0 auto;padding:4px 8px;background:#000;
  border:2px solid var(--yellow);border-radius:2px;
  font-family:var(--font-pixel);font-size:12px;line-height:12px;
  color:var(--yellow);-webkit-text-fill-color:var(--yellow);
  box-shadow:0 0 8px rgba(255,242,0,.5);
}
.badge--green{border-color:var(--green);color:var(--green);-webkit-text-fill-color:var(--green);box-shadow:0 0 8px rgba(85,194,50,.5)}
.badge--cyan{border-color:var(--cyan);color:var(--cyan);-webkit-text-fill-color:var(--cyan);box-shadow:0 0 8px rgba(0,250,255,.5)}

/* letterbox fade: solid at the strip's own edge, easing into the artwork. An ellipse
   cannot reach the corners, so these are full-width rectangles */
.emask{pointer-events:none;z-index:6}
.emask--t{background:linear-gradient(to bottom,#000 0%,rgba(0,0,0,.92) 30%,rgba(0,0,0,.55) 62%,rgba(0,0,0,0) 100%)}
.emask--b{background:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.55) 38%,rgba(0,0,0,.92) 70%,#000 100%)}

.gridfloor{
  overflow:hidden;
  -webkit-mask-image:linear-gradient(to top,#000 20%,transparent 98%);
  mask-image:linear-gradient(to top,#000 20%,transparent 98%);
}
.gridfloor > div{
  position:absolute;inset:0;
  background:url('../img/gridfloor.svg') no-repeat 0 0/1440px 193px;
  opacity:.55;
}
.gridfloor > div::after{content:"";position:absolute;inset:0;background:inherit;filter:blur(2px);opacity:.6}

.socials{display:flex;align-items:center;gap:20px;z-index:10}
.socials > span{font-size:15px;line-height:18px;color:#fff}
.socials a{display:flex;align-items:center;justify-content:center;width:18px;height:18px}
.socials svg{width:18px;height:18px;fill:#fff}
.socials a:hover svg{fill:var(--yellow)}

/* ------------------------------------------------------------------ expo strip */
.expo-strip{
  position:fixed;left:0;right:0;bottom:0;z-index:90;
  background:rgba(0,0,0,.94);border-top:1px solid rgba(255,242,0,.35);
}
.expo-strip a{display:flex;align-items:center;justify-content:center;gap:12px;flex-wrap:wrap;padding:12px 20px;text-align:center}
.expo-strip b{font-family:var(--font-pixel);font-size:10px;line-height:16px;color:var(--yellow)}
.expo-strip span{font-size:14px;color:#cfcfcf}
.expo-strip em{font-size:14px;font-style:normal;color:var(--yellow);border-bottom:1px solid rgba(255,242,0,.5)}

/* ============================================================== reserve page */
.shell{width:100%;max-width:1080px;margin:0 auto;padding:0 24px}
.site-header{position:relative;z-index:20;padding:20px 0}
.site-header__row{display:flex;align-items:center;justify-content:space-between}
.site-header__nav{display:flex;gap:16px}
.btn-ghost{
  display:inline-flex;align-items:center;gap:8px;padding:8px 16px;border-radius:999px;
  border:1px solid #333;font-size:14px;color:#cfcfcf;
}
.btn-ghost:hover{border-color:var(--yellow);color:var(--yellow)}
.section{position:relative}
.section__stars{
  position:absolute;inset:0;background:url('../img/stars.webp') center/cover no-repeat;opacity:.6;pointer-events:none;
}
.section__fade{position:absolute;inset:0;background:radial-gradient(70% 60% at 50% 30%,rgba(0,0,0,0),rgba(0,0,0,.85));pointer-events:none}
.reserve{padding:40px 0 96px}
.reserve__grid{position:relative;z-index:2;display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:56px;align-items:start}
.reserve__eyebrow{font-family:var(--font-mono);font-size:14px;font-weight:600;letter-spacing:.04em;color:var(--orange)}
.pixel{font-family:var(--font-pixel)}
.pixel--section{
  font-size:30px;line-height:44px;color:#000;-webkit-text-stroke:1.2px var(--yellow);
  text-shadow:2px 3px 1px var(--yellow),0 0 10px rgba(255,242,0,.4);
}
.reserve__title{margin-top:18px}
.reserve__lede{margin-top:22px;font-size:18px;line-height:28px;color:#d4d4d4}
.reserve__list{margin-top:26px;display:grid;gap:12px}
.reserve__list li{position:relative;padding-left:22px;font-size:16px;line-height:24px;color:#cfcfcf}
.reserve__list li::before{content:"";position:absolute;left:0;top:9px;width:8px;height:8px;background:var(--yellow);box-shadow:0 0 8px var(--yellow)}
.card-panel{background:#0d0d0d;border:1px solid #333;border-radius:20px;padding:28px}
.field + .field{margin-top:20px}
.field label{display:block;font-family:var(--font-ui);font-size:14px;font-weight:500;color:#9a9a9a;margin-bottom:8px}
.field input,.field select{
  width:100%;padding:14px 16px;background:#000;border:1px solid #333;border-radius:12px;
  color:#fff;font-size:16px;font-family:var(--font-body);
}
.field input:focus,.field select:focus{outline:none;border-color:var(--yellow);box-shadow:0 0 0 3px rgba(255,242,0,.15)}
.consent{display:flex;gap:12px;margin-top:22px;font-size:14px;line-height:20px;color:#a8a8a8}
.consent input{width:18px;height:18px;flex:0 0 auto;margin:1px 0 0}
.form__error{margin-top:14px;font-size:14px;line-height:20px;color:#ff6b6b;min-height:20px}
.btn--md{height:56px;padding:0 24px;justify-content:center}
.form__submit{width:100%;margin-top:6px}
.form__submit svg{fill:none;stroke:currentColor}
.form__note{margin-top:16px;font-size:13px;line-height:19px;color:#7d7d7d}
.success{text-align:center;padding:12px 0}
.success__mark{width:56px;height:56px;margin:0 auto 18px;display:flex;align-items:center;justify-content:center;border:1px solid var(--yellow);border-radius:50%;box-shadow:0 0 18px rgba(255,242,0,.35)}
.success h2{font-family:var(--font-pixel);font-size:18px;line-height:28px;color:var(--yellow)}
.success p{margin-top:14px;font-size:16px;line-height:24px;color:#cfcfcf}
.success code{font-family:var(--font-mono);color:#fff}

/* ============================================================= narrow screens
   Below 1180px the 1440 frame is abandoned: children go back into normal flow and
   the decorative layers are dropped. 1180 rather than 1024 because the frame scales
   with the viewport, and below it the 20px body copy fell under 16px. */
@media (max-width:1179px){
  .fr{height:auto;overflow:visible}
  .fr__in{
    position:static;width:auto;height:auto;margin:0;transform:none;
    display:flex;flex-direction:column;gap:22px;padding:48px 20px;
  }
  .a{position:static;left:auto;top:auto;width:auto;height:auto}
  .deco{display:none !important}

  body{padding-top:66px}
  .hdr{align-items:center;padding:12px 16px}
  .hdr__nav{gap:2px;margin-top:0}
  .hdr__nav a{font-size:12px;padding:2px}

  /* the pixel face is monospaced at 1em per glyph, so a fixed size makes "HOLY MOLLY"
     exactly 10em wide and it ran off a 360px phone. These track the viewport instead. */
  .ttl-hero{font-size:clamp(23px,8vw,34px);line-height:1.35;white-space:normal;text-shadow:0 -1.5px 0 var(--yellow),0 -3px 0 var(--yellow),0 3px 18px #ff922d}
  .ttl-80{font-size:clamp(23px,8vw,34px);line-height:1.35;white-space:normal}
  .vprop{font-size:12px;line-height:20px;white-space:normal}
  .vprop b{font-size:15px;line-height:24px}
  .ttl-42{font-size:clamp(16px,5.2vw,22px);line-height:1.45}
  .body-20{font-size:16px;line-height:24px}
  .btn{align-self:flex-start;height:52px;padding:0 22px;justify-content:center}
  .btn--l{padding:0 18px 0 8px;gap:12px}
  .btn--l .btn__label{font-size:17px}
  .btn__label{font-size:16px}
  .agent{width:52px;height:36px}

  .deck{position:static;width:auto;height:auto;display:flex;gap:14px;overflow-x:auto;padding-bottom:8px;scroll-snap-type:x mandatory}
  /* the swipe rail owns the geometry here, so the desktop slot transform is dropped */
  /* the rail must never hand out a card taller than the screen: 78% of an iPad's
     width through the 313/467 ratio came out at 650x970 */
  .dcard{flex:0 0 min(78%,300px);aspect-ratio:313/467;transition:none;scroll-snap-align:center;
    left:auto;top:auto;width:auto;height:auto;transform:none;will-change:auto}
  .dcard__in img{transform:none}
  /* the notched silhouette is a desktop-only shape; below 1024 a plain radius reads better */
  .dcard,.dcard__in,.gcard--crop7,.gcard--crop7 .gcard__in{clip-path:none;border-radius:32px}
  .dcard__dim{display:none}
  .dnav{display:none}

  .inputbox{padding:16px 18px 18px}
  .ptext{font-size:15px;line-height:22px}
  .tools{margin-top:14px}
  .btn-s{align-self:flex-start;height:32px;padding:0 14px;margin-top:12px}
  .msgbox{padding:16px 18px}
  .msgbox .agent{display:none}
  .msgbox > .a + .a{margin-top:6px}
  .tasklist li{padding-left:12px}

  /* .a{position:static} above would otherwise strip the card's positioning context */
  .gcard,.dcard{position:relative}
  .gcard{width:100%;height:auto}
  .gcard__in{aspect-ratio:466/610;height:auto}
  /* the frame 7 card follows the clip it holds, not the still-image card shape */
  .gcard--crop7 .gcard__in{aspect-ratio:1644/1732}
  .cmeta__name,.cmeta__row{padding:0 20px}
  .cmeta--lg .cmeta__name{font-size:20px;line-height:26px}
  .cmeta--lg .cmeta__row{font-size:15px}

  .model{position:relative;height:340px;overflow:hidden}
  .model img{position:absolute;left:50%;top:0;width:auto;height:100%;transform:translateX(-50%)}
  .panel{padding:16px}
  .drop{height:150px;margin-bottom:16px}
  .btn-3d{height:52px}

  /* no room to spread five parts on a phone: keep the assembled hull and list the labels */
  .split{display:flex;flex-direction:column;gap:10px;width:100%}
  .split__whole{position:static;width:100%;height:auto}
  .split__part{display:none}
  .split .chip{transform:none}
  /* the exploded parts are hidden at this width, so letting the split state run left
     the ship blanked out for half of every 2.6s cycle */
  .split.is-split .split__whole{opacity:1}
  .split.is-split .chip{transform:none}
  .chip{align-self:flex-start;font-size:13px}

  .crad{display:flex;overflow-x:auto;padding-bottom:8px}
  .crad__row{position:static;animation:none;display:flex;gap:14px}
  .gcard--row{width:74vw;max-width:300px;height:auto;aspect-ratio:352/480}
  .cmeta--row .cmeta__name{font-size:17px}
  .badge{font-size:9px;padding:3px 6px;border-width:1.5px}

  .socials{flex-wrap:wrap}
  .expo-strip b{font-size:8px}
  .expo-strip span{display:none}

  .reserve__grid{grid-template-columns:minmax(0,1fr);gap:32px}

  /* both of these are centred compositions in the design. Left to the flow defaults
     the title, the claim and the button each picked their own alignment. */
  /* centring by text-align and align-self only. Setting align-items:center on the
     column instead makes every child shrink to its content, which let the marquee
     rail size itself to all fifteen cards and gave the page an 8000px scrollWidth. */
  #hero .ttl-hero,#hero .vprop,#hero .body-20,
  #start .ttl-80,#start .body-20{text-align:center}
  #hero .btn,#start .btn{align-self:center}
  #start .socials{justify-content:center}

  /* 320-400px: the header row is the only thing that still runs out of width */
  @media (max-width:400px){
    .hdr{padding:10px 12px}
    .hdr__nav a{font-size:11px}
    .brand__word{font-size:11px;line-height:14px}
  }
}

/* ============================================================= tablets
   600-1179px keeps the single column, but caps the measure and steps the type back
   up: at 834px the phone sizes gave 90-character lines and a hero title that read
   like a caption. This tier is also where portrait iPads land. */
@media (min-width:600px) and (max-width:1179px){
  .fr__in{max-width:min(92vw,880px);margin:0 auto;padding:64px 24px;gap:26px}
  .ttl-hero{font-size:46px;line-height:62px}
  .ttl-80{font-size:44px;line-height:58px}
  .ttl-42{font-size:28px;line-height:40px}
  .vprop{font-size:15px;line-height:26px}
  .vprop b{font-size:19px;line-height:32px}
  .body-20{font-size:18px;line-height:28px}
  .btn{height:56px}
  .btn__label{font-size:17px}
  .btn--l .btn__label{font-size:19px}
  .ptext{font-size:16px;line-height:24px}
  .model{height:420px}
  .cmeta--lg .cmeta__name{font-size:22px;line-height:28px}
  .expo-strip span{display:inline}
}

@media (prefers-reduced-motion:reduce){
  .crad__row{animation:none}
  .dcard{transition:none}
  .mono-label,.turtle,.agent{animation:none}
  .bg-drift,.twinkle,.starfield,.caret{animation:none}
}

.legal-bar{border-top:1px solid #1c1c22;background:#000;display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;padding:18px 20px;font-size:13px;color:#5f5f66}
.legal-bar a{color:#8a8a92;text-decoration:none;border-bottom:1px solid rgba(138,138,146,.35)}
.legal-bar a:hover{color:var(--yellow);border-bottom-color:rgba(255,242,0,.6)}
