/* ================================================================
   NO COMPLY — global stylesheet (structural wireframe)

   One file, top to bottom:
     0. Fonts + design tokens   change values here; components only read tokens
     1. Base                    reset, document defaults, shared utilities
     2. Components              header, hero, video, catalog, product card,
                                variant selector, info modal, about, contact
     3. Responsive              breakpoints mostly re-point tokens
     4. Motion preferences
   ================================================================ */

/* Fonts: loaded by the <link> in index.html's <head> (not @import, which would
   wait for this file). To swap typefaces, change that URL and the --font-* tokens below. */

/* ---------- 0. DESIGN TOKENS ---------- */
:root {
  color-scheme: light dark;

  /* Colour palettes — each raw value lives here once. The semantic tokens
     below point at one palette; .theme-inverse points at the other. */
  --light-surface: #f0f0ec;
  --light-surface-raised: #ffffff;
  --light-field: #ffffff;
  --light-ink: #111111;
  --light-ink-soft: #494947;
  --light-placeholder: #777770;
  --light-line: #c8c8c2;
  --light-focus: #0b63ce;
  --light-label-shade: rgba(0,0,0,.16);
  --light-surface-lift: #ffffff;       /* lighter tone at the top of the catalog wave */
  --light-gold-ink: #7d6742;          /* gold text on light surfaces (≈5:1) */
  --light-brush: #111111;             /* brush buttons on light sections: black at rest… */
  --light-brush-ink: #ffffff;
  --light-brush-hover: var(--color-brush-gold); /* …gold on hover */
  --light-brush-hover-ink: #111111;

  --dark-surface: #222220;
  --dark-surface-raised: #2c2c29;
  --dark-field: #121211;
  --dark-ink: #f5f5f0;
  --dark-ink-soft: #b7b7b0;
  --dark-placeholder: #92928a;
  --dark-line: #3d3d38;
  --dark-focus: #8ebdff;
  --dark-label-shade: rgba(0,0,0,.5);
  --dark-surface-lift: #ecebe6;        /* near-white at the top of the catalog wave */
  --dark-gold-ink: #c7b183;           /* gold text on dark surfaces */
  --dark-brush: var(--color-brush-gold); /* brush buttons on dark sections: gold at rest… */
  --dark-brush-ink: #111111;
  --dark-brush-hover: #f5f5f0;        /* …white on hover */
  --dark-brush-hover-ink: #111111;

  /* Colour — scheme-independent */
  --color-page: #0a0a0a;
  --color-stage-dark: #0a0a0a;        /* hero + other always-dark stages */
  --color-on-dark: #f8f8f4;
  --color-on-dark-soft: #b8b8b2;
  --color-line-dark: rgba(255,255,255,.26);
  --color-line-dark-faint: rgba(255,255,255,.11);
  --color-line-dark-strong: rgba(255,255,255,.48);

  /* Colour — accent (CTAs, active filters/sorts, hovers) */
  --color-accent: #f5b700;            /* golden yellow; black text on it ≈ 11:1 */
  --color-accent-ink: #111111;
  --color-gold-muted: #b39c6e;        /* brand gold (desaturated): icons, dividers, hero title */
  --color-chevron: var(--color-gold-muted);
  --color-hero-title: var(--color-gold-muted); /* swap to var(--color-on-dark) for white */
  --color-brush-gold: #d4a743;        /* brush buttons: the brand gold, more saturated */
  --color-badge: #d7372f;             /* cart counter */
  --color-badge-ink: #ffffff;
  --color-gold-surface: #d3c4a2;      /* pale, desaturated gold for boxes on light sections */
  --color-gold-surface-line: rgba(179,156,110,.5); /* gold-muted at half strength: its border */

  /* Colour — chrome + effects */
  --color-header: rgba(10,10,10,.95);
  --color-nav-mobile: rgba(10,10,10,.98);
  --color-backdrop: rgba(0,0,0,.62);
  --color-art-shade: rgba(12,12,11,.92);  /* phone card caption gradient + details panel */
  --color-hero-grid: rgba(255,255,255,.018);
  --color-hero-diagonal: rgba(255,255,255,.045);
  --shadow-popover: 0 14px 40px rgba(0,0,0,.28);

  /* Type */
  --font-display: "Gloock", "Noto Serif SC", Georgia, serif; /* Noto Serif SC covers Chinese glyphs */
  --weight-display: 400;              /* Gloock ships one weight; don't fake bold */
  --font-body: "Barlow", "Helvetica Neue", sans-serif;
  --font-mono: "IBM Plex Mono", monospace;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-black: 800;
  --tracking-display: -.02em;
  --tracking-heading: -.01em;
  --tracking-title: 0em;
  --tracking-label: .05em;
  --tracking-mono: .03em;
  --leading-body: 1.55;

  --step--1: clamp(.75rem, .72rem + .12vw, .82rem);
  --step-0: clamp(.94rem, .9rem + .2vw, 1.06rem);
  --step-1: clamp(1.12rem, 1rem + .5vw, 1.42rem);
  --step-2: clamp(1.45rem, 1.15rem + 1.2vw, 2.15rem);
  --step-3: clamp(2rem, 1.35rem + 2.6vw, 3.75rem);
  --step-hero: clamp(3.2rem, 1.7rem + 7.2vw, 8.4rem);

  /* Space */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* Layout */
  --page-gutter: clamp(1rem, 4vw, 4.5rem);
  --section-y: clamp(4rem, 9vw, 8rem);
  --content-max: 1440px;
  --reading-max: 680px;
  --header-height: 72px;
  /* Ink wave: ink-wave.svg (1920×1080) at full page width and full height. It
     hangs --divider-sink of its height down into the catalog, where it blends
     into the same-coloured surface; the rest overhangs the hero / video. */
  --divider-height: calc(100vw * 1080 / 1920);
  --divider-sink: .5;
  --divider-overhang: calc(var(--divider-height) * (1 - var(--divider-sink)));
  --rail-inline-pad: max(var(--page-gutter), calc((100vw - var(--content-max)) / 2 + var(--page-gutter)));
  --rail-arrow-size: 48px;      /* carousel arrow hit area */
  --rail-arrow-icon: 38px;          /* spear icon width */
  --rail-arrow-inset: clamp(.25rem, 1.5vw, 1.25rem);
  --grid-columns: 3;                  /* product grid view: 3 → 2 → 1 by breakpoint */
  /* Art area on stacked cards. Board images are uniform 480×1800 (1:3.75) with
     the board filling the height between equal margins, so a tall area shows
     every board at the same size. */
  --card-media-height: clamp(360px, 58svh, 560px);

  /* Hero montage background + featured video */
  --hero-video-opacity: .3;           /* low: a texture, not a video */
  --hero-glass-top: rgba(10,10,10,.35);
  --hero-glass-bottom: rgba(10,10,10,.6);
  --feature-video-max: 960px;

  /* Scroll distance per scene, in viewport heights. Raise to slow a scene down. */
  --scene-hero-hold: 0;      /* no hold: title swaps straight into the story beat */
  --scene-crossfade: 1;      /* one full viewport per beat; panels swap across it */
  --scene-story-hold: 0;     /* no hold: story swaps straight into the video beat */
  --scene-video-hold: .5;    /* video fully shown before the boards rise */
  --scene-catalog-hold: 1;   /* pinned product row (carousel view) */
  /* Held sections: 1 = exactly one full-screen transition to the next, so the
     page always snaps to one whole section (no half-and-half in between). */
  --scene-gear-hold: 1;      /* gear (The Forge) -> events */
  --scene-events-hold: 1;    /* events -> about */
  --scene-about-hold: 1;     /* about -> contact */
  --scene-intro: calc(1 + var(--scene-hero-hold) + var(--scene-crossfade) + var(--scene-story-hold) + var(--scene-crossfade) + var(--scene-video-hold));

  --showcase-label-top: var(--header-height);
  --showcase-label-height: 44px;
  /* the pinned product panel starts below the fixed header + sticky control row */
  --showcase-content-top: calc(var(--showcase-label-top) + var(--showcase-label-height) + var(--space-2));

  /* Shape */
  --radius-xs: 4px;
  --radius-sm: 2px;
  --radius-md: 10px;
  --radius-board: 30px;      /* deck-shaped placeholders */
  --radius-pill: 999px;
  --radius-round: 50%;
  --line: 1px;
  --placeholder-line: 1px dashed;

  /* Motion */
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --duration-fast: 180ms;
  --duration-med: 420ms;
  --duration-slow: 650ms;

  /* Stacking */
  --z-hero: 1;
  --z-video: 2;
  --z-scroll: 3;
  --z-header: 30;
}

/* Semantic colour mapping. Page sections follow the visitor's scheme;
   .theme-inverse is the accent mode: it always takes the opposite palette
   (dark on a light page, light on a dark page). Add it to any section. */
:root {
  color-scheme: light;
  --color-surface: var(--light-surface);
  --color-surface-raised: var(--light-surface-raised);
  --color-field: var(--light-field);
  --color-ink: var(--light-ink);
  --color-ink-soft: var(--light-ink-soft);
  --color-placeholder: var(--light-placeholder);
  --color-line: var(--light-line);
  --color-focus: var(--light-focus);
  --color-label-shade: var(--light-label-shade);
  --color-gold-ink: var(--light-gold-ink);
  --color-surface-lift: var(--light-surface-lift);
  --color-brush: var(--light-brush); --color-brush-ink: var(--light-brush-ink);
  --color-brush-hover: var(--light-brush-hover); --color-brush-hover-ink: var(--light-brush-hover-ink);
}
.theme-inverse {
  color-scheme: dark;
  --color-surface: var(--dark-surface);
  --color-surface-raised: var(--dark-surface-raised);
  --color-field: var(--dark-field);
  --color-ink: var(--dark-ink);
  --color-ink-soft: var(--dark-ink-soft);
  --color-placeholder: var(--dark-placeholder);
  --color-line: var(--dark-line);
  --color-focus: var(--dark-focus);
  --color-label-shade: var(--dark-label-shade);
  --color-gold-ink: var(--dark-gold-ink);
  --color-surface-lift: var(--dark-surface-lift);
  --color-brush: var(--dark-brush); --color-brush-ink: var(--dark-brush-ink);
  --color-brush-hover: var(--dark-brush-hover); --color-brush-hover-ink: var(--dark-brush-hover-ink);
}
@media (prefers-color-scheme: dark) {
  :root {
    --color-page: #050505;
    color-scheme: dark;
    --color-surface: var(--dark-surface);
    --color-surface-raised: var(--dark-surface-raised);
    --color-field: var(--dark-field);
    --color-ink: var(--dark-ink);
    --color-ink-soft: var(--dark-ink-soft);
    --color-placeholder: var(--dark-placeholder);
    --color-line: var(--dark-line);
    --color-focus: var(--dark-focus);
    --color-label-shade: var(--dark-label-shade);
    --color-gold-ink: var(--dark-gold-ink);
    --color-surface-lift: var(--dark-surface-lift);
    --color-brush: var(--dark-brush); --color-brush-ink: var(--dark-brush-ink);
    --color-brush-hover: var(--dark-brush-hover); --color-brush-hover-ink: var(--dark-brush-hover-ink);
  }
  .theme-inverse {
    color-scheme: light;
    --color-surface: var(--light-surface);
    --color-surface-raised: var(--light-surface-raised);
    --color-field: var(--light-field);
    --color-ink: var(--light-ink);
    --color-ink-soft: var(--light-ink-soft);
    --color-placeholder: var(--light-placeholder);
    --color-line: var(--light-line);
    --color-focus: var(--light-focus);
    --color-label-shade: var(--light-label-shade);
    --color-gold-ink: var(--light-gold-ink);
    --color-surface-lift: var(--light-surface-lift);
    --color-brush: var(--light-brush); --color-brush-ink: var(--light-brush-ink);
    --color-brush-hover: var(--light-brush-hover); --color-brush-hover-ink: var(--light-brush-hover-ink);
  }
}

/* Always-dark scope: surfaces that stay dark in either scheme (phone card
   caption + details panel over the board art) use the dark palette. */
.theme-dark {
  color-scheme: dark;
  --color-surface: var(--dark-surface);
  --color-surface-raised: var(--dark-surface-raised);
  --color-field: var(--dark-field);
  --color-ink: var(--dark-ink);
  --color-ink-soft: var(--dark-ink-soft);
  --color-placeholder: var(--dark-placeholder);
  --color-line: var(--dark-line);
  --color-focus: var(--dark-focus);
  --color-label-shade: var(--dark-label-shade);
  --color-gold-ink: var(--dark-gold-ink);
  --color-surface-lift: var(--dark-surface-lift);
  --color-brush: var(--dark-brush); --color-brush-ink: var(--dark-brush-ink);
  --color-brush-hover: var(--dark-brush-hover); --color-brush-hover-ink: var(--dark-brush-hover-ink);
}

