/* ==========================================================================
   Lazy Lion Studios — site.css
   Load order: css/fonts.css, then this file.
   ========================================================================== */

:root {
  /* surfaces */
  --bg:#16151A;
  --bg-2:#211F29;
  --bg-3:#2A2933;
  --footer:#0F0E12;
  /* brand */
  --gold:#FECA5C;
  --gold-2:#E6AC3E;
  --gold-edge:#C79A2C;
  --gold-art:#F7DC96;
  /* console */
  --shell-hi:#33313E;
  --shell-lo:#1B1A21;
  --bezel:#100F13;
  --screen:#08070A;
  --bay:#24222C;
  --cart-face:#2A2933;
  --cart-edge:#3A3945;
  --cart-art:#16151A;
  /* type */
  --display:'Bricolage Grotesque', sans-serif;
  --body:'Hanken Grotesk', system-ui, sans-serif;
  /* cartridge geometry + tilt (written by js/main.js at startup) */
  --cart-w:176px;
  --cart-h:198px;
  --tilt:0deg;
  --tilt-hover:0deg;
  /* measured nav height (written by js/main.js, kept live on resize) — the
     console is sized to the viewport minus the sticky nav */
  --nav-h:59px;
}

* { box-sizing:border-box; }

html { scroll-behavior:smooth; }

body {
  margin:0;
  background:var(--bg);
  color:#fff;
  font-family:var(--body);
  -webkit-font-smoothing:antialiased;
}

.page { width:100%; overflow-x:clip; background:var(--bg); }

a { color:var(--gold); text-decoration:none; }
a:hover { color:var(--gold-2); }
::selection { background:var(--gold); color:#16151A; }
input, button, textarea { font-family:var(--body); }
img { max-width:100%; }
h1, h2, h3, p, ul { margin:0; }
ul { list-style:none; padding:0; }

:focus { outline:none; }
:focus-visible {
  outline:2px solid var(--gold);
  outline-offset:2px;
}

.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0;
}

/* Dev-only markup. js/env.js stamps .is-prod on <html> before first paint, so
   anything not ready for the live site is hidden rather than deleted: if the
   script or the JS-built cart UI ever fails, a stray static link is a gentler
   failure than a half-built page. The cartridges themselves are filtered out of
   the catalogue in js/main.js and never reach the DOM at all. */
html.is-prod [data-dev-only] { display:none !important; }

body.is-dragging {
  user-select:none;
  -webkit-user-select:none;
  cursor:grabbing;
}

/* ==========================================================================
   Nav
   ========================================================================== */

.nav {
  position:sticky; top:0; z-index:900;
  display:flex; align-items:center; justify-content:space-between; gap:24px;
  padding:13px 34px;
  background:rgba(22,21,26,.86);
  -webkit-backdrop-filter:blur(12px);
  backdrop-filter:blur(12px);
  border-bottom:1px solid rgba(255,255,255,.07);
}
.nav__lockup { display:flex; align-items:center; gap:12px; color:#fff; }
.nav__mark { height:32px; width:auto; display:block; }
.nav__wordmark { height:18px; width:auto; display:block; } /* 0.5× of the 36px pixel grid — keep to 18/36/54 so crispEdges lands on whole device pixels */
.nav__rule { width:2px; height:26px; background:var(--gold); display:block; flex:none; }
.nav__links {
  display:flex; align-items:center; gap:26px;
  font-size:13px; font-weight:600; color:rgba(255,255,255,.62);
}
/* the pill is excluded: the child-combinator rule would otherwise outrank
   .nav__contact's own gold */
.nav__links > a:not(.nav__contact) { color:inherit; }
.nav__contact {
  display:block;
  color:var(--gold);
  border:1px solid rgba(254,202,92,.4);
  padding:7px 15px;
  font-weight:700; font-size:12px; letter-spacing:.08em; text-transform:uppercase;
}
/* re-pins the resting gold; without it the global a:hover flips the pill to gold-2 */
.nav__contact:hover { color:var(--gold); }

/* ==========================================================================
   Console shell
   ========================================================================== */

/* full-bleed console: one viewport of hardware under the nav. dvh keeps mobile
   browser chrome from cropping the dock; the vh line is the fallback. */
.hero {
  display:flex;
  width:100%;
  height:calc(100vh - var(--nav-h));
  height:calc(100dvh - var(--nav-h));
  min-height:580px;
}

.shell {
  position:relative;
  flex:1; min-width:0;
  display:flex; flex-direction:column;
  padding:14px;
  background:linear-gradient(var(--shell-hi),var(--bg-2) 42%,var(--shell-lo));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14);
}
/* seat impact — the whole console takes the weight of the cart for one beat.
   The transform makes .shell a containing block for any position:fixed
   descendant, so js/main.js only ever applies this when nothing inside is
   relying on the viewport as its coordinate space: never while a cart is in
   flight (.cart.is-flying), and never in drawer mode, where #bay and
   #bayBackdrop are themselves fixed descendants of the shell. */
.shell.is-thunk { animation:shellThunk 220ms cubic-bezier(.3,.7,.3,1); }

.shell__status {
  flex:none;
  display:flex; align-items:center; justify-content:space-between;
  padding:2px 12px 12px;
}
.shell__brand { display:flex; align-items:center; gap:9px; }
.shell__label {
  font-size:9.5px; font-weight:800; letter-spacing:.26em; text-transform:uppercase;
  color:rgba(255,255,255,.32);
}
.shell__vents { display:flex; gap:4px; align-items:center; }

/* the speaker switch — a hardware toggle sitting with the vents, not a UI
   control floating over the page */