/* ---------- 1. BASE ---------- */
*, *::before, *::after { box-sizing: border-box; scrollbar-width: none; }
*::-webkit-scrollbar { display: none; width: 0; height: 0; }
/* overflow-x on html too: mobile Safari ignores body-only clipping for side-scroll. */
html { overflow-x: clip; scroll-behavior: smooth; scroll-snap-type: y mandatory; background: var(--color-page); }
/* grid view reads freely: page snapping off (JS stepping still moves between sections) */
html.grid-view { scroll-snap-type: none; }
/* Invisible per-scene snap areas, laid out by app.js. Each spans its whole scene
   so scrolling inside stays free; snap-stop keeps a fling from skipping scenes. */
.snap-scene {
  position: absolute; left: 0; width: 1px; pointer-events: none;
  scroll-snap-align: start; scroll-snap-stop: always;
}
body {
  margin: 0;
  min-width: 0;
  overflow-x: clip;
  background: var(--color-page);
  color: var(--color-on-dark);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: var(--weight-display); }
button, input, textarea { font: inherit; }
a { color: inherit; }
:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 3px; }
.skip-link {
  position: fixed; left: var(--space-4); top: var(--space-4); z-index: 100;
  transform: translateY(-160%); padding: .7rem 1rem;
  background: var(--color-accent); color: var(--color-accent-ink);
}
.skip-link:focus { transform: translateY(0); }
.svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
/* Spear-star icon (sprite symbol #icon-spear, points right). Sized by width;
   colour follows currentColor. Modifiers turn it to point another way. */
.icon-spear { width: 1.6em; height: auto; aspect-ratio: 32 / 20; fill: currentColor; flex: none; }
.icon-spear--left { transform: scaleX(-1); }
.icon-spear--up { transform: rotate(-90deg); }
.icon-spear--down { transform: rotate(90deg); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.shell { width: min(100%, var(--content-max)); margin-inline: auto; }
.placeholder {
  border: var(--placeholder-line) currentColor;
  color: var(--color-placeholder);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-mono);
}
.kicker {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-soft);
}

/* ---------- 2. COMPONENTS ---------- */

/* LAUNCH-SALE BANNER (fixed under the nav; overlays content, never shifts layout) */
:root { --sale-banner-height: 44px; }
.sale-banner {
  position: fixed; top: var(--header-height); left: 0; right: 0; z-index: 25;
  min-height: var(--sale-banner-height);
  display: flex; align-items: center; justify-content: center; gap: var(--space-3);
  padding: .45rem var(--page-gutter);
  background: var(--color-brush-gold); color: #161616;
}
.sale-banner[hidden] { display: none; }
.sale-banner-text {
  margin: 0; font-family: var(--font-body); font-weight: 600; font-size: .95rem;
  letter-spacing: .02em; text-align: center;
}
.sale-banner-close {
  /* 44px tap target; the × itself reads larger */
  display: grid; place-items: center; flex: none;
  min-width: 44px; min-height: 44px;
  background: none; border: 0; padding: 0; margin: 0 -.5rem 0 0;
  color: inherit; font-size: 2rem; font-weight: 400; line-height: 1; cursor: pointer;
}

/* HEADER */
.site-header {
  position: fixed; inset: 0 0 auto; z-index: var(--z-header);
  min-height: var(--header-height);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-6); padding: .8rem var(--page-gutter);
  /* solid-ish, no backdrop-filter: a live blur over the hero video re-blurred every frame */
  background: var(--color-header);
  border-bottom: var(--line) solid var(--color-line-dark-faint);
}
/* Brand marks: the SVG logos are masks filled with currentColor, so the same
   files read white on dark (header, footer) and black on light (about). */
.brand-logo { display: block; background: currentColor; }
.brand-logo--full {
  aspect-ratio: 958 / 93;
  -webkit-mask: url("assets/images/brand/nocomply-logo-full.svg") center / contain no-repeat;
  mask: url("assets/images/brand/nocomply-logo-full.svg") center / contain no-repeat;
}
.brand-logo--icon {
  aspect-ratio: 1;
  -webkit-mask: url("assets/images/brand/nocomply-logo-icon.svg") center / contain no-repeat;
  mask: url("assets/images/brand/nocomply-logo-icon.svg") center / contain no-repeat;
}
/* Header: full logo at the top of the page; once scrolled it collapses to the
   X icon (app.js toggles .is-condensed). */
.site-logo {
  --logo-h: var(--header-logo-height, 20px);
  --logo-icon: 28px;
  position: relative; display: block; flex: none;
  height: max(var(--logo-h), var(--logo-icon)); width: calc(var(--logo-h) * 958 / 93);
  color: var(--color-on-dark);
  transition: width var(--duration-med) var(--ease-out);
}
.site-logo-full, .site-logo-icon {
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  transition: opacity var(--duration-med) var(--ease-out);
}
.site-logo-full { height: var(--logo-h); width: 100%; }
.site-logo-icon { height: var(--logo-icon); width: var(--logo-icon); opacity: 0; }
.site-header.is-condensed .site-logo { width: var(--logo-icon); }
.site-header.is-condensed .site-logo-full { opacity: 0; }
.site-header.is-condensed .site-logo-icon { opacity: 1; }
.site-logo:hover { color: var(--color-accent); }
.nav-toggle {
  display: none; flex: none; width: 44px; height: 44px; padding: 0;
  background: transparent; border: 0;
  color: var(--color-on-dark); cursor: pointer;
}
.nav-toggle::before, .nav-toggle::after {
  content: ""; display: block; width: 18px; height: 1px; margin: 6px auto;
  background: currentColor; transition: transform var(--duration-fast), opacity var(--duration-fast);
}
.nav-toggle[aria-expanded="true"]::before { transform: translateY(3.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"]::after { transform: translateY(-3.5px) rotate(-45deg); }
.main-nav { display: flex; align-items: center; gap: clamp(1rem, 3vw, 2.5rem); margin-left: auto; }

/* Header cart button: after the nav on desktop, left of the hamburger on phones.
   The red counter shows the number of items (hidden when empty). */
.cart-button {
  position: relative; flex: none; width: 44px; height: 44px; margin: -6px -8px -6px calc(var(--space-5) - var(--space-6));
  display: grid; place-items: center; padding: 0;
  border: 0; background: none; color: var(--color-on-dark); cursor: pointer;
  transition: color var(--duration-fast);
}
.cart-button:hover { color: var(--color-accent); }
.cart-button-icon { width: 24px; height: 24px; }
.cart-count {
  position: absolute; top: 3px; right: 1px;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  background: var(--color-badge); color: var(--color-badge-ink);
  font: var(--weight-bold) 11px/1 var(--font-body); letter-spacing: 0;
  box-shadow: 0 0 0 2px var(--color-stage-dark);
}
.cart-count[hidden] { display: none; }
.cart-count.is-bumped { animation: cart-bump .45s var(--ease-out); }
@keyframes cart-bump { 40% { transform: scale(1.35); } }
@media (prefers-reduced-motion: reduce) { .cart-count.is-bumped { animation: none; } }
.main-nav a {
  color: var(--color-on-dark-soft); text-decoration: none;
  font-family: var(--font-mono); font-size: var(--step--1);
  transition: color var(--duration-fast);
}
.main-nav a:hover { color: var(--color-accent); }

/* HERO — pinned beneath the document */
.hero {
  position: fixed; inset: 0; z-index: var(--z-hero);
  min-height: 100vh; min-height: 100svh; overflow: hidden;
  display: grid; align-items: safe center; background: var(--color-stage-dark);
}
.hero-backdrop {
  position: absolute; inset: -10%; will-change: transform;
  background: var(--color-stage-dark);
}
/* Montage loop: its own layer (gentler parallax than the grid) with extra
   height above, so it always fills the stage. The file is pre-blurred and
   low-res; the glass tint on top keeps it a quiet texture. */
.hero-video {
  position: absolute; left: 0; top: -30%; width: 100%; height: 130%;
  object-fit: cover; pointer-events: none; will-change: transform;
  opacity: var(--hero-video-opacity); /* blur + desaturation are baked into the file: no live filters */
}
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, var(--hero-glass-top), var(--hero-glass-bottom));
}
.hero-inner {
  position: relative; z-index: 2; width: min(100%, 1320px); margin: 0 auto;
  height: 100vh; height: 100svh;
  will-change: transform;
}
/* HERO PANELS — three full-screen beats on the same fixed stage, one viewport
   apart. app.js swaps them (title -> story -> video) with opacity only; the
   backdrop keeps its parallax. Panels scroll internally when their content
   runs taller than the viewport, so the section itself never moves. */
.hero-panel {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  overflow-y: auto;
  padding: calc(var(--header-height) + var(--space-10)) var(--page-gutter) var(--space-12);
  will-change: opacity;
}
/* Safe vertical centering: short content sits centered, tall content starts at
   the top and scrolls inside the panel. */
.hero-panel > :first-child { margin-top: auto; }
.hero-panel > :last-child { margin-bottom: auto; }
.hero-panel--title { align-items: flex-start; padding-top: calc(var(--header-height) + var(--space-20)); } /* extra room above the Nishan logo */
.hero-panel--title .board-stack { width: min(100%, 620px); margin-top: var(--space-6); }
.hero-panel--story { opacity: 0; pointer-events: none; align-items: center; text-align: center; }
.hero-blurb {
  max-width: 680px; margin: 0 0 var(--space-5);
  color: var(--color-on-dark); font-size: var(--step-1); line-height: 1.5;
}
.hero-lore {
  max-width: 620px; margin: 0;
  color: var(--color-on-dark-soft); font-size: var(--step-0); line-height: 1.65;
}
/* Nishan brand mark (white version; nishan-logo-black.webp for light grounds). Kept small. */
/* ---- Board anatomy (hero, anatomy.js) ----
   Hairline line drawing + callouts; ink sweep colours come from --anatomy-ink. */
.board-anatomy {
  --anatomy-ink: #e8e2d2;           /* bone; try var(--color-gold-muted) */
  --anatomy-line: #ffffff;
  width: min(100%, 1100px); margin-top: clamp(2.5rem, 7vh, 5rem);
}
.anatomy-art { position: relative; width: 100%; }
.anatomy-art svg { display: block; width: 100%; height: auto; overflow: hidden; }
.board-anatomy .ln { fill: none; stroke: var(--anatomy-stroke, var(--anatomy-line)); stroke-width: .9; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; stroke-dasharray: 1; stroke-dashoffset: 1; }
.board-anatomy .co { stroke-width: .5; stroke-linejoin: miter; }
.board-anatomy .ln.on { stroke-dashoffset: 0; }
.board-anatomy .dot { fill: var(--anatomy-stroke, var(--anatomy-line)); transform-box: fill-box; transform-origin: center; transform: scale(0); transition: transform .45s cubic-bezier(.34,1.56,.64,1); }
.board-anatomy .dot.on { transform: scale(1); }
.board-anatomy .end { fill: none; stroke: var(--anatomy-stroke, var(--anatomy-line)); stroke-width: .5; vector-effect: non-scaling-stroke; transform-box: fill-box; transform-origin: center; transform: scale(0); opacity: 0; transition: transform .5s cubic-bezier(.34,1.56,.64,1), opacity .4s; }
.board-anatomy .end.on { transform: scale(1); opacity: 1; }
.anatomy-ink { fill: var(--anatomy-ink); }
.anatomy-inv { --anatomy-stroke: #0a0a0a; } /* (not --line: that is the site's line-width token) */
.anatomy-inv * { transition: none !important; }
.anatomy-inv .ln { stroke-dasharray: none; }
.anatomy-inv .sil { fill: #0a0a0a; }
.anatomy-inv .sil-edge { stroke: #0a0a0a; }
.anatomy-inv .knock { stroke: var(--anatomy-ink); }
.anatomy-inv .bar-dark { stroke: #0a0a0a; stroke-width: 3.2; }
/* pulse rings: GPU-composited HTML overlays (no SVG repaints) */
.anatomy-pulses { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.board-anatomy .pr { position: absolute; aspect-ratio: 1; border-radius: 50%; border: .5px solid #fff; translate: -50% -50%; opacity: 0; will-change: scale, opacity; }
.board-anatomy .pr.dark { border-color: #0a0a0a; }
.board-anatomy .pr.on { animation: anatomy-pulse 2.4s ease-out infinite; }
@keyframes anatomy-pulse { 0% { scale: 1; opacity: .7; } 80%, 100% { scale: 2.3; opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .board-anatomy .pr.on { animation: none; } }
.hero-logo {
  display: block; width: var(--hero-logo-width, clamp(64px, 9vw, 120px)); height: auto;
  margin-bottom: var(--space-6);
}
.hero h1 {
  /* 14ch keeps every rotating phrase to two lines on desktop; the vw cap keeps
     the longest word ("COMPLIANCE.") on screen on phones. */
  max-width: 14ch; margin: 0 0 var(--space-8);
  color: var(--color-hero-title); font-size: min(var(--step-hero), 12.5vw); line-height: .84;
  font-weight: var(--weight-display); letter-spacing: var(--tracking-display); text-transform: uppercase;
}
.hero-grid {
  display: grid; grid-template-columns: minmax(260px, .72fr) minmax(360px, 1.28fr);
  gap: clamp(2rem, 6vw, 7rem); align-items: end;
}
.hero-copy { max-width: 470px; }
.lore-slot { min-height: 112px; padding: var(--space-5); display: flex; align-items: center; border-color: var(--color-line-dark); color: var(--color-on-dark-soft); }
.board-stack {
  position: relative; min-height: clamp(220px, 31vw, 420px);
  border-color: var(--color-line-dark); overflow: hidden;
}
.board-silhouette {
  position: absolute; top: 8%; left: 50%; width: clamp(48px, 6vw, 84px); height: 84%;
  border: var(--placeholder-line) var(--color-line-dark-strong); border-radius: var(--radius-board);
  display: grid; place-items: center; color: var(--color-on-dark-soft);
  font: .68rem/1.2 var(--font-mono); text-align: center; writing-mode: vertical-rl;
  transform-origin: 50% 85%;
}
.board-silhouette:nth-child(1) { transform: translateX(-140%) rotate(-13deg); }
.board-silhouette:nth-child(2) { transform: translateX(-50%) rotate(0deg); }
.board-silhouette:nth-child(3) { transform: translateX(40%) rotate(13deg); }
.truck { position: absolute; left: 20%; right: 20%; height: 1px; background: var(--color-line-dark); }
.truck.top { top: 18%; } .truck.bottom { bottom: 18%; }

/* PINNED VIDEO STAGE — crossfades over the hero before content rises */
.video-feature {
  position: fixed; inset: 0; z-index: var(--z-video);
  min-height: 100vh; min-height: 100svh; display: grid; align-content: safe center;
  padding: calc(var(--header-height) + var(--space-8)) var(--page-gutter) var(--space-8);
  overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: auto;
  background: transparent; color: var(--color-on-dark);
  opacity: 0; pointer-events: none; will-change: opacity;
}
/* Inactive state: as the catalog rises over the stage, a dark veil fades in
   over the featured video (and the hero loop behind it). app.js sets
   --stage-dim from the video beat (0) to the catalog heading stop (full). */
.video-feature::after {
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: var(--color-stage-dark); opacity: var(--stage-dim, 0);
}
/* Featured video: centred and capped (by width and by viewport height, so it
   never fills the screen); the blurb sits under it at the same width. */
.video-layout {
  display: grid; grid-template-columns: 1fr; gap: var(--space-5);
  width: min(100%, var(--feature-video-max), calc((100svh - var(--header-height) - 16rem) * 16 / 9));
  margin-inline: auto;
}
.video-frame {
  aspect-ratio: 16 / 9; overflow: hidden; background: #000;
  border: var(--line) solid var(--color-line-dark); border-radius: var(--radius-md);
  box-shadow: 0 24px 60px rgba(0,0,0,.45);
}
.feature-video { display: block; width: 100%; height: 100%; object-fit: contain; background: #000; }
.video-copy { display: grid; gap: var(--space-5); justify-items: center; text-align: center; }
.video-blurb {
  max-width: 62ch; margin: 0;
  color: var(--color-on-dark-soft); font-size: var(--step-0); line-height: var(--leading-body);
}
.video-blurb strong { color: var(--color-on-dark); font-weight: var(--weight-semibold); }
/* Social links: gold icon + handle; reusable anywhere (icons live in the sprite). */
.social-links { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3) var(--space-6); margin: 0; padding: 0; list-style: none; }
.social-links--left { justify-content: flex-start; margin: var(--space-8) 0 var(--space-4); }
.social-links a {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--color-gold-muted); text-decoration: none;
  font: var(--weight-medium) var(--step--1)/1 var(--font-mono); letter-spacing: .02em;
  transition: color var(--duration-fast);
}
.social-links a:hover, .social-links a:focus-visible { color: var(--color-accent); }
.social-icon { width: 26px; height: 26px; flex: none; }

/* CONTENT THAT SCROLLS OVER BOTH PINNED STAGES */
/* Room for hero → video (see --scene-* tokens), then the ink edge rises. */
main::before {
  content: "";
  display: block;
  height: calc(var(--scene-intro) * 100vh + var(--divider-overhang));
  height: calc(var(--scene-intro) * 100svh + var(--divider-overhang));
}
.scroll-over {
  position: relative; z-index: var(--z-scroll);
  color: var(--color-ink); background: var(--color-surface);
}
/* Ink wave: straddles the catalog's top edge. The SVG is a stencil filled with
   the surface colour, so it matches the section in any scheme. A second mask
   layer is solid below the edge and fades out just above it, patching the
   dry-brush gaps so the stroke bleeds into the section with no hard line. */
/* Catalog top glow: one eased gradient from near-white at the wave's stroke
   tips, down into the catalog heading, fully dark by --catalog-glow-end (from
   the catalog's top edge; app.js sets it to the midpoint between the tagline
   and the heading, so the heading always reads). The wave and the catalog
   background share the stops, measured from the same line, so there's no seam.
   --glow-span is the whole run, from the wave's top to that end point. */
.catalog {
  --catalog-glow-end: 140px;
  --glow-span: calc(var(--divider-overhang) + var(--catalog-glow-end));
  --glow-a: color-mix(in srgb, var(--color-surface-lift) 55%, var(--color-surface));
  --glow-b: color-mix(in srgb, var(--color-surface-lift) 26%, var(--color-surface));
  --glow-c: color-mix(in srgb, var(--color-surface-lift) 9%, var(--color-surface));
}
.ink-divider {
  position: absolute; left: 0; right: 0; top: calc(-1 * var(--divider-overhang)); height: var(--divider-height);
  pointer-events: none;
  background: linear-gradient(to bottom,
    var(--color-surface-lift) 0,
    var(--glow-a) calc(var(--glow-span) * .22),
    var(--glow-b) calc(var(--glow-span) * .48),
    var(--glow-c) calc(var(--glow-span) * .75),
    var(--color-surface) var(--glow-span));
  --divider-edge: calc(var(--divider-sink) * 100%);
  -webkit-mask:
    url("assets/ink-wave.svg") center / 100% 100% no-repeat,
    linear-gradient(to top, #000 var(--divider-edge), transparent calc(var(--divider-edge) + 12%));
  mask:
    url("assets/ink-wave.svg") center / 100% 100% no-repeat,
    linear-gradient(to top, #000 var(--divider-edge), transparent calc(var(--divider-edge) + 12%));
}

/* CATALOG */
.catalog {
  /* above the held sections that tuck under it (gear 4, events 3, about 2) */
  position: relative; z-index: 5;
  /* same stops as the wave, shifted up by the wave's overhang */
  background: linear-gradient(to bottom,
    var(--color-surface-lift) calc(-1 * var(--divider-overhang)),
    var(--glow-a) calc(var(--glow-span) * .22 - var(--divider-overhang)),
    var(--glow-b) calc(var(--glow-span) * .48 - var(--divider-overhang)),
    var(--glow-c) calc(var(--glow-span) * .75 - var(--divider-overhang)),
    var(--color-surface) var(--catalog-glow-end)) top / 100% calc(var(--catalog-glow-end) + 2px) no-repeat;

  /* Product card layout. Compact values (stacked card) are set for the grid
     view and for phones further down; card rules only read these. */
  --card-columns: minmax(280px, .9fr) 1.1fr; /* art | content on side-by-side cards */
  --card-rows: auto;
  --card-min-height: 480px;
  --card-media-min-height: 440px;
  --card-media-divider-side: var(--line) solid var(--color-line);
  --card-media-divider-bottom: 0;
  --card-art-height: 88%;            /* placeholder deck; board images share its 1:4.3 shape */
  --card-pad: clamp(1.25rem, 2.5vw, 2.25rem);
  --card-title-gap: var(--space-4);
  --card-rhythm: var(--space-5);
  --card-copy-height: 9.5rem;        /* blurb + lore box; longer text scrolls inside */
  --card-copy-fade: 1rem;           /* fade height at the text box's top edge once scrolled */
  --card-copy-fade-bottom: 3.5rem;  /* stronger bottom fade: signals there's more to scroll */
  --card-pills-gap: var(--space-6);
  --card-cta-width: 15rem;           /* brushstroke Summon button; height follows the stroke */
  --card-cta-align: flex-start;      /* Summon position in the text column */
  --toggle-display: inline-flex;
  --toggle-width: max-content;
  --toggle-radius: var(--radius-pill);
  --toggle-option-pad: .5rem 1rem;
  --toggle-info-gap: .5rem;
  --toggle-font-size: .68rem;        /* desktop cards; phones use var(--step--1) */

  /* Half the room between heading and first card (carousel: header + control bar). */
  --head-shift: calc((var(--space-2) + var(--showcase-content-top)) / 2);
}
.catalog-head {
  /* Above the ink wave's lower half and the stage's top padding it overlaps. */
  position: relative; z-index: 3;
  width: min(100%, var(--content-max));
  /* Centred in the space above the products: shifted down by --head-shift and
     pulled back by the same amount below, so the products don't move. */
  /* padding, not margin: a top margin here would collapse into the section */
  padding: var(--head-shift) var(--page-gutter) 0;
  margin: 0 auto calc(var(--space-2) - var(--head-shift));
}
/* Rotating heading (data-rotate): the ink filter is only on while a swap runs;
   its own layer keeps the filter from repainting with the video behind it. */
[data-rotate] { will-change: transform; }
[data-rotate].is-inking { filter: url(#ink-dissolve); }
.catalog h2 {
  margin: var(--space-3) 0 0; font-size: clamp(2.4rem, 1.5rem + 3.5vw, 4.6rem); line-height: 1;
  letter-spacing: var(--tracking-heading); text-transform: uppercase;
}
/* Subheading: the line under a section heading. Heavier and larger than body
   copy, in the body face for contrast with the serif heading. */
.subheading {
  color: var(--color-ink);
  font: var(--weight-semibold) var(--step-1)/1.25 var(--font-body);
  letter-spacing: .005em;
}

/* Sticky filter / sort / view row: sits under the header over the products. */
.catalog-controls {
  position: sticky; z-index: 5;
  top: var(--showcase-label-top);
  /* filter | sort | view | line | count — only the sort column shrinks */
  display: grid; grid-template-columns: auto minmax(0, max-content) auto 1fr auto; align-items: center; gap: var(--space-3);
  width: min(100%, var(--content-max)); height: var(--showcase-label-height);
  /* Takes no room in the flow: the products start right under the heading. */
  margin: 0 auto calc(-1 * var(--showcase-label-height)); padding: var(--space-1) var(--page-gutter);
  background: transparent; pointer-events: none;
  /* Hidden until the product section is reached (app.js adds .is-revealed). */
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity var(--duration-fast) ease, transform var(--duration-fast) ease, visibility 0s linear var(--duration-fast);
}
.catalog-controls.is-revealed {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--duration-fast) ease, transform var(--duration-fast) ease, visibility 0s;
}
.catalog-controls > .control-menu,
.catalog-controls > .control-button { pointer-events: auto; }

/* Content scrolls under the row; a soft shade off the header edge keeps it legible. */
.catalog-controls::before {
  content: ""; position: absolute; z-index: -1; top: 0; left: 50%;
  width: 100vw; height: calc(100% + var(--space-4)); transform: translateX(-50%);
  background: linear-gradient(to bottom, var(--color-label-shade), transparent);
  opacity: 0; transition: opacity var(--duration-fast) ease;
}
.catalog-controls.is-revealed::before { opacity: 1; }
.catalog-controls-line { height: 1px; background: var(--color-line); }
.catalog-count { margin: 0; color: var(--color-ink-soft); font: var(--step--1)/1 var(--font-mono); white-space: nowrap; }

.control-menu { position: relative; }
.control-menu--sort { min-width: 0; }
.control-menu--sort > .control-button { max-width: 100%; }
/* Long sort names cut off with an ellipsis instead of pushing the row wider. */
[data-sort-label] { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.control-button svg, .control-badge { flex: none; }
.control-button {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: .55rem 1rem; border: var(--line) solid var(--color-line); border-radius: var(--radius-pill);
  background: var(--color-surface-raised); color: var(--color-ink); cursor: pointer;
  font: var(--weight-medium) var(--step--1)/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label);
  transition: background var(--duration-fast), border-color var(--duration-fast), color var(--duration-fast);
}
.control-button:hover, .control-button[aria-expanded="true"], .control-button[aria-pressed="true"] { border-color: var(--color-ink); }
.control-button.is-active { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-accent-ink); }
.control-button svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.control-button--icon { padding: .5rem; }
.control-button--icon svg { width: 17px; height: 17px; }
/* The view toggle shows the view it switches to. */
.control-button--icon .icon-carousel,
.control-button--icon[aria-pressed="true"] .icon-grid { display: none; }
.control-button--icon[aria-pressed="true"] .icon-carousel { display: block; }
.control-badge {
  min-width: 18px; height: 18px; padding: 0 5px; display: inline-grid; place-items: center;
  border-radius: var(--radius-pill); background: var(--color-accent-ink); color: var(--color-accent);
  font-size: .68rem;
}
.control-badge[hidden] { display: none; }

.control-panel {
  position: absolute; z-index: 10; top: calc(100% + var(--space-2)); left: 0;
  width: min(280px, calc(100vw - 2 * var(--page-gutter)));
  max-height: calc(100svh - var(--showcase-content-top) - var(--space-8)); overflow-y: auto;
  display: grid; gap: var(--space-3); padding: var(--space-3);
  background: var(--color-surface-raised); color: var(--color-ink);
  border: var(--line) solid var(--color-line); border-radius: var(--radius-md);
  box-shadow: var(--shadow-popover);
}
.control-panel[hidden] { display: none; }
.option-list { display: grid; gap: 6px; min-width: 0; margin: 0; padding: 0; border: 0; }
/* Options are plain selectable pills; the native checkbox / radio stays for a11y only. */
.option-pill {
  position: relative; display: flex; align-items: center;
  padding: .6rem .9rem; border: var(--line) solid var(--color-line); border-radius: var(--radius-pill);
  cursor: pointer; font: var(--step--1)/1.2 var(--font-mono);
  transition: background var(--duration-fast), border-color var(--duration-fast), color var(--duration-fast);
}
.option-pill:hover { border-color: var(--color-ink-soft); }
.option-pill input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.option-pill:has(input:checked) { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-accent-ink); }
.option-pill:has(input:focus-visible) { outline: 3px solid var(--color-focus); outline-offset: 2px; }
.control-clear {
  justify-self: start; padding: .25rem 0; border: 0; background: none; color: var(--color-ink-soft);
  font: var(--step--1)/1.2 var(--font-mono); text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.control-clear:hover { color: var(--color-ink); }

/* Carousel view (default): one pinned, looping row */
.catalog-showcase {
  position: relative; z-index: 2;
  height: calc((1 + var(--scene-catalog-hold)) * 100vh);
  height: calc((1 + var(--scene-catalog-hold)) * 100svh);
}
.catalog-stage {
  /* overflow visible: the brush wave hangs below the row (the viewport clips the rail) */
  position: sticky; top: 0; z-index: 2; height: 100vh; height: 100svh; overflow: visible;
  padding: 0;
  background: var(--color-surface); isolation: isolate;
  transform: translate3d(0, 0, 0); will-change: transform;
  transition: transform var(--duration-slow) var(--ease-out);
}
.catalog-stage.is-exiting {
  transform: translate3d(0, calc(-100% - var(--wave-overhang)), 0); pointer-events: none;
  /* slow enough to watch the brush wave sweep over The Forge */
  transition-duration: var(--stage-exit-duration, 1.7s);
  transition-timing-function: cubic-bezier(.45, 0, .2, 1);
}
.product-viewport { position: relative; height: 100%; min-height: 0; overflow: hidden; }
.product-group {
  position: absolute; inset: 0; min-width: 0; padding-top: var(--showcase-content-top);
  display: grid; align-content: safe center;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: auto;
  -webkit-overflow-scrolling: touch; touch-action: pan-x pan-y;
  background: var(--color-surface);
}
/* Before the stage pins, the row rides along with the heading instead of
   scrolling on its own (app.js keeps it at its top meanwhile). */
.catalog:not(.is-grid) .catalog-stage:not(.is-pinned) .product-group { overflow-y: hidden; }
.product-carousel { position: relative; width: 100%; min-width: 0; }
.product-rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(680px, min(82vw, 900px));
  gap: var(--space-6); overflow-x: auto; overscroll-behavior-inline: contain;
  scroll-snap-type: inline mandatory; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 0 var(--rail-inline-pad) var(--space-5);
}
.product-rail::-webkit-scrollbar { display: none; }
/* Carousel arrows: bare chevrons floating on the screen edges, vertically
   centred, shown only while the products own the screen (same moment as the
   control bar). Fixed inside the transformed stage = pinned to the stage,
   which fills the screen while the row is pinned. */
.rail-arrow {
  position: fixed; top: 50%; z-index: 6;
  width: var(--rail-arrow-size); height: var(--rail-arrow-size); margin-top: calc(var(--rail-arrow-size) / -2);
  display: grid; place-items: center; padding: 0;
  border: 0; background: none; color: var(--color-chevron); cursor: pointer;
  filter: drop-shadow(0 1px 3px var(--color-label-shade));
  opacity: 0; visibility: hidden;
  transition: opacity var(--duration-fast), transform var(--duration-fast), visibility 0s linear var(--duration-fast);
}
.catalog.products-active .rail-arrow {
  opacity: .85; visibility: visible;
  transition: opacity var(--duration-fast), transform var(--duration-fast), visibility 0s;
}
.catalog.products-active .rail-arrow:hover:not(:disabled) { opacity: 1; }
.rail-arrow--prev:hover:not(:disabled) { transform: translateX(-3px); }
.rail-arrow--next:hover:not(:disabled) { transform: translateX(3px); }
.catalog.products-active .rail-arrow:disabled { opacity: .25; cursor: default; }
.rail-arrow[hidden] { display: none; }
.rail-arrow--prev { left: var(--rail-arrow-inset); }
.rail-arrow--next { right: var(--rail-arrow-inset); }
.rail-arrow .icon-spear { width: var(--rail-arrow-icon); }
.rail-status {
  display: flex; align-items: center; justify-content: center; gap: var(--space-3);
  min-height: 28px; padding: var(--space-2) var(--page-gutter) 0;
  color: var(--color-ink-soft); font: var(--weight-medium) var(--step--1)/1 var(--font-mono);
}
.rail-status::before, .rail-status::after { content: ""; width: clamp(20px, 4vw, 48px); height: 1px; background: var(--color-line); }

/* Grid view: the pinned stage drops back into normal flow and cards wrap into
   columns; the about card is revealed from underneath as the grid ends. */
.catalog.is-grid .catalog-showcase { height: auto; background: var(--color-surface); }
.catalog.is-grid .catalog-stage {
  position: relative; height: auto; overflow: visible;
  transform: none; transition: none; pointer-events: auto;
}
.catalog.is-grid .product-viewport { height: auto; overflow: visible; }
/* Room at the top for the control bar, which overlays the grid once stuck. */
.catalog.is-grid .product-group {
  position: relative; inset: auto; overflow: visible;
  padding: calc(var(--showcase-label-height) + var(--space-4)) 0 var(--section-y);
}
.catalog.is-grid .product-rail {
  grid-auto-flow: row; grid-auto-columns: auto;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  overflow: visible; scroll-snap-type: none;
}
/* Grid view reads freely: without the rail as their scroller, the cards' snap
   points would otherwise snap the whole page card by card. */
.catalog.is-grid .product-card { scroll-snap-align: none; }
.catalog.is-grid .rail-arrow,
.catalog.is-grid .rail-status { display: none; }

/* PRODUCT CARD */
.product-card {
  scroll-snap-align: start; display: grid; grid-template-columns: var(--card-columns); grid-template-rows: var(--card-rows);
  min-height: var(--card-min-height); background: var(--color-surface-raised); border: var(--line) solid var(--color-line);
}
.product-media {
  position: relative; min-height: var(--card-media-min-height); display: grid; place-items: center;
  height: var(--card-media-fixed-height, auto);
  padding: var(--space-6);
  border-right: var(--card-media-divider-side); border-bottom: var(--card-media-divider-bottom);
  background: repeating-linear-gradient(135deg, transparent 0 12px, color-mix(in srgb, var(--color-line) 38%, transparent) 12px 13px);
  color: var(--color-placeholder);
}
/* Board art sits inside the art area (never sizes it), so a tall board image
   can't stretch the card. Both sides are stacked; .show-top cross-fades to the
   grip side. Zoom scales the art box around --art-x / --art-y (app.js). */
.product-media.has-art { overflow: hidden; cursor: zoom-in; touch-action: pan-x pan-y; -webkit-user-select: none; user-select: none; }
.product-media.is-zoomed { cursor: zoom-out; }
/* Phone-card caption + details panel (shown only at phone width, below). */
.art-overlay, .art-panel { display: none; }
.product-art {
  position: absolute; inset: var(--space-4);
  transform: scale(var(--art-zoom, 1)); transform-origin: var(--art-x, 50%) var(--art-y, 50%);
  transition: transform var(--duration-med) var(--ease-out);
}
.product-media.is-pinching .product-art { transition: none; }
.board-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  transition: opacity var(--duration-med) var(--ease-out);
}
.board-img--top,
.product-media.show-top .board-img--graphic { opacity: 0; }
.product-media.show-top .board-img--top { opacity: 1; }
/* Golden glow flash behind the board art whenever its side flips: a slim
   vertical beam with a bright core. Sized from the art height (which always
   equals the board height), so it stays centered on the board no matter how
   wide the art box runs — a touch wider than the board so the halo spills
   past its silhouette. The beam's color is the background; its shape is
   carved by two independent masks multiplied together
   (mask-composite: intersect): a soft left/right falloff and a denser
   top/bottom ramp. The beam stays fully inside the art box so the card can
   never clip its faded ends. */
.product-art::before {
  content: ""; position: absolute;
  top: 0; left: 50%; height: 100%;
  aspect-ratio: 1 / 3;
  transform: translateX(-50%);
  background: radial-gradient(ellipse 50% 50% at center,
    #fffbee 0%, #fffbee 20%, #f3e6bc 55%, #e2d098 100%);
  -webkit-mask-image:
    linear-gradient(to right,
      rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 12.5%, rgba(0, 0, 0, 0.25) 25%,
      rgba(0, 0, 0, 0.4) 37.5%, rgba(0, 0, 0, 0.8) 50%,
      rgba(0, 0, 0, 0.4) 62.5%, rgba(0, 0, 0, 0.25) 75%,
      rgba(0, 0, 0, 0.1) 87.5%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom,
      rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.4) 12.5%, rgba(0, 0, 0, 0.65) 25%,
      rgba(0, 0, 0, 0.85) 37.5%, rgba(0, 0, 0, 1) 50%,
      rgba(0, 0, 0, 0.85) 62.5%, rgba(0, 0, 0, 0.65) 75%,
      rgba(0, 0, 0, 0.4) 87.5%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right,
      rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 12.5%, rgba(0, 0, 0, 0.25) 25%,
      rgba(0, 0, 0, 0.4) 37.5%, rgba(0, 0, 0, 0.8) 50%,
      rgba(0, 0, 0, 0.4) 62.5%, rgba(0, 0, 0, 0.25) 75%,
      rgba(0, 0, 0, 0.1) 87.5%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom,
      rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.4) 12.5%, rgba(0, 0, 0, 0.65) 25%,
      rgba(0, 0, 0, 0.85) 37.5%, rgba(0, 0, 0, 1) 50%,
      rgba(0, 0, 0, 0.85) 62.5%, rgba(0, 0, 0, 0.65) 75%,
      rgba(0, 0, 0, 0.4) 87.5%, rgba(0, 0, 0, 0) 100%);
  mask-composite: intersect;
  opacity: 0; pointer-events: none;
}
.product-media.art-flash .product-art::before { animation: art-glow-flash 1.4s ease-in-out; }
@keyframes art-glow-flash {
  0% { opacity: 0; }
  40% { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .product-media.art-flash .product-art::before { animation: none; }
}
.product-media .deck-placeholder {
  height: var(--card-art-height); width: auto; aspect-ratio: 1 / 4.3;
  border: var(--placeholder-line) currentColor; border-radius: var(--radius-board);
  display: grid; place-items: center; writing-mode: vertical-rl; font-family: var(--font-mono); font-size: .7rem;
}
.product-body { container: card-body / inline-size; padding: var(--card-pad); display: flex; flex-direction: column; }
.product-series { margin-bottom: var(--space-1); }
.product-title {
  margin: 0 0 var(--card-title-gap); font-size: var(--step-2); line-height: 1.05;
  letter-spacing: var(--tracking-title); /* names show as written in products.json */
}
/* Gold rule under the name, matching the phone caption divider. */
.product-title::after {
  content: ""; display: block; height: 1px; margin-top: var(--card-title-gap);
  background: var(--color-chevron);
}
.product-title-cn { font-weight: var(--weight-medium); letter-spacing: 0; color: var(--color-ink-soft); }
.product-title-slot { margin: 0 0 var(--space-3); padding: .55rem .7rem; min-height: 52px; display: flex; align-items: center; }
.product-price { margin: 0 0 var(--card-rhythm); font-family: var(--font-mono); color: var(--color-ink-soft); }
.product-card .product-price { color: var(--color-ink); font-size: var(--step-1); }
.price-note {
  margin-left: var(--space-2); color: var(--color-ink-soft);
  font-size: var(--step--1); text-transform: uppercase; letter-spacing: var(--tracking-label);
}
/* Availability (In stock / Pre-order / Sold out): small gold label above Summon. */
.availability-label { margin: 0 0 var(--space-3); align-self: var(--card-cta-align, flex-start); }
.product-body > .availability-label { margin-top: auto; }
.product-body > .availability-label + .summon-button { margin-top: 0; }
/* Sold out: replaces the price; setups are disabled and Summon dims. */
.price-sold-out {
  display: inline-block; padding: .3rem .75rem;
  border: var(--line) solid currentColor; border-radius: var(--radius-pill);
  font: var(--weight-medium) var(--step--1)/1.1 var(--font-mono);
  text-transform: uppercase; letter-spacing: var(--tracking-label);
}
.product-card.is-sold-out .summon-button { opacity: .4; cursor: not-allowed; }
.product-card.is-sold-out .summon-button:hover::before,
.product-card.is-sold-out .summon-button:focus-visible::before { background: var(--color-brush); transform: none; }
.product-card.is-sold-out .summon-button:hover,
.product-card.is-sold-out .summon-button:focus-visible { color: var(--color-brush-ink); }
.price-compare-at {
  margin-left: var(--space-2); color: var(--color-ink-soft);
  text-decoration: line-through;
}
/* Blurb + lore: one borderless box of fixed height. Overflow scrolls inside it
   (no scrollbar); edges with more text beyond them fade out (app.js toggles
   .has-more-above / .has-more-below). */
@property --copy-fade-top { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --copy-fade-bottom { syntax: "<length>"; inherits: false; initial-value: 0px; }
.product-copy {
  height: var(--card-copy-height); margin-bottom: var(--card-rhythm);
  overflow-y: auto; overscroll-behavior-y: auto; scrollbar-width: none;
  --copy-fade-top: 0px; --copy-fade-bottom: 0px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--copy-fade-top), #000 calc(100% - var(--copy-fade-bottom)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--copy-fade-top), #000 calc(100% - var(--copy-fade-bottom)), transparent 100%);
  transition: --copy-fade-top var(--duration-fast), --copy-fade-bottom var(--duration-fast);
}
.product-copy::-webkit-scrollbar { display: none; }
.product-copy.has-more-above { --copy-fade-top: var(--card-copy-fade); }
.product-copy.has-more-below { --copy-fade-bottom: var(--card-copy-fade-bottom); }
.product-copy:focus-visible { outline-offset: 4px; }
.product-copy p { margin: 0 0 var(--space-3); font-size: var(--step--1); line-height: var(--leading-body); }
.product-copy p:last-child { margin-bottom: 0; }
.product-blurb { color: var(--color-ink); }
.product-lore { color: var(--color-ink-soft); font-style: italic; }
.product-copy .is-placeholder { color: var(--color-placeholder); font-family: var(--font-mono); font-style: normal; letter-spacing: var(--tracking-mono); }
.pill-list { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--card-pills-gap); }
.pill { padding: .28rem .7rem; border: var(--line) solid var(--color-line); border-radius: var(--radius-pill); font: var(--step--1)/1.3 var(--font-mono); color: var(--color-ink-soft); }
/* Brush buttons (Summon, Equip, Browse, Send, Team): text over a brushstroke
   (assets/brushstroke1.svg as a mask), bold sans caps. Dark sections: gold at
   rest, white on hover. Light sections: black at rest, gold on hover.
   (--color-brush* come from the section's palette.) */
.summon-button {
  position: relative; isolation: isolate;
  /* The stroke's visual weight sits right of and below its box centre: nudge
     the text left / up with uneven padding (the stroke itself stays put). */
  --cta-nudge-x: 4px; --cta-nudge-y: 3px;
  margin-top: auto; align-self: var(--card-cta-align, auto); width: var(--card-cta-width, 15rem); aspect-ratio: 10 / 3; /* stroke stretched a touch taller for room around the text */
  padding: 0 calc(var(--space-6) + 2 * var(--cta-nudge-x)) calc(2 * var(--cta-nudge-y)) var(--space-6);
  display: grid; place-items: center;
  border: 0; background: none; color: var(--color-brush-ink); cursor: pointer;
  font: var(--weight-bold) var(--step-0)/1 var(--font-body);
  text-transform: uppercase; letter-spacing: .12em;
}
.summon-button::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--color-brush);
  -webkit-mask: url("assets/brushstroke1.svg") center / 100% 100% no-repeat;
  mask: url("assets/brushstroke1.svg") center / 100% 100% no-repeat;
  transition: background-color var(--duration-fast), transform var(--duration-fast) var(--ease-out);
}
.summon-button:hover::before, .summon-button:focus-visible::before { background: var(--color-brush-hover); transform: scale(1.04); }
.summon-button:hover, .summon-button:focus-visible { color: var(--color-brush-hover-ink); }
/* the hero is always dark */
.hero {
  --color-brush: var(--dark-brush); --color-brush-ink: var(--dark-brush-ink);
  --color-brush-hover: var(--dark-brush-hover); --color-brush-hover-ink: var(--dark-brush-hover-ink);
}
.hero-panel--story .summon-button { margin-top: var(--space-10); align-self: center; }
.contact-form .summon-button.form-send { justify-self: start; margin-top: var(--space-2); --card-cta-width: 12rem; }
.info-copy .team-button { justify-self: start; margin-top: var(--space-2); --card-cta-width: 12rem; }
/* Call-out box (About: sponsorship): a pale gold surface with a hairline gold
   border, small caps title, generous padding. Quiet enough for the light section. */
.callout {
  max-width: 36rem; padding: var(--space-10) clamp(var(--space-8), 4vw, var(--space-12));
  margin-top: var(--space-4);
  border: var(--line) solid var(--color-gold-surface-line); border-radius: var(--radius-xs);
  background: var(--color-gold-surface); color: var(--light-ink);
}
.callout-title {
  margin: 0 0 var(--space-4);
  font: var(--weight-bold) var(--step--1)/1.3 var(--font-body);
  text-transform: uppercase; letter-spacing: .14em;
  color: inherit;
}
.callout p { margin: 0; color: var(--light-ink); line-height: 1.6; }
.callout a {
  color: var(--light-ink); font-weight: var(--weight-bold);
  text-decoration: underline; text-decoration-color: currentColor;
  text-underline-offset: .2em; text-decoration-thickness: 2px;
}
.callout a:hover { text-decoration-color: currentColor; }
/* No claim link yet: still shows the hover, but reads as unavailable. */
.summon-button:disabled { cursor: not-allowed; }
a.summon-button { text-decoration: none; }
.product-card--empty {
  grid-template-columns: 1fr; align-content: center; justify-items: center; gap: var(--space-3);
  padding: var(--space-8); text-align: center; color: var(--color-ink-soft);
}
.product-card--empty p { margin: 0; }

/* VARIANT SELECTOR — deck / stock complete / pro complete */
.variant-toggle {
  display: var(--toggle-display); grid-auto-flow: column; grid-auto-columns: 1fr; flex-wrap: wrap;
  gap: 3px; width: var(--toggle-width); max-width: 100%; margin-bottom: var(--space-3); padding: 3px;
  border: var(--line) solid var(--color-line); border-radius: var(--toggle-radius);
}
.variant-segment {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: calc(var(--toggle-radius) - 3px);
  transition: background var(--duration-fast), color var(--duration-fast);
}
.variant-segment:has([aria-checked="true"]) { background: var(--color-ink); color: var(--color-surface-raised); }
.variant-option {
  padding: var(--toggle-option-pad); border: 0; border-radius: var(--radius-pill);
  background: none; color: inherit; cursor: pointer; line-height: 1.15; text-align: center;
  font: var(--weight-medium) var(--toggle-font-size)/1.15 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label);
}
.variant-option:disabled { color: var(--color-ink-soft); cursor: not-allowed; opacity: .55; }
.variant-segment:has(.variant-info) .variant-option { padding-right: .3rem; }
.variant-info {
  position: relative; flex: none; width: 20px; height: 20px; margin-right: var(--toggle-info-gap); padding: 0;
  display: grid; place-items: center;
  border: var(--line) solid currentColor; border-radius: var(--radius-round); background: none; color: inherit;
  font: var(--weight-semibold) .68rem/1 var(--font-mono); cursor: pointer; opacity: .75;
}
.variant-info:hover, .variant-info:focus-visible { opacity: 1; }
/* Tooltip anchors to the right edge so it never runs past the card. */
.variant-info::after {
  content: attr(data-tooltip); position: absolute; z-index: 2; bottom: calc(100% + 8px); right: -6px;
  padding: .35rem .6rem; white-space: nowrap; pointer-events: none;
  background: var(--color-ink); color: var(--color-surface-raised); border-radius: var(--radius-sm);
  font: var(--weight-regular) var(--step--1)/1.2 var(--font-mono); text-transform: none; letter-spacing: 0;
  opacity: 0; transform: translateY(4px);
  transition: opacity var(--duration-fast), transform var(--duration-fast);
}
.variant-info:hover::after, .variant-info:focus-visible::after { opacity: 1; transform: translateY(0); }
/* When the card's text column is too narrow for one pill row, the selector
   becomes three equal full-width cells (labels may wrap). Follows the column
   width, so it holds for stacked, grid and narrow side-by-side cards alike. */
@container card-body (max-width: 410px) {
  .variant-toggle {
    --toggle-display: grid;
    --toggle-width: 100%;
    --toggle-radius: var(--radius-md);
    --toggle-option-pad: .5rem .35rem;
    --toggle-info-gap: .35rem;
  }
}

/* Compact (stacked) product card — grid view at every width; phones set the
   same tokens in the responsive section. */
.catalog.is-grid {
  /* Grid can't centre the heading: any shift past the heading's bottom gap
     would leave it peeking behind the stuck control bar at the grid's start. */
  --head-shift: var(--space-2);
  --card-columns: 1fr;
  --card-rows: auto 1fr;
  --card-min-height: 0;
  --card-media-min-height: var(--card-media-height);
  --card-media-fixed-height: var(--card-media-height);
  --card-media-divider-side: 0;
  --card-media-divider-bottom: var(--line) solid var(--color-line);
  --card-art-height: calc(var(--card-media-height) - 4.5rem);
  --card-pad: var(--space-4);
  --card-title-gap: var(--space-3);
  --card-rhythm: var(--space-3);
  --card-copy-height: 7.5rem;
  --card-pills-gap: var(--space-3);
  --card-cta-width: 13rem;
  --card-cta-align: center;
}

/* VARIANT INFO MODAL */
.info-modal {
  width: min(560px, calc(100vw - 2 * var(--page-gutter)));
  max-height: calc(100svh - 2 * var(--space-8)); padding: 0;
  border: var(--line) solid var(--color-line); background: var(--color-surface-raised); color: var(--color-ink);
}
.info-modal::backdrop { background: var(--color-backdrop); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
html:has(.info-modal[open]) { overflow: hidden; }
.info-modal-inner { position: relative; display: grid; gap: var(--space-4); padding: clamp(1.5rem, 4vw, 2.5rem); }
.info-modal h2 {
  margin: 0; padding-right: var(--space-12); font-size: var(--step-2); line-height: 1.05;
  letter-spacing: var(--tracking-title); text-transform: uppercase;
}
.info-modal-media[hidden] { display: none; }
.info-modal-media { display: grid; place-items: center; overflow: hidden; min-height: 140px; }
.info-modal-media img { width: 100%; height: auto; display: block; }
.info-modal-body { min-height: 120px; padding: var(--space-4); display: flex; align-items: center; }
/* Team modal: same dialog as the setup info, with a scrolling member list. */
.team-modal { width: min(640px, calc(100vw - 2 * var(--page-gutter))); }
.team-modal h2 { text-transform: none; }
.team-list {
  display: grid; gap: var(--space-5); margin: 0; padding: 0 var(--space-1) 0 0; list-style: none;
  max-height: min(58vh, 560px); overflow-y: auto; overscroll-behavior: contain;
  border-top: var(--line) solid var(--color-gold-muted);
}
.team-member {
  display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: var(--space-5); align-items: start;
  padding: var(--space-5) 0; border-bottom: var(--line) solid color-mix(in srgb, var(--color-gold-muted) 45%, transparent);
}
.team-photo {
  aspect-ratio: 1; display: grid; place-items: center;
  background: var(--color-field); border: var(--line) solid var(--color-gold-muted); color: var(--color-gold-muted);
}
.team-photo img { width: 100%; height: 100%; object-fit: cover; }
.team-photo .brand-logo { width: 38%; opacity: .55; }
.team-name { margin: 0; font-size: var(--step-1); line-height: 1.15; }
.team-role { margin: .35rem 0 .45rem; }
.team-social { display: inline-flex; align-items: center; gap: .45rem; color: var(--color-gold-ink); text-decoration: none; font: var(--weight-medium) var(--step--1)/1 var(--font-mono); }
.team-social .social-icon { width: 18px; height: 18px; }
.team-bio { margin: .6rem 0 0; color: var(--color-ink-soft); font-size: var(--step--1); line-height: var(--leading-body); }
@media (max-width: 640px) {
  .team-member { grid-template-columns: 72px minmax(0, 1fr); gap: var(--space-4); }
}
.info-modal-close-form { position: absolute; top: var(--space-3); right: var(--space-3); margin: 0; }
.info-modal-close {
  width: 40px; height: 40px; display: grid; place-items: center; padding: 0; cursor: pointer;
  border: var(--line) solid var(--color-line); border-radius: var(--radius-round); background: transparent; color: var(--color-ink);
}
.info-modal-close:hover { background: var(--color-accent); color: var(--color-accent-ink); }
.info-modal-close svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; }

/* ---- Cart modal: head, scrolling item list, footer (subtotal + Checkout)
   that stays put at the bottom. Gold rules frame the list. ---- */
.cart-modal { width: min(600px, calc(100vw - 2 * var(--page-gutter))); overflow: hidden; }
.cart-shell {
  display: flex; flex-direction: column;
  max-height: calc(100svh - 2 * var(--space-8));
}
.cart-head { position: relative; padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1.5rem, 4vw, 2.5rem) 0; }
.cart-head .kicker { margin: 0 0 var(--space-2); }
.cart-head h2 { margin: 0; }
.cart-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  margin-top: var(--space-5); padding-bottom: var(--space-3);
  border-bottom: var(--line) solid var(--color-gold-muted);
}
.cart-summary { margin: 0; color: var(--color-ink-soft); font: var(--weight-medium) var(--step--1)/1.2 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.cart-clear {
  padding: .35rem 0; border: 0; background: none; cursor: pointer;
  color: var(--color-gold-ink); font: var(--weight-medium) var(--step--1)/1.2 var(--font-mono);
  text-transform: uppercase; letter-spacing: var(--tracking-label);
  text-decoration: underline; text-underline-offset: .25em; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
}
.cart-clear:hover { color: var(--color-ink); text-decoration-color: currentColor; }
.cart-clear.is-confirming { color: var(--color-badge); text-decoration-color: currentColor; }
.cart-clear[hidden] { display: none; }

.cart-list {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  margin: 0; padding: 0 clamp(1.5rem, 4vw, 2.5rem); list-style: none;
}
.cart-item {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: var(--space-4);
  padding: var(--space-5) 0;
  border-bottom: var(--line) solid color-mix(in srgb, var(--color-gold-muted) 45%, transparent);
}
.cart-item:last-child { border-bottom: 0; }
.cart-thumb {
  width: 64px; height: 88px; display: grid; place-items: center; overflow: hidden;
  background: var(--color-field); border: var(--line) solid color-mix(in srgb, var(--color-gold-muted) 55%, transparent);
}
.cart-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 6px; box-sizing: border-box; }
.cart-item-main { min-width: 0; display: grid; align-content: start; gap: .3rem; }
.cart-item-name { margin: 0; font: var(--weight-display) var(--step-1)/1.15 var(--font-display); color: var(--color-ink); }
.cart-item-meta { margin: 0; }
.cart-item-price { margin: 0; color: var(--color-ink-soft); font-size: var(--step--1); }
.cart-item-price s { margin-left: .35em; opacity: .7; }
.cart-item-side { display: grid; justify-items: end; align-content: space-between; gap: var(--space-3); }
.cart-line-total { margin: 0; color: var(--color-ink); font: var(--weight-medium) var(--step-0)/1.2 var(--font-body); white-space: nowrap; }
.cart-item.is-unavailable .cart-item-name,
.cart-item.is-unavailable .cart-thumb { opacity: .5; }
.cart-item-warning { margin: 0; color: var(--color-badge); font: var(--weight-medium) var(--step--1)/1.3 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label); }