.snd {
  display:flex; align-items:center; gap:6px;
  margin-right:10px; padding:4px 8px;
  border:1px solid rgba(255,255,255,.12); border-radius:2px;
  background:transparent; cursor:pointer;
  transition:border-color .25s, background .25s;
}
.snd__label {
  font-size:8.5px; font-weight:800; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(255,255,255,.3); transition:color .25s;
}
.snd__wave { display:flex; align-items:flex-end; gap:2px; height:9px; }
.snd__wave i {
  display:block; width:2px; border-radius:1px;
  background:rgba(255,255,255,.24); transition:background .25s, height .25s;
}
.snd__wave i:nth-child(1) { height:3px; }
.snd__wave i:nth-child(2) { height:9px; }
.snd__wave i:nth-child(3) { height:6px; }
.snd.is-on { border-color:rgba(254,202,92,.4); background:rgba(254,202,92,.1); }
.snd.is-on .snd__label { color:var(--gold); }
.snd.is-on .snd__wave i { background:var(--gold); }
/* muted: the bars flatten to a single dead line */
.snd:not(.is-on) .snd__wave i { height:2px; }
.snd:hover { border-color:rgba(255,255,255,.26); }
.dot {
  width:7px; height:7px; border-radius:50%; display:block; flex:none;
  background:radial-gradient(circle at 35% 30%,#5b5967,#2b2a33);
}
.dot--offset { margin-left:8px; }
.vent {
  width:26px; height:3px; border-radius:2px; display:block; flex:none;
  background:rgba(0,0,0,.35);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07);
}
/* the split: screen + dock on the left, cartridge bay on the right */
.shell__split {
  display:flex; flex-wrap:nowrap; align-items:stretch;
  gap:26px; flex:1; min-height:0;
}
.console {
  flex:1 1 420px; min-width:0; min-height:0;
  display:flex; flex-direction:column; gap:22px;
}

.bezel {
  position:relative; z-index:1;
  flex:1; min-height:355px;
  display:flex;
  padding:15px; border-radius:16px; background:var(--bezel);
  box-shadow:inset 0 2px 5px rgba(0,0,0,.9), 0 1px 0 rgba(255,255,255,.06);
}

.screen {
  position:relative;
  flex:1; min-height:0;
  border-radius:9px;
  background:var(--screen);
  overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.05), inset 0 0 70px rgba(0,0,0,.9);
}

.screen__scanlines {
  position:absolute; inset:0; z-index:40; pointer-events:none;
  background:repeating-linear-gradient(rgba(255,255,255,.028) 0px,rgba(255,255,255,.028) 1px,transparent 1px,transparent 3px);
}
.screen__vignette {
  position:absolute; inset:0; z-index:41; pointer-events:none;
  background:radial-gradient(120% 100% at 50% 45%,transparent 52%,rgba(0,0,0,.55) 100%);
}
/* power-on blink as the panel mounts — a CRT waking, not a strobe */
.screen.is-flash::after {
  content:''; position:absolute; inset:0; z-index:42; pointer-events:none;
  background:#fff; opacity:0;
  animation:screenFlash 240ms linear;
}

/* ---- screen states ---- */

.screen-idle, .screen-boot { display:none; }
.screen[data-screen="idle"] .screen-idle { display:flex; }
.screen[data-screen="booting"] .screen-boot { display:flex; }

.screen-idle {
  position:absolute; inset:0;
  flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:40px;
}
.screen-idle__mark {
  height:74px; width:auto; opacity:.22; margin-bottom:26px;
  animation:bob 4.5s ease-in-out infinite;
}
.screen-idle__chip {
  display:inline-flex; align-items:center; gap:8px;
  border:1px solid rgba(254,202,92,.34);
  padding:5px 12px; margin-bottom:18px;
  font-size:10px; font-weight:800; letter-spacing:.3em; text-transform:uppercase;
  color:var(--gold);
}
.screen-idle__pip { width:5px; height:5px; background:var(--gold); display:block; flex:none; }
.screen-idle__head {
  font-family:var(--display); font-weight:700; font-size:31px; letter-spacing:-.01em;
}
.caret { animation:blink 1.05s step-start infinite; }
.screen-idle__sub { font-size:14px; color:rgba(255,255,255,.4); margin-top:12px; }

.screen-boot {
  position:absolute; inset:0;
  flex-direction:column; align-items:center; justify-content:center;
}
/* three sleeping z's drifting up and to the right — the brand's signature
   direction. Colour carries the per-glyph alpha so zDrift's own opacity ramp
   multiplies against it rather than replacing it. */
.screen-boot__z {
  position:relative; flex:none;
  width:72px; height:44px; margin-bottom:14px;
  font-family:var(--display); font-weight:700;
}
.screen-boot__zg { position:absolute; display:block; line-height:1; }
.screen-boot__zg:nth-child(1) {
  left:2px; bottom:2px; font-size:11px; color:rgba(254,202,92,.55);
  animation:zDrift 1.26s ease-in-out 0s infinite;
}
.screen-boot__zg:nth-child(2) {
  left:24px; bottom:14px; font-size:14px; color:rgba(254,202,92,.7);
  animation:zDrift 1.26s ease-in-out .42s infinite;
}
.screen-boot__zg:nth-child(3) {
  left:48px; bottom:26px; font-size:18px; color:rgba(254,202,92,.85);
  animation:zDrift 1.26s ease-in-out .84s infinite;
}

.screen-boot__label {
  font-size:11px; font-weight:800; letter-spacing:.32em; text-transform:uppercase;
  color:rgba(255,255,255,.45); margin-bottom:16px;
}
.screen-boot__track {
  width:210px; height:3px; background:rgba(255,255,255,.09);
  overflow:hidden; position:relative;
}
.screen-boot__bar {
  position:absolute; left:0; top:0; width:38%; height:100%;
  background:var(--gold);
  animation:sweep .72s linear infinite;
}

/* ==========================================================================
   Detail panels
   ========================================================================== */

.panels { position:absolute; inset:0; }

.panel {
  position:absolute; inset:0;
  padding:30px 32px;
  display:flex; flex-direction:column;
  opacity:0; transform:translateY(12px); pointer-events:none;
  /* visibility keeps the inactive panels' links out of the tab order
     without cutting the fade-out short */
  visibility:hidden;
  transition:opacity .34s ease,
             transform .34s cubic-bezier(.2,.8,.3,1),
             visibility 0s linear .34s;
}
.panel.is-active {
  opacity:1; transform:none; pointer-events:auto; visibility:visible;
  transition:opacity .34s ease,
             transform .34s cubic-bezier(.2,.8,.3,1),
             visibility 0s linear 0s;
}