/* Quantity: one round pill, minus / count / plus */
.qty-pill {
  display: inline-flex; align-items: center; margin-top: var(--space-2); justify-self: start;
  border: var(--line) solid var(--color-gold-muted); border-radius: var(--radius-pill);
}
.qty-pill button {
  width: 34px; height: 34px; display: grid; place-items: center; padding: 0;
  border: 0; border-radius: var(--radius-round); background: none; color: var(--color-ink); cursor: pointer;
}
.qty-pill button:hover:not(:disabled) { color: var(--color-gold-ink); }
.qty-pill button:disabled { opacity: .35; cursor: not-allowed; }
.qty-pill svg { width: 14px; height: 14px; }
.qty-value { min-width: 1.6em; text-align: center; font: var(--weight-medium) var(--step--1)/1 var(--font-mono); color: var(--color-ink); }
.cart-remove {
  width: 36px; height: 36px; margin-right: -8px; display: grid; place-items: center; padding: 0;
  border: 0; background: none; color: var(--color-ink-soft); cursor: pointer; border-radius: var(--radius-round);
}
.cart-remove:hover { color: var(--color-badge); }
.cart-remove svg { width: 19px; height: 19px; }

.cart-empty { padding: var(--space-10) clamp(1.5rem, 4vw, 2.5rem); text-align: center; }
.cart-empty[hidden] { display: none; }
.cart-empty p { margin: 0 0 var(--space-10); color: var(--color-ink-soft); }
.cart-browse {
  display: inline-flex; align-items: center; gap: .6rem; color: var(--color-ink); text-decoration: none;
  font: var(--weight-bold) var(--step--1)/1 var(--font-body); text-transform: uppercase; letter-spacing: .12em;
}
.cart-browse .icon-spear { width: 26px; height: 16px; color: var(--color-chevron); fill: currentColor; transition: transform var(--duration-fast); }
.cart-browse:hover .icon-spear { transform: translateX(3px); }