/* content stagger: head, art, then the right column, layered inside the
   panel's own .34s entrance. Deactivation carries no delay (all three leave
   together) because the delays only live on the .is-active rules. */
.panel__head, .panel__art, .panel__text {
  opacity:0; transform:translateY(10px);
  transition:opacity .34s ease, transform .34s cubic-bezier(.2,.8,.3,1);
}
.panel.is-active .panel__head,
.panel.is-active .panel__art,
.panel.is-active .panel__text { opacity:1; transform:none; }
.panel.is-active .panel__head { transition-delay:0s; }
.panel.is-active .panel__art  { transition-delay:60ms; }
.panel.is-active .panel__text { transition-delay:120ms; }

.panel__head {
  display:flex; align-items:flex-start; justify-content:space-between; gap:20px;
  padding-bottom:18px;
  border-bottom:1px solid rgba(255,255,255,.09);
}
.panel__meta { display:flex; align-items:center; gap:10px; margin-bottom:9px; }
.badge {
  border:1px solid rgba(255,255,255,.28);
  color:rgba(255,255,255,.72);
  font-size:9.5px; font-weight:800; letter-spacing:.2em; text-transform:uppercase;
  padding:4px 9px;
}
.badge--gold { border-color:rgba(254,202,92,.5); color:var(--gold); }
.panel__tag { font-size:12px; color:rgba(255,255,255,.4); }
.panel__name {
  font-family:var(--display); font-weight:700; font-size:31px; letter-spacing:-.02em;
}
.panel__ctas { display:flex; gap:9px; flex:none; }

.btn { display:inline-block; white-space:nowrap; }
/* the two :hover rules below only re-pin the resting color — the CTAs are
   anchors, so the global a:hover would otherwise flip their text to gold-2 */
.btn--gold {
  background:var(--gold); color:#16151A; font-weight:700; font-size:13.5px; padding:11px 19px;
}
.btn--gold:hover { color:#16151A; }
.btn--ghost {
  border:1px solid rgba(255,255,255,.22); color:#fff; font-size:13.5px; font-weight:600; padding:11px 17px;
}
.btn--ghost:hover { color:#fff; }

.panel__body {
  display:grid; grid-template-columns:1.1fr .9fr; gap:26px;
  padding-top:20px; flex:1; min-height:0;
}
.panel__art {
  position:relative; min-height:0;
  border-radius:4px; overflow:hidden; background:rgba(255,255,255,.03);
}
/* a playable panel gives the board the larger half — the copy beside it is
   support, the game is the point */
.panel--play .panel__body { grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr); }
/* the screen is viewport-sized now, so the right column takes the overflow on
   short windows rather than pushing the specs row out of the panel */
.panel__text {
  display:flex; flex-direction:column; min-height:0;
  overflow:hidden auto;
  scrollbar-width:thin;
  scrollbar-color:rgba(255,255,255,.16) transparent;
}
.panel__blurb {
  font-size:14.5px; line-height:1.62; color:rgba(255,255,255,.66);
  margin:0 0 16px; text-wrap:pretty;
}
.bullets { display:flex; flex-direction:column; gap:8px; margin-bottom:18px; }
.bullets li {
  display:flex; gap:10px; align-items:baseline;
  font-size:13.5px; color:rgba(255,255,255,.78);
}
.bullets li::before {
  content:''; width:5px; height:5px; background:var(--gold);
  display:block; flex:none; position:relative; top:-2px;
}
.specs {
  margin-top:auto; display:flex;
  border-top:1px solid rgba(255,255,255,.09); padding-top:12px;
}
.spec { flex:1; display:flex; flex-direction:column; gap:3px; }
.spec__k {
  font-size:9px; font-weight:800; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(255,255,255,.32);
}
.spec__v { font-size:13px; font-weight:600; color:#fff; }

/* ==========================================================================
   Art compositions
   ========================================================================== */

.art {
  position:absolute; inset:0; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
}
.art__lockup { display:block; object-fit:contain; }

/* 1 — Cricket Dynasty */
.art--cd { background:#131417; }
.art--cd .art__glow {
  position:absolute; inset:0;
  background:radial-gradient(52% 60% at 50% 46%,rgba(255,255,255,.04),transparent 70%);
}
.art--cd .art__lockup { position:relative; height:55%; width:auto; max-width:64%; }

/* 2 — MyStats for 2K */
.art--ms { background:var(--bg); }
.art--ms .art__bars {
  position:absolute; left:0; right:0; bottom:0; height:74%;
  display:flex; align-items:flex-end; justify-content:center; gap:16px;
}
.art--ms .art__bars i { width:18px; display:block; background:rgba(255,255,255,.05); }
.art--ms .art__bars i:nth-child(1) { height:42%; }
.art--ms .art__bars i:nth-child(2) { height:66%; }
.art--ms .art__bars i:nth-child(3) { height:96%; background:rgba(254,202,92,.35); }
.art--ms .art__bars i:nth-child(4) { height:54%; }
.art--ms .art__bars i:nth-child(5) { height:78%; }
.art--ms .art__lockup { position:relative; height:50%; width:auto; }

/* 3 — Looped.TV. The art window is a framed card, so it takes the kit's framed
   shades (Navy 700 / Navy 600) rather than the near-black page ground #040509 —
   visibly navy under the cream wordmark. */
.art--lt { background:radial-gradient(120% 100% at 50% 40%,#12152C 0%,#0D0F1F 100%); }
.art--lt .art__lockup { position:relative; width:57%; height:auto; max-height:40%; }
.art--lt .art__chip {
  position:absolute; top:12px; right:14px;
  display:inline-flex; align-items:center; gap:7px;
  font-size:8px; font-weight:800; letter-spacing:.24em; text-transform:uppercase;
  color:#F4A13A;
}
.art--lt .art__chip i { width:5px; height:5px; background:#F4A13A; display:block; flex:none; }
.art--lt .art__foot {
  position:absolute; left:14px; right:14px; bottom:12px;
  display:flex; align-items:center; gap:10px;
  font-size:8px; font-weight:800; letter-spacing:.24em; text-transform:uppercase;
  color:rgba(245,236,217,.4);
}
.art--lt .art__foot::after {
  content:''; flex:1; height:1px; background:rgba(245,236,217,.14);
}

/* 4 — Wrapped Weekly (kit paper #F1EFE7, clay #C15F3C, warm grey #706B5B) */
.art--ww { background:#F1EFE7; box-shadow:inset 0 0 0 1px rgba(27,27,24,.12); }
/* the horizontal lockup is ~9.4:1, so it is sized by width; height stays auto
   and the flex centring on .art keeps it on the optical middle line */
.art--ww .art__lockup { position:relative; width:72%; height:auto; max-height:40%; }
.art--ww .art__hair {
  position:absolute; left:22px; right:22px; top:15%; height:1px;
  background:rgba(193,95,60,.3);
}
.art__deltas {
  position:absolute; right:14px; bottom:11px;
  display:flex; align-items:center; gap:7px;
  font-size:10px; line-height:1; color:#706B5B;
}
.art__deltas i { font-style:normal; display:block; }

/* 5 — Annotate (kit paper #FBF7F1, ink #23201C, highlighter #EFC04A) */
.art--an { background:#FBF7F1; box-shadow:inset 0 0 0 1px rgba(27,27,24,.12); }
/* mark + wordmark lockup, ~7.5:1 — width-sized like the WW one */
.art--an .art__lockup { position:relative; width:64%; height:auto; max-height:40%; }

/* ==========================================================================
   Dock — the slot deck under the screen
   ========================================================================== */

/* fixed height: the dock-mask sits at a hard 50px, just under the slot line,
   so the docked cart reads as swallowed rather than parked. overflow keeps the
   seatIn travel inside the deck. */
.dock {
  position:relative; z-index:100;
  flex:none; height:130px; overflow:hidden;
  border-radius:16px; background:var(--bay);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 -8px 24px rgba(0,0,0,.35);
  padding:0 22px 20px;
  display:flex; flex-direction:column;
}

.dock__controls {
  position:relative; z-index:60;
  display:flex; align-items:center; flex-wrap:nowrap; gap:18px;
  padding:16px 0 24px;
}
.dock__side { flex:1; display:flex; align-items:center; min-width:0; }
.dock__side--end { justify-content:flex-end; }

/* z-index clears the dock-mask (z75) so the readout still shows with a cart in */
.dock__now {
  position:relative; z-index:80;
  flex:1; min-height:0;
  display:flex; align-items:center; justify-content:space-between; gap:22px;
  border-top:1px solid rgba(255,255,255,.06);
  padding-top:12px;
}
.dock__nowline { display:flex; align-items:baseline; gap:11px; min-width:0; }
.dock__nowlabel {
  flex:none;
  font-size:9px; font-weight:800; letter-spacing:.24em; text-transform:uppercase;
  color:rgba(255,255,255,.3);
}
.dock__nowvalue {
  font-family:var(--display); font-weight:700; font-size:13.5px;
  color:rgba(255,255,255,.72);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.dock__grille {
  flex:none; width:94px; height:24px; border-radius:2px;
  background-image:radial-gradient(circle,rgba(0,0,0,.5) 1.6px,transparent 1.8px);
  background-size:9px 9px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}

.pwr {
  display:flex; align-items:center; gap:9px;
  border:1px solid rgba(255,255,255,.14);
  background:transparent;
  padding:9px 15px; border-radius:3px;
  transition:all .3s;
}
.led {
  width:9px; height:9px; border-radius:50%; display:block; flex:none;
  background:rgba(255,255,255,.14); box-shadow:none;
  transition:background .3s, box-shadow .3s;
}
.pwr__label {
  font-size:11px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
  color:rgba(255,255,255,.3);
  transition:color .3s;
}
/* idle breathing — a sleeping console, faintly warm. The live states below
   win because the animation only runs while the pwr is not live. */
.pwr:not(.is-live) .led { animation:ledBreathe 3.8s ease-in-out infinite; }
.pwr.is-live { border-color:rgba(254,202,92,.45); background:rgba(254,202,92,.14); }
.pwr.is-live .pwr__label { color:var(--gold); }
.pwr.is-live .led { background:var(--gold); box-shadow:0 0 12px rgba(254,202,92,.85); }

.slot {
  flex:0 0 184px; height:30px; border-radius:3px;
  background:linear-gradient(#040405,#15141A);
  box-shadow:inset 0 4px 8px rgba(0,0,0,.9), inset 0 -1px 0 rgba(255,255,255,.06);
  transition:box-shadow .2s;
}
.slot.is-hot {
  box-shadow:inset 0 4px 8px rgba(0,0,0,.9), 0 0 0 3px rgba(254,202,92,.55), 0 0 20px rgba(254,202,92,.45);
}
/* seat impact — the hot glow decays to rest as a keyframe so it still plays
   after .is-hot has already been dropped by the drop handler */
.slot.is-flash { animation:slotFlash 260ms ease-out; }

.eject {
  background:transparent;
  border:1px solid rgba(255,255,255,.14);
  color:rgba(255,255,255,.26);
  font-size:11px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
  padding:9px 15px; border-radius:3px;
  cursor:default;
  transition:all .2s;
}
.eject:not(:disabled) {
  background:rgba(254,202,92,.14);
  border-color:rgba(254,202,92,.45);
  color:var(--gold);
  cursor:pointer;
}

/* ==========================================================================
   Bay — the cartridge sidebar
   ========================================================================== */

/* the same z-index as .dock, later in the DOM: a cart in flight (z1000 inside
   this stacking context) therefore passes over the dock on its way to the slot */
/* 420px, not 400: two 176px cart columns plus the gap still clear a classic
   15px scrollbar, so the shelf does not collapse to one column off-Mac */
.bay {
  position:relative; z-index:100;
  flex:0 1 420px; min-width:216px; min-height:0;
  display:flex; flex-direction:column; gap:14px;
  border-radius:16px; background:var(--bay);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 22px 44px -26px rgba(0,0,0,.7);
  padding:16px;
  scroll-margin-top:calc(var(--nav-h) + 14px);
}

/* The drawer furniture is a small-screen affair only: above the stacking
   breakpoint the bay is a sidebar that is always open, so the button that opens
   it, the one that closes it and the scrim behind it have nothing to do. They
   are switched on in the max-width:900px block below. */
.bay-toggle, .bay-close, .bay-backdrop { display:none; }

.bay__meta {
  flex:none;
  display:flex; flex-direction:column; align-items:flex-start;
  gap:12px;
}
.bay__count {
  font-size:10.5px; font-weight:800; letter-spacing:.26em; text-transform:uppercase;
  color:rgba(255,255,255,.36);
}
.chips { display:flex; gap:8px; flex-wrap:wrap; align-self:stretch; }
.chip {
  cursor:pointer;
  font-size:12px; font-weight:700; padding:7px 14px; border-radius:3px;
  border:1px solid rgba(255,255,255,.18);
  background:transparent;
  color:rgba(255,255,255,.72);
  /* was `all .15s` — spelled out so the press can run at its own 80ms */
  transition:background-color .15s, border-color .15s, color .15s, transform 80ms ease;
}
.chip.is-active {
  background:var(--gold); border-color:var(--gold); color:#16151A;
}
.chip:active { transform:scale(.96); }

/* the shelf scrolls inside the sidebar. A cart in flight is position:fixed, so
   it leaves this box rather than being clipped by it. */
/* the top row lifts 13px on hover and a scroll box cannot show overflow above
   its own top edge — so the shelf carries 14px of internal headroom and is
   pulled back up by the same amount, leaving the spacing unchanged */
.cart-grid {
  position:relative;
  flex:1; min-height:0;
  overflow:hidden auto;
  margin-top:-14px; padding:14px 0 4px;
  display:grid; grid-template-columns:repeat(auto-fit,var(--cart-w,176px));
  align-content:start; justify-content:center; gap:20px 16px;
  scrollbar-width:thin;
  scrollbar-color:rgba(255,255,255,.16) transparent;
}
.cart-grid::-webkit-scrollbar { width:8px; }
.cart-grid::-webkit-scrollbar-track { background:transparent; }
.cart-grid::-webkit-scrollbar-thumb {
  background:rgba(255,255,255,.14); border-radius:4px;
  border:2px solid transparent; background-clip:padding-box;
}
.cart-grid:hover::-webkit-scrollbar-thumb { background:rgba(255,255,255,.22); background-clip:padding-box; }

/* ==========================================================================
   Cartridges
   ========================================================================== */

.skin--gold {
  --edge:var(--gold-edge);
  --face:var(--gold);
  --art:var(--gold-art);
  --text:#16151A;
  --sub:rgba(22,21,26,.55);
}
.skin--dark {
  --edge:var(--cart-edge);
  --face:var(--cart-face);
  --art:var(--cart-art);
  --text:#fff;
  --sub:rgba(255,255,255,.42);
}

.cart-cell { position:relative; width:var(--cart-w,176px); height:var(--cart-h,198px); }
.cart-ghost {
  position:absolute; inset:0; display:none;
  border:2px dashed rgba(255,255,255,.13);
  border-radius:10px 10px 2px 2px;
  background:rgba(0,0,0,.2);
}
.cart-cell.is-away .cart-ghost { display:block; }

.cart {
  position:relative;
  width:var(--cart-w,176px); height:var(--cart-h,198px);
  border:none; background:transparent; padding:0;
  transform-style:preserve-3d;
  touch-action:none;
  -webkit-tap-highlight-color:transparent;
  cursor:grab;
  opacity:1;
  transform:perspective(900px) rotateX(calc(-1 * var(--tilt)));
  transition:transform .24s cubic-bezier(.34,1.4,.6,1);
}
.shell[data-phase="idle"] .cart:not(.is-asleep):hover {
  transform:perspective(900px) rotateX(calc(-1 * var(--tilt-hover))) translateY(-13px) scale(1.02);
}
.cart.is-asleep {
  opacity:.3;
  pointer-events:none;
  cursor:default;
}
.shell:not([data-phase="idle"]) .cart:not(.is-flying) {
  pointer-events:none;
  cursor:default;
}
.cart.is-flying {
  position:fixed;
  z-index:1000;
  cursor:grabbing;
  /* a filtered-out cart still flies home fully opaque; it only dims once it lands */
  opacity:1;
  /* left / top / transform / transition are written inline by js/main.js */
}
/* Docked, or stowed: in drawer mode a cart on its way to the slot is not flown
   across the viewport (the shelf is not in it), so it simply leaves the shelf
   the way the docked one does, and its cell ghost holds the gap. */
.cart.is-docked, .cart.is-stowed { display:none; }

.cart__face {
  position:absolute; inset:0;
  border-radius:10px 10px 2px 2px;
  overflow:hidden;
  background:var(--face);
  box-shadow:0 14px 26px rgba(0,0,0,.45),
             inset 0 1px 0 rgba(255,255,255,.24),
             inset 1px 0 0 rgba(255,255,255,.08),
             inset -1px 0 0 rgba(0,0,0,.2);
  display:flex; flex-direction:column;
}
.cart__edge {
  height:15px; flex:none;
  background:var(--edge);
  background-image:repeating-linear-gradient(90deg,rgba(0,0,0,.26) 0px,rgba(0,0,0,.26) 3px,transparent 3px,transparent 9px);
  box-shadow:inset 0 -1px 0 rgba(0,0,0,.22);
}
.cart__body {
  flex:1; display:flex; flex-direction:column;
  padding:12px 13px 13px; min-height:0;
}
.cart__art {
  position:relative; overflow:hidden;
  flex:1; border-radius:4px;
  background:var(--art);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.2);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:7px;
}
/* cover art: the product's own logo. The cart button owns every pointer and
   the image is decorative, so it never takes a hit or a native image drag. */
.cart__cover {
  display:block; object-fit:contain;
  pointer-events:none; -webkit-user-select:none; user-select:none;
}
/* per-cart sizing — optically matched weight, nothing touching the art edges
   except the Looped.TV full-bleed below */
.cart__art--cd .cart__cover { height:78%; width:auto; max-width:86%; }
.cart__art--ms .cart__cover { height:66%; width:auto; max-width:80%; }
.cart__art--ww .cart__cover { height:56%; width:auto; }
.cart__art--an .cart__cover { height:55%; width:auto; max-width:70%; }
.cart__art--ci .cart__cover { height:60%; width:auto; }

/* Nudge's cover brings its own juniper ground, so — like Looped.TV below —
   it fills the art window edge to edge; ::after re-draws the inset ring above
   the artwork so the window still reads contained. */
.cart__art--ws .cart__cover {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
}
.cart__art--ws::after {
  content:''; position:absolute; inset:0; border-radius:4px;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.3); pointer-events:none;
}

/* Looped.TV brings its own red ground, so the cover fills the art window.
   ::after re-draws the inset ring above the image so it still reads contained;
   the caption gets a shadow to clear the artwork underneath it. */
.cart__art--lt .cart__cover {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
}
.cart__art--lt::after {
  content:''; position:absolute; inset:0; border-radius:4px;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.3); pointer-events:none;
}
/* The printed label, above the art. Serial then title, stacked and flush left
   — one fixed-height block on every cart, so the art windows all line up
   across the shelf however long the product name is. */
.cart__row {
  flex:none; margin-bottom:9px;
  display:flex; flex-direction:column; align-items:flex-start; gap:2px;
}
.cart__serial {
  font-size:7.5px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  color:var(--sub); white-space:nowrap; line-height:1;
}
.cart__name {
  font-size:13.5px; font-weight:700; color:var(--text);
  line-height:1.1; text-align:left;
  white-space:nowrap; max-width:100%; overflow:hidden;
}

/* ---- docked cartridge visual ---- */

/* top must stay in step with DOCK_PAD in js/main.js — the flying cart is handed
   off to this replica mid-air, so the two have to agree on where the slot is */
.docked {
  position:absolute; top:26px; left:50%;
  width:var(--cart-w,176px); height:var(--cart-h,198px);
  z-index:70; pointer-events:none;
  transform:translate(-50%,-10%);
  animation:seatIn .5s cubic-bezier(.36,.78,.3,1) both;
}
.docked .cart__face {
  box-shadow:0 4px 16px rgba(0,0,0,.55),
             inset 0 1px 0 rgba(255,255,255,.24),
             inset 1px 0 0 rgba(255,255,255,.08),
             inset -1px 0 0 rgba(0,0,0,.2);
}
/* Only the top ~28px of the seated cart clears the deck, and the title now
   sits in that strip — so the replica drops the serial and tightens its top
   padding to fit the whole name above the slot line rather than have it
   sliced through the middle. */
.docked .cart__serial { display:none; }
.docked .cart__body { padding-top:8px; }
/* The seated cart is itself an eject switch — hit the strip above the slot
   line and it gives a few px (the spring taking the push) before the flight
   jolts it back out. Pointer-only by design, like the drag itself; keyboard
   users have the Eject button. Height must stop at the dock-mask's top edge
   (50px − the cart's 26px top) so the deck below stays dead to the pointer. */
.docked__hit {
  position:absolute; left:0; right:0; top:0; height:24px;
  pointer-events:auto; cursor:pointer;
}
/* travel must stay in step with PRESS_PX / PRESS_MS in js/main.js — the
   flight's first frame starts from the pressed-in position */
.docked.is-pressed { animation:dockPress .11s cubic-bezier(.4,0,.7,1) both; }
.docked__sink {
  position:absolute; left:0; right:0; top:8px; bottom:0;
  background:linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.55) 22%,rgba(0,0,0,.8) 40%);
}
/* everything below the slot line is deck, not cartridge */
.dock-mask {
  position:absolute; top:50px; left:0; right:0; bottom:0;
  z-index:75; border-radius:0 0 16px 16px;
  background:var(--bay); pointer-events:none;
}
.dock-shade {
  position:absolute; top:50px; left:50%; margin-left:-92px;
  width:184px; height:9px; z-index:76;
  background:linear-gradient(rgba(0,0,0,.45),rgba(0,0,0,0)); pointer-events:none;
}

/* ==========================================================================
   Letter
   ========================================================================== */

.letter { border-top:1px solid rgba(255,255,255,.07); background:var(--bg); }
.letter__inner {
  max-width:1240px; margin:0 auto; padding:82px 34px;
  display:grid; grid-template-columns:1fr .9fr; gap:56px; align-items:center;
}
.letter__head {
  font-family:var(--display); font-weight:800;
  font-size:clamp(26px,3.2vw,38px); line-height:1.1; letter-spacing:-.02em;
  margin:0 0 12px;
}
.letter__copy {
  font-size:16px; line-height:1.62; color:rgba(255,255,255,.58);
  margin:0; max-width:48ch; text-wrap:pretty;
}
.letter__form { display:flex; flex-direction:column; gap:11px; }
.letter__row { display:flex; gap:10px; flex-wrap:wrap; }
.letter__input {
  flex:1; min-width:200px;
  background:var(--bg-2);
  border:1px solid rgba(255,255,255,.14);
  color:#fff; font-size:15px; padding:14px 16px; border-radius:3px;
}
.letter__input::placeholder { color:rgba(255,255,255,.32); }
.letter__submit {
  background:var(--gold); color:#16151A; border:none;
  font-weight:700; font-size:14px; padding:14px 24px; border-radius:3px; cursor:pointer;
}
.letter__note { font-size:12px; color:rgba(255,255,255,.34); }

/* ==========================================================================
   Footer
   ========================================================================== */

.footer { border-top:1px solid rgba(255,255,255,.07); background:var(--footer); }
.footer__inner {
  max-width:1240px; margin:0 auto; padding:52px 34px 40px;
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:48px; flex-wrap:wrap;
}
.footer__brand { display:flex; flex-direction:column; gap:18px; }
.footer__lockup { display:flex; align-items:center; gap:20px; }
.footer__mark { height:62px; width:auto; display:block; }
.footer__rule { width:2px; height:56px; background:var(--gold); display:block; flex:none; }
.footer__wordmark { height:54px; width:auto; display:block; } /* 1.5× of the 36px pixel grid */
.footer__tagline { font-size:12.5px; color:rgba(255,255,255,.35); }
.footer__cols { display:flex; gap:56px; flex-wrap:wrap; }
.footer__col { display:flex; flex-direction:column; gap:10px; }
.footer__colhead {
  font-size:9.5px; font-weight:800; letter-spacing:.24em; text-transform:uppercase;
  color:rgba(255,255,255,.3);
}
.footer__col a { font-size:13.5px; color:rgba(255,255,255,.62); }

/* ==========================================================================
   Keyframes
   ========================================================================== */

@keyframes blink { 0%,100% { opacity:1 } 50% { opacity:.12 } }
@keyframes sweep { 0% { transform:translateX(-130%) } 100% { transform:translateX(240%) } }
@keyframes bob { 0%,100% { transform:translateY(0) } 50% { transform:translateY(-7px) } }
@keyframes seatIn {
  0%   { transform:translate(-50%,-58%) }
  74%  { transform:translate(-50%,-7.4%) }
  88%  { transform:translate(-50%,-11.4%) }
  100% { transform:translate(-50%,-10%) }
}
/* seatIn fills to the same transform the element rests at, so the press can
   simply take over the animation slot once the cart is seated */
@keyframes dockPress {
  to { transform:translate(-50%,calc(-10% + 7px)) }
}
@keyframes pulse { 0%,100% { opacity:.35 } 50% { opacity:1 } }

/* --- iteration 2 motion --- */

@keyframes shellThunk {
  0%   { transform:translateY(0) }
  35%  { transform:translateY(2px) }
  100% { transform:translateY(0) }
}
/* four shadows in both stops, insets in the same order, so the list
   interpolates: the ring and glow fade out over the untouched rest shadows */
@keyframes slotFlash {
  0% {
    box-shadow:inset 0 4px 8px rgba(0,0,0,.9), inset 0 -1px 0 rgba(255,255,255,.06),
               0 0 0 3px rgba(254,202,92,.55), 0 0 20px rgba(254,202,92,.45);
  }
  100% {
    box-shadow:inset 0 4px 8px rgba(0,0,0,.9), inset 0 -1px 0 rgba(255,255,255,.06),
               0 0 0 3px rgba(254,202,92,0), 0 0 20px rgba(254,202,92,0);
  }
}
@keyframes screenFlash { 0% { opacity:0 } 20% { opacity:.06 } 100% { opacity:0 } }
@keyframes ledBreathe {
  0%,100% { background-color:rgba(255,255,255,.14) }
  50%     { background-color:rgba(254,202,92,.32) }
}
@keyframes zDrift {
  0%   { opacity:0; transform:translate(0,4px) scale(.85) }
  45%  { opacity:1 }
  100% { opacity:0; transform:translate(7px,-9px) scale(1.1) }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* the sidebar drops to a single cart column before the split itself gives way,
   so the screen keeps its width down to the stacking breakpoint */
@media (max-width:1180px) {
  .bay { flex:0 1 252px; }
  /* four chips never fit one line in the narrow shelf — 2×2 beats a 3+1 wrap */
  .chips { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); }
  .chip { text-align:center; padding:7px 10px; }
  .panel__body { grid-template-columns:1fr 1fr; }
  .panel__name { font-size:27px; }
}

/* ---- split → stack: the bay comes out from beside the console and sits
   under it, full width, and the whole hero stops being viewport-locked ---- */
@media (max-width:900px) {
  .hero { height:auto; min-height:0; }
  .shell__split { flex-direction:column; gap:22px; }

  .console { flex:none; gap:18px; }
  .bezel { display:block; flex:none; min-height:0; }
  .screen { height:456px; }

  .chips { display:flex; }
  .chip { text-align:center; padding:7px 14px; }
  /* Two carts to a row in the drawer. The cartridge is built from fixed pixel
     sizes throughout — face, edge stripe, label type — so it is scaled whole
     with `zoom` rather than unpicked; zoom scales the layout box too, so the
     grid still measures honestly and nothing clips. auto-fit from the base rule
     then does the rest: two columns wherever 2×176px + the gap fits inside the
     zoomed track (every phone from ~360px up), one column below that. */
  .cart-grid {
    flex:none; overflow:visible;
    margin-top:0; padding:0; gap:22px 20px;
    zoom:.8;
  }

  .panel__head { flex-direction:column; align-items:flex-start; gap:12px; }
  .panel__ctas { flex-wrap:wrap; }

  /* ---- the bay as a drawer ----
     Dragging a cartridge across a touch screen was always the weak half of the
     interaction, so below this breakpoint the shelf slides in over the page and
     a tap loads the cart. Same #bay element, no second copy of the DOM. */

  /* the button reads as console hardware — the enabled Eject switch, widened to
     the console's full width so it sits under the dock like a drawer handle */
  .bay-toggle {
    display:block; width:100%;
    background:rgba(254,202,92,.14);
    border:1px solid rgba(254,202,92,.45);
    color:var(--gold);
    font-size:11px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
    padding:12px 15px; border-radius:3px;
    cursor:pointer;
  }

  /* hard corners, one chunky offset shadow to the left, gold spine — the studio
     UI rules, on a panel that is only ever seen from the right edge in.
     The z-indexes clear the sticky nav (z900): a drawer sliding out from under
     the nav bar would put its own close button beneath it. */
  .bay {
    position:fixed; top:0; right:0; bottom:0; left:auto;
    width:min(360px,88vw);
    z-index:960;
    flex:none; min-width:0;
    border-radius:0;
    border-left:3px solid var(--gold);
    box-shadow:-10px 0 0 rgba(0,0,0,.45);
    overflow:hidden auto;
    /* the shelf's own scroll stops at its ends rather than chaining out to the
       page behind; body.bay-open below holds that page still meanwhile */
    overscroll-behavior:contain;
    /* parked far enough out that the offset shadow, which is drawn 10px to the
       drawer's left, clears the viewport edge too */
    transform:translateX(calc(100% + 16px));
    /* visibility keeps the shelf's buttons out of the tab order while the
       drawer is parked, without cutting the slide-out short */
    visibility:hidden;
    transition:transform .28s cubic-bezier(.3,.85,.35,1), visibility 0s linear .28s;
  }
  .bay.is-open {
    transform:none;
    visibility:visible;
    transition:transform .28s cubic-bezier(.3,.85,.35,1), visibility 0s linear 0s;
  }

  .bay-backdrop {
    display:block;
    position:fixed; inset:0; z-index:950;
    background:rgba(0,0,0,.6);
    opacity:0; pointer-events:none;
    /* the scrim is a lid, not a surface: a swipe on it must not scroll the page
       it is covering */
    touch-action:none;
    transition:opacity .28s ease;
  }
  .bay-backdrop.is-open { opacity:1; pointer-events:auto; }

  /* js/main.js sets this for as long as the drawer is open */
  body.bay-open { overflow:hidden; }

  /* the meta block stays a stack (heading over chips); the close switch is
     lifted out of that flow into the corner the thumb reaches for */
  .bay__meta { position:relative; padding-right:38px; }
  .bay-close {
    display:block;
    position:absolute; top:-2px; right:0;
    width:30px; height:30px; padding:0;
    background:transparent;
    border:1px solid rgba(255,255,255,.18);
    border-radius:3px;
    color:rgba(255,255,255,.6);
    font-size:13px; line-height:1;
    cursor:pointer;
  }

  /* the carts no longer take a pointer drag here, so they must stop swallowing
     the touch scroll that moves the drawer */
  .cart { touch-action:auto; }

  /* With a cart loaded the shelf is normally dead — on desktop the dock sits
     right beside it and explains why. The drawer covers the dock, so a shelf of
     inert carts would be a dead end instead: here a tap swaps cartridges, and
     the carts have to keep taking the tap to do it. Out-specifies the
     `.shell:not([data-phase="idle"]) .cart:not(.is-flying)` rule above; the
     loaded cart itself is display:none in the shelf and stays out of it. */
  .shell:not([data-phase="idle"]) .bay .cart:not(.is-flying):not(.is-docked) {
    pointer-events:auto;
    cursor:pointer;
  }
}

@media (max-width:820px) {
  .nav { padding:12px 20px; gap:16px; }
  .nav__links { gap:16px; }

  .shell { padding:12px; }

  .screen { height:auto; min-height:520px; }
  .panel {
    position:relative; inset:auto; display:none;
    padding:24px 22px;
  }
  .panel.is-active { display:flex; visibility:visible; }
  .panels { position:relative; inset:auto; }
  .panel__body { grid-template-columns:1fr; gap:20px; }
  .panel__art { min-height:200px; }
  /* .panel--play's own column split outranks the stack rule above, so it has
     to be unwound by name — and the board needs real height once stacked */
  .panel--play .panel__body { grid-template-columns:1fr; }
  .panel--play .panel__art { min-height:430px; }
  .panel__name { font-size:26px; }
  .screen-idle__head { font-size:25px; }

  .dock { padding:0 16px 20px; }
  .dock__controls { gap:12px; }
  .slot { flex:0 1 150px; }
  .bay { padding:14px; }

  .letter__inner { grid-template-columns:1fr; gap:32px; padding:64px 20px; }
  .footer__inner { padding:44px 20px 36px; gap:36px; }
  .footer__cols { gap:36px; }
}

@media (max-width:560px) {
  /* flex-wrap is the safety net below ~380px; above it the row still fits */
  .nav { flex-wrap:wrap; gap:12px; row-gap:10px; }
  .nav__links { gap:14px; font-size:12.5px; }
  .nav__contact { padding:6px 11px; }
  .nav__mark { height:26px; }
  .nav__wordmark { height:18px; }
  .nav__rule { height:21px; }
  /* the controls row must never wrap: the dock mask at top:50px assumes the
     slot sits on the first line of the deck */
  .dock { padding:0 12px 20px; }
  .dock__controls { gap:10px; }
  .pwr, .eject { padding:9px 11px; }
  .slot { flex:0 1 120px; min-width:84px; }
  .dock__grille { display:none; }
  .bay { padding:12px; }
  .footer__mark { height:48px; }
  .footer__wordmark { height:36px; }
  .footer__rule { height:42px; }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion:reduce) {
  html { scroll-behavior:auto; }
  .screen-idle__mark { animation:none; }
  .caret { animation:none; }
  .screen-boot__bar {
    animation:pulse 1.2s ease-in-out infinite;
    width:100%;
  }
  .docked { animation:none; }
  .cart { transition:none; }
  .shell[data-phase="idle"] .cart:not(.is-asleep):hover { transform:perspective(900px) rotateX(calc(-1 * var(--tilt))); }
  .panel {
    transform:none;
    transition:opacity .12s linear, visibility 0s linear .12s;
  }
  .panel.is-active {
    transform:none;
    transition:opacity .12s linear, visibility 0s linear 0s;
  }

  /* --- iteration 2 motion --- */

  /* seat impact, power-on blink and the idle LED are off entirely */
  .shell.is-thunk { animation:none; }
  .slot.is-flash { animation:none; }
  .screen.is-flash::after { content:none; animation:none; }
  .pwr:not(.is-live) .led { animation:none; }

  /* the drifting z's collapse to one static glyph cluster */
  .screen-boot__zg { display:none; }
  .screen-boot__z {
    width:auto; height:auto;
    font-size:15px; line-height:1; color:rgba(254,202,92,.7);
  }
  .screen-boot__z::before { content:'zZz'; }

  /* stagger reduces to a plain fade — no travel, no delays */
  .panel__head, .panel__art, .panel__text {
    transform:none;
    transition:opacity .12s linear;
  }
  .panel.is-active .panel__head,
  .panel.is-active .panel__art,
  .panel.is-active .panel__text { transform:none; transition-delay:0s; }

  .chip { transition:background-color .15s, border-color .15s, color .15s; }
  .chip:active { transform:none; }

  /* the drawer snaps in and out; the visibility hand-off still has to happen on
     the same frame as the transform, so both transitions go rather than just
     the travel */
  .bay, .bay.is-open { transition:none; }
  .bay-backdrop { transition:none; }
}