.cart-foot {
  flex: none; display: grid; gap: var(--space-2);
  padding: var(--space-5) clamp(1.5rem, 4vw, 2.5rem) clamp(1.25rem, 3vw, 2rem);
  border-top: var(--line) solid var(--color-gold-muted); background: var(--color-surface-raised);
}
.cart-foot[hidden] { display: none; }
.cart-subtotal { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
.cart-subtotal .gold-label { margin: 0; }
.cart-subtotal-amount { font: var(--weight-display) var(--step-2)/1 var(--font-display); color: var(--color-ink); }
.cart-savings { margin: 0; color: var(--color-gold-ink); font: var(--weight-medium) var(--step--1)/1.3 var(--font-mono); text-align: right; }
.cart-savings[hidden] { display: none; }
.cart-note { margin: 0; color: var(--color-ink-soft); font-size: var(--step--1); }
.cart-checkout { justify-self: center; width: min(100%, 16rem); margin-top: var(--space-3); }
.cart-checkout:disabled { opacity: .4; cursor: not-allowed; }
.cart-status { margin: 0; min-height: 1.3em; text-align: center; color: var(--color-ink-soft); font-size: var(--step--1); }
.cart-status:empty { min-height: 0; }
/* Wider screens: label + shipping note stacked on the left, amount + savings on the right */
@media (min-width: 641px) {
  .cart-foot { grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-6); row-gap: var(--space-1); }
  .cart-subtotal { display: contents; }
  .cart-subtotal .gold-label { grid-column: 1; grid-row: 1; align-self: end; }
  .cart-subtotal-amount { grid-column: 2; grid-row: 1; justify-self: end; }
  .cart-note { grid-column: 1; grid-row: 2; align-self: start; }
  .cart-savings { grid-column: 2; grid-row: 2; align-self: start; }
  .cart-checkout, .cart-status { grid-column: 1 / -1; }
}

/* Gear colourways double as the colour picker (radio pills) */
.colorway-option { cursor: pointer; background: none; font: inherit; }
.colorway-option[aria-checked="true"] { border-color: var(--color-ink); box-shadow: inset 0 0 0 1px var(--color-ink); color: var(--color-ink); }
.colorway-option:hover { border-color: var(--color-ink); }
.summon-button.is-added { pointer-events: none; }

/* ---- Catalog intro: gold tagline label, Limited Run stamp + note ---- */
.kicker--gold { color: var(--color-gold-ink); letter-spacing: var(--tracking-label); }
.catalog-head .kicker { text-transform: uppercase; }
.catalog-note { display: flex; align-items: center; margin-top: var(--space-5); max-width: 46rem; }
.catalog-note p strong { color: var(--color-ink); font-weight: var(--weight-bold); }
.catalog-note p {
  margin: 0; max-width: 46ch;
  color: var(--color-ink-soft); font-size: var(--step-0); line-height: 1.45;
}

/* ---- Bottom brush wave (catalog -> The Forge) ----
   Same idea as the ink wave on top: a mask filled with the catalog surface,
   hung off the bottom of the board row (.catalog-stage). Its upper half sits
   behind the row (a solid patch fills the brush's gaps, so no holes); the
   lower half hangs below it. When the row slides away at the catalog's end
   the wave sweeps up over The Forge with it and leaves completely (the exit
   slide includes the overhang), so The Forge is clean once it's in. */
:root {
  --wave-height: calc(100vw * 1080 / 1920);
  --wave-sink: .5;               /* share of the wave inside its section */
  --wave-overhang: calc(var(--wave-height) * (1 - var(--wave-sink)));
}
.brush-divider {
  position: absolute; left: 0; right: 0; z-index: 0; pointer-events: none;
  top: calc(100% - var(--wave-height) * var(--wave-sink)); height: var(--wave-height);
  background: var(--color-surface);
  --wave-edge: calc(var(--wave-sink) * 100%);
  -webkit-mask:
    url("assets/brushwave.svg") center / 100% 100% no-repeat,
    linear-gradient(to bottom, #000 var(--wave-edge), transparent calc(var(--wave-edge) + 10%));
  mask:
    url("assets/brushwave.svg") center / 100% 100% no-repeat,
    linear-gradient(to bottom, #000 var(--wave-edge), transparent calc(var(--wave-edge) + 10%));
}
/* (.catalog-showcase is z-index 2, so the board row stays above the wave) */

/* About's wave: About-coloured (theme-inverse), on the Events panel's bottom
   edge. Solid below its middle (melts into About), ragged above, so it rises
   over Events as Events scrolls away; app.js fades it in only once that
   starts. About's reveal is pushed down by the overhang, so the wave is gone
   once About is fully in. */
.brush-divider--rise {
  z-index: 1; opacity: 0;
  -webkit-mask:
    url("assets/brushwave.svg") center / 100% 100% no-repeat,
    linear-gradient(to top, #000 var(--wave-edge), transparent calc(var(--wave-edge) + 10%));
  mask:
    url("assets/brushwave.svg") center / 100% 100% no-repeat,
    linear-gradient(to top, #000 var(--wave-edge), transparent calc(var(--wave-edge) + 10%));
}

/* ---- HELD SECTIONS (gear, events; about uses the same idea) ----
   Each wrapper tucks one viewport under the section before it (negative top
   margin + lower z-index), so its pinned panel is revealed as that section
   scrolls away, holds for its --scene-*-hold, then scrolls off to reveal the
   next. Panels scroll internally when their content runs long. */
.section-tall { position: relative; margin-top: -100vh; margin-top: -100svh; background: var(--color-surface); }
.section-tall--gear { z-index: 4; height: calc((1 + var(--scene-gear-hold)) * 100vh); height: calc((1 + var(--scene-gear-hold)) * 100svh); }
/* a little extra headroom: the wave passes over the top of The Forge */
.gear-section { padding-top: calc(var(--header-height) + var(--space-12)); }
.section-tall--events { z-index: 3; height: calc((1 + var(--scene-events-hold)) * 100vh); height: calc((1 + var(--scene-events-hold)) * 100svh); }
.feature-section {
  position: sticky; top: 0;
  height: 100vh; height: 100svh; overflow-y: auto;
  display: flex; flex-direction: column; gap: clamp(1.5rem, 3.2vw, 2.75rem);
  padding: calc(var(--header-height) + var(--space-8)) var(--page-gutter) var(--space-12);
  background: var(--color-surface); color: var(--color-ink);
}
.feature-section > * { width: min(100%, var(--content-max)); margin-inline: auto; }
/* safe vertical centring: short content centres, tall content starts at the top */
.feature-section > :first-child { margin-top: auto; }
.feature-section > :last-child { margin-bottom: auto; }
.feature-head h2 {
  margin: var(--space-3) 0 0; font-size: var(--step-3); line-height: 1;
  letter-spacing: var(--tracking-heading); text-transform: uppercase;
}
.feature-head h2::after {
  content: ""; display: block; width: 4.5rem; height: 1px; margin-top: var(--space-4);
  background: var(--color-gold-muted);
}
.feature-intro { margin: var(--space-4) 0 0; max-width: 46ch; color: var(--color-ink-soft); }

/* Shared gold bits for the feature cards */
.gold-label {
  margin: 0 0 var(--space-2); font: var(--weight-medium) var(--step--1)/1.2 var(--font-mono);
  text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--color-gold-ink);
}
.pill--gold { border-color: var(--color-gold-muted); color: var(--color-ink); }
.swatch {
  display: inline-block; width: .8em; height: .8em; margin-right: .45em; vertical-align: -.08em;
  border-radius: 50%; background: var(--swatch); box-shadow: inset 0 0 0 1px rgba(0,0,0,.28);
}

/* ---- THE FORGE: limited hardware (light accent section) ---- */
.gear-section {
  --card-cta-width: 15rem;
  --gear-mat: #f4f4f1;          /* product photos sit on a light mat in any scheme */
  --gear-mat-ink: #7d6742;
}
.gear-carousel { position: relative; }
.gear-rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: 100%; gap: var(--space-6);
  overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
}
.gear-arrow { position: absolute; top: 50%; z-index: 2; transform: translateY(-50%); }
.gear-arrow--prev { left: calc(-1 * var(--space-4)); }
.gear-arrow--next { right: calc(-1 * var(--space-4)); }
.gear-card {
  scroll-snap-align: start;
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  border: var(--line) solid var(--color-line); background: var(--color-surface-raised);
}
.gear-gallery {
  position: relative; min-height: clamp(320px, 56svh, 600px);
  background: var(--gear-mat); border-right: var(--line) solid var(--color-line);
  -webkit-tap-highlight-color: transparent; user-select: none;
}
.gear-gallery[role="button"] { cursor: pointer; }
.gear-gallery:focus-visible { outline-offset: -4px; }
.gear-slides { position: absolute; inset: 0; overflow: hidden; }
.gear-slide {
  position: absolute; inset: 0; margin: 0; display: grid; place-items: center;
  opacity: 0; transition: opacity var(--duration-med) var(--ease-out);
}
.gear-slide.is-active { opacity: 1; }
/* pinned to the slide: a % height inside the centring grid resolved to auto, so wide
   stacked cards (tablets) sized the photo by width alone and cropped its bottom */
.gear-slide img { position: absolute; inset: 0; box-sizing: border-box; width: 100%; height: 100%; object-fit: contain; padding: 7%; }
.gear-slide-placeholder {
  display: grid; place-items: center; width: 70%; height: 60%;
  border: var(--placeholder-line) #b4b4ac; color: #8d8d85;
  font: var(--step--1)/1 var(--font-mono); letter-spacing: var(--tracking-mono);
}
.gear-counter {
  position: absolute; top: var(--space-4); right: var(--space-4);
  font: var(--weight-medium) var(--step--1)/1 var(--font-mono); letter-spacing: var(--tracking-label); color: var(--gear-mat-ink);
}
.gear-dots { position: absolute; left: 0; right: 0; bottom: var(--space-4); display: flex; justify-content: center; gap: .5rem; }
.gear-dot { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--color-gold-muted); transition: background var(--duration-fast); }
.gear-dot.is-active { background: var(--color-gold-muted); }
.gear-hint {
  position: absolute; left: var(--space-4); top: var(--space-4);
  font: var(--step--1)/1 var(--font-mono); color: #8d8d85; letter-spacing: var(--tracking-mono);
}
.gear-body { display: flex; flex-direction: column; gap: var(--space-5); padding: clamp(1.25rem, 2.5vw, 2.25rem); }
.gear-title { margin: var(--space-1) 0 0; font-size: var(--step-2); line-height: 1.05; letter-spacing: var(--tracking-title); }
.gear-title::after { content: ""; display: block; height: 1px; margin-top: var(--space-4); background: var(--color-gold-muted); }
.gear-body .product-price { margin: 0; color: var(--color-ink); font-size: var(--step-1); }
.gear-blurb { margin: 0; color: var(--color-ink-soft); font-size: var(--step--1); line-height: var(--leading-body); max-width: 58ch; }
.gear-highlights { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .45rem 1.25rem; }
.gear-highlights li { display: flex; align-items: center; gap: .55rem; font-size: var(--step--1); }
.gear-highlights .icon-spear { width: 1.25em; color: var(--color-gold-muted); }
.spec-list { margin: 0; }
.spec-row {
  display: grid; grid-template-columns: minmax(6.5rem, 8rem) 1fr; gap: var(--space-4);
  padding: .55rem 0; border-top: var(--line) solid color-mix(in srgb, var(--color-gold-muted) 55%, transparent);
}
.spec-row:last-child { border-bottom: var(--line) solid color-mix(in srgb, var(--color-gold-muted) 55%, transparent); }
.spec-row dt { font: var(--weight-medium) var(--step--1)/1.4 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--color-gold-ink); }
.spec-row dd { margin: 0; font-size: var(--step--1); line-height: 1.45; }
.gear-body .pill-list { margin: 0; }
.gear-body .summon-button { margin-top: 0; align-self: flex-start; }
.gear-body .availability-label { margin: var(--space-2) 0 0; }
.gear-card.is-sold-out .summon-button { opacity: .4; cursor: not-allowed; }

/* ---- EVENTS (dark section) ---- */
.events-feed { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-4); }
.events-list {
  /* positioned, so screen-reader-only labels stay clipped inside the slider */
  position: relative;
  grid-row: 1 / span 3; margin: 0; padding: 0; list-style: none;
  height: var(--events-list-h, auto); overflow-y: auto; scroll-snap-type: y mandatory;
  /* no overscroll containment: at the list ends a swipe carries on to the section / page */
  border-top: var(--line) solid var(--color-gold-muted);
}
.events-list:focus-visible { outline-offset: 4px; }
.event {
  scroll-snap-align: start;
  display: grid; grid-template-columns: 5.25rem minmax(0, 1fr); gap: var(--space-5);
  padding: var(--space-5) 0; border-bottom: var(--line) solid color-mix(in srgb, var(--color-gold-muted) 45%, transparent);
}
.event-date {
  display: grid; justify-items: center; align-content: start; gap: .2rem;
  padding: .7rem .25rem .6rem; border: var(--line) solid var(--color-gold-muted); color: var(--color-gold-ink);
  text-align: center;
}
.event-weekday, .event-month { font: var(--weight-medium) .68rem/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.event-day { font: var(--weight-display) var(--step-2)/1 var(--font-display); color: var(--color-ink); white-space: nowrap; }
.event-day--range { font-size: var(--step-1); }
.event-tags { display: flex; flex-wrap: wrap; gap: .35rem; }
.event-tags .pill { padding: .16rem .55rem; font-size: .68rem; }
.event-title { margin: .45rem 0 .5rem; font-size: var(--step-1); line-height: 1.15; }
.event-meta { display: flex; flex-wrap: wrap; gap: .35rem 1.25rem; margin: 0 0 .55rem; font: var(--step--1)/1.35 var(--font-mono); color: var(--color-ink-soft); }
.event-meta span { display: inline-flex; align-items: center; gap: .4rem; }
.event-meta svg { width: 14px; height: 14px; flex: none; fill: none; stroke: var(--color-gold-muted); stroke-width: 1.6; }
.event-desc { margin: 0; max-width: 60ch; color: var(--color-ink-soft); font-size: var(--step--1); line-height: var(--leading-body); }
.event-note {
  display: flex; align-items: flex-start; gap: .5rem; margin: .6rem 0 0; max-width: 60ch;
  color: var(--color-gold-ink); font-size: var(--step--1); line-height: 1.45;
}
.event-note .icon-spear { width: 1.25em; margin-top: .22em; color: var(--color-gold-muted); }
.event--pinned .event-date { border-style: dashed; }
.event--pinned .event-day { font-size: var(--step-1); }
.event-link { display: inline-flex; align-items: center; gap: .4rem; margin-top: .6rem; color: var(--color-gold-ink); font: var(--weight-medium) var(--step--1)/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label); text-decoration: none; }
.event-link .icon-spear { width: 1.3em; }
.events-end {
  scroll-snap-align: end; padding: var(--space-5) 0 var(--space-2);
  color: var(--color-ink-soft); font: var(--step--1)/1.5 var(--font-mono); letter-spacing: var(--tracking-mono);
}
.events-arrow {
  width: 44px; height: 44px; display: grid; place-items: center; padding: 0; cursor: pointer;
  border: 0; background: none; color: var(--color-chevron); transition: opacity var(--duration-fast), transform var(--duration-fast);
}
.events-arrow .icon-spear { width: 26px; }
.events-arrow:disabled { opacity: .25; cursor: default; }
.events-arrow:not(:disabled):hover { transform: scale(1.1); }
.events-arrow--up { grid-column: 2; grid-row: 1; align-self: start; }
.events-arrow--down { grid-column: 2; grid-row: 3; align-self: end; }
.events-status {
  grid-column: 2; grid-row: 2; align-self: center; justify-self: center; margin: 0; writing-mode: vertical-rl;
  font: var(--weight-medium) var(--step--1)/1 var(--font-mono); letter-spacing: var(--tracking-label); color: var(--color-gold-ink);
}
.events-feed.is-static .events-arrow, .events-feed.is-static .events-status { display: none; }

@media (min-width: 1100px) {
  /* wide cards: specs sit beside ride + colourways */
  .gear-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(1.25rem, 2.5vw, 2.25rem); align-content: start; }
  .gear-body > * { grid-column: 1 / -1; }
  .gear-body > .gear-block--ride { grid-column: 1; grid-row: 4; }
  .gear-body > .gear-block--colors { grid-column: 1; grid-row: 5; }
  .gear-body > .gear-block--specs { grid-column: 2; grid-row: 4 / span 2; }
  .gear-body > .gear-block--ride, .gear-body > .gear-block--colors, .gear-body > .gear-block--specs { align-self: start; }
  /* the call to action closes the card, under every spec: label, then Equip */
  .gear-body > .availability-label { grid-column: 1 / -1; grid-row: 6; margin-top: var(--space-4); }
  .gear-body > .summon-button { grid-column: 1 / -1; grid-row: 7; justify-self: start; margin-top: calc(var(--space-3) - var(--space-5)); } /* label-to-button gap as on boards */
  .gear-highlights { grid-template-columns: 1fr; }
}
@media (min-width: 901px) {
  /* events: heading column + feed column */
  .events-section { display: grid; grid-template-columns: minmax(240px, .72fr) minmax(0, 1.28fr); column-gap: clamp(2rem, 6vw, 6rem); align-content: safe center; }
  .events-section > *, .events-section > :first-child, .events-section > :last-child { width: auto; margin: 0; }
}
@media (max-width: 900px) {
  .gear-card { grid-template-columns: 1fr; }
  .gear-gallery { min-height: clamp(260px, 42svh, 440px); border-right: 0; border-bottom: var(--line) solid var(--color-line); }
}
@media (max-width: 640px) {
  /* Limited items stack plainly on phones: photo, then details. */
  .gear-highlights { grid-template-columns: 1fr; }
  .gear-arrow--prev { left: 0; }
  .gear-arrow--next { right: 0; }
  .gear-section { --card-cta-width: 13rem; }
  .gear-body .summon-button { align-self: center; }
  .gear-body .availability-label { align-self: center; }
  .event { grid-template-columns: 4.25rem minmax(0, 1fr); gap: var(--space-4); }
  .catalog-note p { max-width: none; }
}

/* ABOUT — held beneath the events, then released into contact */
.about-tall {
  position: relative; z-index: 2;
  /* tucked under Events, minus the rising wave's overhang (see .brush-divider--rise) */
  --about-tuck: calc(-100svh + var(--wave-overhang));
  height: calc((1 + var(--scene-about-hold)) * 100vh);
  height: calc((1 + var(--scene-about-hold)) * 100svh);
  margin-top: calc(-100vh + var(--wave-overhang)); margin-top: var(--about-tuck);
  background: var(--color-surface);
}
.info-section {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  display: grid; grid-template-columns: .8fr 1.2fr; align-content: safe center;
  gap: clamp(2rem, 7vw, 7rem);
  padding: calc(var(--header-height) + var(--space-8)) var(--page-gutter) var(--section-y);
  background: var(--color-surface); color: var(--color-ink);
  /* Like the hero panels: the section stays pinned while its content scrolls
     internally, so bio + social links stay reachable when they overflow. */
  overflow-y: auto;
}
.info-section h2 { margin: 0; font-size: var(--step-3); line-height: 1; }
.info-copy { display: grid; gap: var(--space-5); }
.kicker--brand { display: flex; align-items: center; gap: .6rem; color: var(--color-ink); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.kicker--brand .brand-logo { width: 1.9em; height: 1.9em; flex: none; }
.info-slot p:first-child { margin-top: 0; }

/* CONTACT */
.contact-section {
  padding: var(--section-y) var(--page-gutter); background: var(--color-surface); color: var(--color-ink);
}
.contact-layout {
  display: grid; grid-template-columns: minmax(240px, .65fr) minmax(320px, 1.35fr);
  gap: clamp(2rem, 8vw, 8rem); align-items: start;
}
.contact-section h2 { margin: var(--space-3) 0 var(--space-6); font-size: var(--step-3); line-height: 1; }
.contact-note { max-width: 34ch; color: var(--color-ink-soft); }
.contact-form { display: grid; gap: var(--space-5); }
.field { display: grid; gap: var(--space-2); }
.field label { font: var(--step--1)/1.2 var(--font-mono); color: var(--color-ink-soft); }
.field input, .field textarea {
  width: 100%; border: var(--line) solid var(--color-line); border-radius: 0;
  padding: .9rem 1rem; background: var(--color-field); color: var(--color-ink);
}
.field textarea { min-height: 150px; resize: vertical; }
.form-note { margin: -.4rem 0 0; color: var(--color-ink-soft); font-size: var(--step--1); }
.site-footer {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-5); flex-wrap: wrap;
  padding: var(--space-10) var(--page-gutter); background: var(--color-page); color: var(--color-on-dark-soft);
  font: var(--step--1)/1.4 var(--font-mono);
}
.footer-logo { display: block; width: 112px; color: var(--color-on-dark); }
.footer-logo:hover { color: var(--color-accent); }
.footer-meta { margin: 0; }

/* ---------- 3. RESPONSIVE ---------- */
@media (max-width: 1100px) {
  :root { --grid-columns: 2; }
}

@media (max-width: 900px) {
  :root { --header-height: 64px; }
  .hero-grid, .video-layout, .info-section, .contact-layout { grid-template-columns: 1fr; }
  .hero-grid { gap: var(--space-5); }
  .hero-copy { max-width: 580px; }
  .board-stack { min-height: 210px; }
  .product-rail { grid-auto-columns: min(88vw, 760px); }
}

@media (max-width: 640px) {
  :root {
    --page-gutter: 1rem;
    --section-y: 4rem;
    --grid-columns: 1;
    --rail-arrow-size: 36px;
    --rail-arrow-icon: 30px;
    --showcase-label-top: calc(var(--header-height) + var(--space-2));
  }
  /* Phones always use the compact (stacked) card — same values as grid view. */
  .catalog {
    --card-columns: 1fr;
    --card-rows: auto 1fr;
    --card-min-height: 0;
    --card-media-min-height: var(--card-media-height);
    --card-media-fixed-height: var(--card-media-height);
    --card-media-divider-side: 0;
    --card-media-divider-bottom: var(--line) solid var(--color-line);
    --card-art-height: calc(var(--card-media-height) - 4.5rem);
    --card-pad: var(--space-4);
    --card-title-gap: var(--space-3);
    --card-rhythm: var(--space-3);
    --card-copy-height: 7.5rem;
    --card-pills-gap: var(--space-3);
    --card-cta-width: 13rem;
    --card-cta-align: center;
  }
  .site-header { min-height: var(--header-height); }
  .site-header { --header-logo-height: 17px; }
  .nav-toggle { display: block; order: 2; margin-right: -10px; }
  /* cart right up against the hamburger (cancels the header gap) */
  .cart-button { order: 1; margin: -6px calc(-1 * var(--space-6)) -6px auto; }
  /* narrow phones: the full logo gives way; cart + hamburger never shrink */
  .site-logo { flex: 0 1 auto; min-width: 0; max-width: calc(100vw - 2 * var(--page-gutter) - 88px - var(--space-4)); }
  .main-nav {
    position: absolute; top: 100%; left: 0; right: 0;
    display: none; flex-direction: column; align-items: stretch; gap: 0;
    background: var(--color-nav-mobile); border-top: var(--line) solid var(--color-line-dark-faint);
  }
  .main-nav.is-open { display: flex; }
  .main-nav a { padding: 1rem var(--page-gutter); border-bottom: var(--line) solid var(--color-line-dark-faint); }
  .hero-panel { padding-top: calc(var(--header-height) + var(--space-8)); }
  .hero-panel--title { padding-top: calc(var(--header-height) + var(--space-16)); }
  .hero-logo { margin-bottom: var(--space-5); }
  /* Phrases are fitted to the width (app.js); shorter ones sit centred in the
     height reserved for the tallest. */
  .hero h1 { margin-bottom: var(--space-6); display: flex; flex-direction: column; justify-content: center; }
  .lore-slot { min-height: 74px; }
  .board-stack { min-height: 170px; }
  .board-silhouette { width: 43px; }

  .catalog-controls { grid-template-columns: auto minmax(0, max-content) auto 1fr; gap: var(--space-2); }
  .catalog-controls-line { display: none; }
  .catalog-count { justify-self: end; }
  .control-button { padding: .5rem .75rem; }
  .control-button--icon { padding: .45rem; }
  .product-rail {
    grid-auto-columns: calc(100vw - (var(--page-gutter) * 2));
    padding: 0 var(--page-gutter) var(--space-5); gap: var(--space-5);
  }
  .product-title-slot { min-height: 36px; margin-bottom: var(--space-2); padding: .4rem .55rem; }
  .rail-status { min-height: 24px; padding-top: var(--space-1); }
  .info-section { padding-inline: var(--page-gutter); }

  /* Phone cards: the art area carries a gradient caption (series, name, tags,
     More) below the board, and a scrollable details panel that covers the art.
     The body below keeps only the setup selector, price and Summon. */
  /* The art area is two rows: the board fills the top and the caption takes the
     height its content needs. The board's tail tucks --art-tuck under the
     caption's fade, so they read as one piece; the caption text never covers it. */
  :root { --card-media-height: clamp(500px, 82svh, 740px); }
  /* Every caption reserves the same height so all boards render the same size;
     a caption that ever needs more simply grows (that board shrinks a little). */
  .catalog {
    --card-art-height: 88%;
    --toggle-font-size: var(--step--1);
    --art-caption-fade: 3rem;   /* gradient above the caption */
    --art-tuck: .25rem;         /* extra slide of the board tail into that gradient */
    --art-caption-min: 11rem;
  }
  .product-media {
    overflow: hidden; padding: 0;
    grid-template-rows: minmax(0, 1fr) auto; place-items: stretch;
  }
  .product-art { position: relative; inset: auto; margin: var(--space-3) var(--space-4) calc(-1 * var(--art-tuck)); }
  .product-media > .deck-placeholder { place-self: center; }
  /* Before the panel opens a phone card is just the art + caption. */
  .product-body { display: none; }
  .art-overlay {
    display: flex; flex-direction: column; justify-content: flex-end; position: relative; z-index: 2;
    min-height: var(--art-caption-min);
    /* One continuous ramp: the fade above (::before) reaches --art-caption-start,
       then the shade keeps deepening down through the text, full only at the base. */
    --art-caption-start: color-mix(in srgb, var(--color-art-shade) 50%, transparent);
    background: linear-gradient(to bottom,
      var(--art-caption-start) 0%,
      color-mix(in srgb, var(--color-art-shade) 72%, transparent) 35%,
      color-mix(in srgb, var(--color-art-shade) 90%, transparent) 65%,
      var(--color-art-shade) 100%);
    transition: opacity var(--duration-fast);
  }
  .art-overlay::before {
    content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--art-caption-fade);
    background: linear-gradient(to top, var(--art-caption-start), transparent); pointer-events: none;
  }
  .art-overlay-open {
    display: grid; gap: .35rem; justify-items: start; width: 100%;
    padding: var(--space-1) var(--space-4) var(--space-4); border: 0; background: none; cursor: pointer;
    color: var(--color-on-dark); text-align: left; font: inherit;
  }
  .art-series { font: var(--step--1)/1.2 var(--font-mono); color: var(--color-on-dark-soft); }
  .art-name { font: var(--weight-display) var(--step-2)/1.05 var(--font-display); letter-spacing: var(--tracking-title); }
  .art-divider { justify-self: stretch; height: 1px; margin: .3rem 0 .1rem; background: var(--color-chevron); }
  .art-tags { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .15rem; }
  .art-overlay .pill { padding: .2rem .55rem; font-size: .68rem; }
  /* Bottom row of the caption: starting price on the left, More tucked right. */
  .art-foot { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); justify-self: stretch; margin-top: .2rem; }
  .art-from { font: var(--step--1)/1 var(--font-mono); color: var(--color-on-dark-soft); white-space: nowrap; }
  .art-price { display: inline-flex; align-items: center; gap: .45rem; min-width: 0; }
  .avail-pill {
    padding: .18rem .45rem; border: var(--line) solid var(--color-gold-muted); border-radius: var(--radius-pill);
    font: var(--weight-medium) .62rem/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tracking-label);
    color: var(--color-gold-ink); white-space: nowrap;
  }
  .is-sold-out .art-from { color: var(--color-on-dark); text-transform: uppercase; letter-spacing: var(--tracking-label); }
  .art-more {
    font: var(--weight-medium) var(--step--1)/1 var(--font-mono);
    text-transform: uppercase; letter-spacing: var(--tracking-label);
    color: var(--color-on-dark); border-bottom: var(--line) solid currentColor; padding-bottom: 2px;
  }
  .art-panel {
    display: block; position: absolute; inset: 0; z-index: 3;
    container: card-body / inline-size; /* same selector layout rules as the card body */
    /* scroll chains on to the section / page once the panel hits its ends */
    overflow-y: auto; overscroll-behavior: auto; scrollbar-width: none;
    padding: var(--space-5) var(--space-4) var(--space-8);
    background: var(--color-art-shade); color: var(--color-ink);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    opacity: 0; visibility: hidden; transform: translateY(12px);
    transition: opacity var(--duration-med) var(--ease-out), transform var(--duration-med) var(--ease-out), visibility 0s linear var(--duration-med);
  }
  .product-media.panel-open .art-panel {
    opacity: 1; visibility: visible; transform: none;
    transition: opacity var(--duration-med) var(--ease-out), transform var(--duration-med) var(--ease-out), visibility 0s;
  }
  .product-media.panel-open .art-overlay { opacity: 0; pointer-events: none; }
  .art-panel:focus { outline: none; }
  .art-panel-close {
    position: sticky; top: 0; float: right; z-index: 1; margin: 0 0 var(--space-2) var(--space-3);
    width: 36px; height: 36px; display: grid; place-items: center; padding: 0; cursor: pointer;
    border: var(--line) solid var(--color-line-dark); border-radius: var(--radius-round);
    background: var(--color-art-shade); color: var(--color-on-dark);
  }
  .art-panel-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; }
  .art-panel-name { margin: var(--space-1) 0 var(--space-3); font-size: var(--step-2); line-height: 1.05; letter-spacing: var(--tracking-title); }
  .art-panel .product-price { margin: var(--space-2) 0 var(--space-4); }
  .art-panel-copy { margin-bottom: var(--space-4); }
  .art-panel-copy p { margin: 0 0 var(--space-3); font-size: var(--step-0); line-height: var(--leading-body); }
  .art-panel-copy .product-blurb { color: var(--color-ink); }
  .art-panel-copy .product-lore { color: var(--color-ink-soft); font-style: italic; }
  .art-panel-copy .is-placeholder { color: var(--color-placeholder); font-family: var(--font-mono); font-style: normal; font-size: var(--step--1); }
  .art-panel .pill-list { margin-bottom: var(--space-6); }
  .art-panel .summon-button { margin: 0 auto; }
  .art-panel .availability-label { text-align: center; }
}

@media (max-height: 740px) and (min-width: 641px) {
  .hero-panel--story { transform: scale(.88); transform-origin: 50% 52%; }
  .board-stack { min-height: 210px; }
}

/* ---------- 4. MOTION PREFERENCES ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; }
  .hero-backdrop, .hero-video, .hero-panel--title { transform: none !important; }
}
