/* Atelier 151 — "HUD" direction, rev 5: "Taffy Dreams" recolour (Bright
   Spring palette #14). Same instrument panel, repainted spring-bright.
   Ground: pale sky blue #D1EBFA, with lighter and deeper tints of the same
   blue for panels, the photo well, the header and the hero. One ink: deep
   teal #0B2A33 carries every word — titles, prices, labels. The four brights
   are fills, borders and marks, never text on the light surfaces: teal
   #239FA9 draws the HUD (scan line, brackets, rulers, diamonds, frames,
   hover rims, glows), pink #F4649F is the primary key with an ink label,
   mint #4AE5AB is the In-Stock node and the footer accent, mustard #E1B808
   fills the JP badge and ::selection behind ink text. Deep teal #0D626F is
   the only coloured word (links, active nav) and the focus ring. The footer
   is the one dark band (ink), where the brights may be text.
   Palette measured (WCAG 2.x):
   #0B2A33 on #D1EBFA 12.2 · on #E4F2FC 13.2 · on #F0F8FE 14.0 · on #B7DBF2 10.4
     · on #C3E1F5 11.1 · on #BFE2F7 11.1 · on #C9E5F7 11.5 · on the hero chip ~12.1
   #16414E on #D1EBFA 9.0 · on #E4F2FC 9.7 · on #B7DBF2 7.6 · on #C3E1F5 8.1
   #2E5A66 on #D1EBFA 6.1 · on #E4F2FC 6.7 · on #BFE2F7 5.6 · on the hero chip 5.6
     · on #C3E1F5 5.6 · on #B7DBF2 5.2
   #37616D on #D1EBFA 5.5 · on #E4F2FC 6.0 · on #B7DBF2 4.7 · on the hero chip 5.6
     · on #C3E1F5 5.0
   #0D626F on #D1EBFA 5.7 · on #E4F2FC 6.2 · on #C3E1F5 5.2 · on #C9E5F7 5.4
     · on #BFE2F7 5.2 · on #B7DBF2 4.8 — links, active nav, focus rings
   #0A4E58 on #D1EBFA 7.6 (link hover)
   #0B2A33 on #F4649F 5.15 (btn) · on #F782B3 6.3 (btn hover) · on #EF5796 4.7
     (btn active) · on #E1B808 7.9 (JP badge, ::selection) · on #4AE5AB 9.4
   #F0F8FE on rgba(11,42,51,.88) >=9.8:1 over the well (EN badge)
   On #0B2A33 (footer): #D1EBFA 12.2 · #9CC4D4 8.1 · #7FA6B5 5.8 · #4AE5AB 9.4
   #239FA9 on #D1EBFA 2.57 · on #E4F2FC 2.78 — FILL/BORDER/MARK-ONLY, never
     text: every state near it is duplicated by words, motion or a >=3:1 channel
   #4AE5AB on #D1EBFA 1.30 · #E1B808 1.53 · #F4649F 2.37 — FILL-ONLY behind ink
   #4A7684 on #D1EBFA 4.0 · on #E4F2FC 4.4 · on #C3E1F5 3.7 · on #C9E5F7 3.8
     · on #B7DBF2 3.4 — CONTROL BORDERS >=3:1, never text
   #8FB6C9 on #D1EBFA 1.8 — ORNAMENT ONLY
   #6E5900 on #E4F2FC 6.0 (dormant .stock--low tint)
   Prices are IBM Plex Mono 500 only — Orbitron's slashed zero never renders
   a figure. */

:root {
  --bg: #d1ebfa;               /* pale sky blue ground */
  --abyss: #0b2a33;            /* footer: the one dark band, deep teal-ink */
  --panel: #e4f2fc;            /* cards, modules: lifted sky */
  --panel-hi: #f0f8fe;
  --well: #b7dbf2;             /* photo viewport: deeper sky */
  --ink: #0b2a33;              /* every word on the light surfaces */
  --ink-2: #16414e;            /* was --bright in the dark rev; the scale has flipped */
  --muted: #2e5a66;
  --dim: #37616d;
  --signal: #239fa9;           /* teal: HUD line work — fills/borders/marks ONLY, never text */
  --signal-deep: #0d626f;      /* teal dark enough to be text: links, active nav, focus */
  --mint: #4ae5ab;             /* In-Stock node; footer accent (text-safe on the dark band) */
  --mustard: #e1b808;          /* fills behind ink text: JP badge, ::selection */
  --link: #0d626f;
  --link-hover: #0a4e58;
  --line: #8fb6c9;             /* ornament only */
  --line-hi: #4a7684;          /* >=3:1 control borders */
  --btn: #f4649f;
  --btn-hi: #f782b3;
  --btn-lo: #ef5796;
  --on-btn: #0b2a33;
  --on-abyss: #d1ebfa;         /* footer primary text */
  --on-abyss-muted: #9cc4d4;   /* footer links */
  --on-abyss-dim: #7fa6b5;     /* footer fine print */
  --grid: rgba(11, 42, 51, 0.06);
  --tick: rgba(11, 42, 51, 0.45);   /* corner brackets: ornament only, carries no state */
  /* Corner registration brackets: eight background layers on a pseudo-element
     above the viewport. Pure decoration. */
  --ticks:
    linear-gradient(var(--tick), var(--tick)) 0 0/16px 2px,
    linear-gradient(var(--tick), var(--tick)) 0 0/2px 16px,
    linear-gradient(var(--tick), var(--tick)) 100% 0/16px 2px,
    linear-gradient(var(--tick), var(--tick)) 100% 0/2px 16px,
    linear-gradient(var(--tick), var(--tick)) 0 100%/16px 2px,
    linear-gradient(var(--tick), var(--tick)) 0 100%/2px 16px,
    linear-gradient(var(--tick), var(--tick)) 100% 100%/16px 2px,
    linear-gradient(var(--tick), var(--tick)) 100% 100%/2px 16px;
  /* Same brackets, inset 14px, for the hero frame corners. */
  --ticks-hero:
    linear-gradient(var(--tick), var(--tick)) left 14px top 14px/22px 2px,
    linear-gradient(var(--tick), var(--tick)) left 14px top 14px/2px 22px,
    linear-gradient(var(--tick), var(--tick)) right 14px top 14px/22px 2px,
    linear-gradient(var(--tick), var(--tick)) right 14px top 14px/2px 22px,
    linear-gradient(var(--tick), var(--tick)) left 14px bottom 14px/22px 2px,
    linear-gradient(var(--tick), var(--tick)) left 14px bottom 14px/2px 22px,
    linear-gradient(var(--tick), var(--tick)) right 14px bottom 14px/22px 2px,
    linear-gradient(var(--tick), var(--tick)) right 14px bottom 14px/2px 22px;
  --page: 1200px;
  --radius: 6px;
  /* Chamfered modules via asymmetric radii: outlines and overflow clipping
     stay intact — clip-path would clip focus rings, so it is used only on
     non-interactive elements (badges, the hero silhouette). */
  --facet: 4px 14px 4px 14px;
  --facet-s: 3px 10px 3px 10px;
  --facet-l: 6px 22px 6px 22px;
  --glow-card: 0 0 0 1px rgba(35, 159, 169, 0.4), 0 10px 30px rgba(11, 42, 51, 0.3),
    0 0 24px rgba(35, 159, 169, 0.15);
  --shadow-panel: 0 18px 44px rgba(11, 42, 51, 0.32);
  --font-display: "Orbitron", "Segoe UI", system-ui, sans-serif;
  --font-body: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  /* A light wash at the top settling onto the sky ground. It never drifts
     deeper than --bg, so every text token keeps its measured ratio to the
     bottom of the longest page. */
  background: linear-gradient(180deg, #eaf6fe 0, var(--bg) 420px);
  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: 0.02em;
  margin: 0;
}

h1 { font-size: clamp(1.7rem, 3.6vw, 2.4rem); }
h2 { font-size: clamp(1.3rem, 2.6vw, 1.75rem); }
h3 { font-size: 1.15rem; }

a { color: var(--link); }            /* 5.7:1 on --bg */
a:hover { color: var(--link-hover); } /* 7.6:1 */

img { max-width: 100%; display: block; }

::selection { background: var(--mustard); color: var(--ink); }   /* 7.9:1 */

[hidden] { display: none !important; }

.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 24px;
}

.mono {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--dim);              /* 5.5:1 on --bg */
}

/* A token that must never split across lines. Code-like fragments in product
   titles — set codes such as "(EB-02)", card numbers — are wrapped in
   <span class="nobr"> by the build; nowrap keeps the token whole and the
   text wraps around it. Measured: the longest token (~7 chars of Orbitron
   600) is ≈63px at card-title size and ≈137px at h1 size, so it fits the
   narrowest card body (159px at 320px) and the h1 measure (272px at 320px)
   with room to spare. Ordinary hyphenated words ("Super-Premium",
   "Ultra-Premium", "non-refundable") are NOT wrapped in .nobr and still
   break at the hyphen, as normal prose should. */
.nobr { white-space: nowrap; }

/* Category-page and About ledes set their colour and measure inline; this
   supplies the type so they are not body-default. */
.lede { font-size: 1.06rem; line-height: 1.6; margin: 16px 0 0; }

/* ---------- header ---------- */

.site-header {
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  /* Solid sky, deliberately not translucent: the deep-teal brand mark
     keeps >=4.5:1 over anything scrolling beneath. */
  background: #c3e1f5;
  z-index: 20;
}

/* The signal scanline across the top of every page. */
.site-header::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--signal), rgba(35, 159, 169, 0.3));
  pointer-events: none;
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 62px;
  flex-wrap: wrap;
}

.brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-decoration: none;
}

.brand span { color: var(--signal-deep); }   /* 5.2:1 on the header */

/* Phone tap target: a 44px line box makes the brand link >=44px tall with
   zero visible change. The header bar is 56-62px — taller than 44px — and
   .wrap already centres its items, so the glyph sits exactly where it did;
   only the clickable box grows, inside the existing bar. Scoped to the
   header so the footer brand is untouched. */
.site-header .brand { line-height: 44px; }

.header-end {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

/* Pure-CSS menu state for phones. Hidden on desktop; see the <=820px block. */
.nav-check, .nav-btn { display: none; }

.site-nav { display: flex; gap: 22px; flex-wrap: wrap; }

.site-nav a {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);            /* 5.6:1 on the header */
  text-decoration: none;
  padding: 6px 0;
  border-bottom: 2px solid transparent;
}

.site-nav a:hover { color: var(--ink); }

/* Active mark: deep-teal text + teal bar, the reference's "active node". */
.site-nav a[aria-current="page"] {
  color: var(--signal-deep);    /* 5.2:1 on the header */
  border-bottom-color: var(--signal);
}

/* ---------- hero / masthead ---------- */

.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(1000px 460px at 10% 0%, rgba(35, 159, 169, 0.1), rgba(35, 159, 169, 0) 62%),
    var(--ticks-hero),
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0/100% 40px,
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0/40px 100%,
    #bfe2f7;
  background-repeat: no-repeat;
}

/* The one ambient effect: a scan line crossing the masthead. Transform-only,
   faint, clipped by the hero, and stopped under reduced-motion. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(35, 159, 169, 0), rgba(35, 159, 169, 0.14), rgba(35, 159, 169, 0)) 0 0/100% 3px no-repeat;
  transform: translateY(-100%);
  animation: hero-scan 9s linear infinite;
}

@keyframes hero-scan { to { transform: translateY(100%); } }

/* Area-chart silhouette at the base: a teal ridge clipped to peaks.
   Without clip-path support it simply does not render. */
.hero::after {
  content: "";
  display: none;
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 118px;
  pointer-events: none;
  opacity: 0.45;
  background: linear-gradient(180deg, rgba(35, 159, 169, 0.15), rgba(35, 159, 169, 0) 82%);
}

@supports (clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)) {
  .hero::after {
    display: block;
    clip-path: polygon(0 100%, 0 58%, 6% 58%, 9% 34%, 13% 34%, 16% 64%, 22% 64%,
      26% 18%, 31% 18%, 35% 52%, 41% 52%, 45% 10%, 50% 10%, 54% 44%, 60% 44%,
      64% 28%, 70% 28%, 74% 60%, 80% 60%, 84% 36%, 90% 36%, 94% 54%, 100% 54%,
      100% 100%);
  }
}

.hero .wrap { position: relative; z-index: 1; padding-block: 64px 52px; }

/* Eyebrow as a label chip: thin outline, spaced uppercase, status node. */
.hero .mono {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--line-hi);
  border-radius: 3px;
  padding: 6px 12px;
  background: rgba(228, 242, 252, 0.6);
  color: var(--dim);                /* 5.6:1 on the chip */
}

.hero .mono::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 6px rgba(35, 159, 169, 0.8);
  flex: 0 0 auto;
}

/* Title in the glowing rectangular frame, straight from the reference. */
.hero h1 {
  display: inline-block;
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: 0.02em;
  max-width: 15ch;
  margin-top: 22px;
  padding: 20px 24px;
  border: 1px solid rgba(35, 159, 169, 0.6);
  background: rgba(228, 242, 252, 0.5);
  box-shadow: 0 0 24px rgba(35, 159, 169, 0.16), inset 0 0 24px rgba(35, 159, 169, 0.05);
}

.hero p.lede {
  color: var(--muted);          /* 5.6:1 on the hero ground */
  max-width: 58ch;
  margin: 20px 0 0;
  font-size: 1.06rem;
  line-height: 1.6;
}

/* ---------- catalogue tiles (homepage index) ---------- */

.cats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
  margin: 30px auto 0;
  padding: 0 24px 46px;
  max-width: var(--page);
}

.cat {
  position: relative;
  display: block;
  padding: 22px 22px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--facet);
  text-decoration: none;
  color: inherit;
  transition: transform 160ms ease-out, border-color 160ms ease-out,
    box-shadow 160ms ease-out;
}

.cat:hover, .cat:focus-visible {
  transform: translateY(-2px);
  border-color: var(--signal);
  box-shadow: var(--glow-card);
}

.cat:active { transform: translateY(0); box-shadow: none; }

.cat h3 { margin: 12px 0 8px; transition: color 140ms ease-out; }
.cat p { margin: 0 0 14px; color: var(--muted); font-size: 0.92rem; }

/* Index number as an outlined chip. */
.cat > .mono:first-child {
  display: inline-block;
  border: 1px solid var(--line-hi);
  border-radius: 3px;
  padding: 2px 8px;
  color: var(--dim);
}

/* "Browse" readout strip: ruled division, strong-ink label. */
.cat .mono:last-child {
  display: block;
  border-top: 1px solid var(--line);
  padding-top: 10px;
  color: var(--ink-2);
}

@media (hover: hover) {
  .cat:hover h3 { color: var(--signal-deep); }   /* 6.2:1 on the panel */
}

/* ---------- catalogue grid ---------- */

.section { padding-block: 56px; }

/* Category and About page titles get a ruled instrument header. */
.section > h1 {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.section > h1::before {
  content: "";
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 12px;
  background: var(--signal);
  transform: rotate(45deg);
  box-shadow: 0 0 8px rgba(35, 159, 169, 0.55);
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}

/* Diamond node before major section titles. Decorative only. */
.section-head h2::before,
.gameband-head h2::before,
.faq h2::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 12px;
  background: var(--signal);
  transform: rotate(45deg);
  box-shadow: 0 0 7px rgba(35, 159, 169, 0.5);
}

/* Tick scale stretched between the title and the count. Ornament only. */
.section-head::after, .gameband-head::after {
  content: "";
  flex: 1 1 48px;
  align-self: flex-end;
  height: 6px;
  margin: 0 2px 5px;
  background: repeating-linear-gradient(90deg, rgba(55, 97, 109, 0.4) 0 1px, transparent 1px 9px);
  border-bottom: 1px solid var(--line);
}

.gameband-head::after { border-bottom: 0; margin-bottom: 3px; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 26px;
}

/* ---------- product card ---------- */

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--facet);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  transition: transform 160ms ease-out, border-color 160ms ease-out,
    box-shadow 160ms ease-out;
}

.card:hover, .card:focus-visible {
  transform: translateY(-2px);
  border-color: var(--signal);
  box-shadow: var(--glow-card);
}

.card:active { transform: translateY(0); box-shadow: none; }

/* The viewport: transparent cut-outs float over a deeper sky well with a
   soft floor shadow under the product and a top light — the deeper mid-blue
   flatters dark packaging and white packaging alike. (.card-media--photo is
   intentionally neutral — cut-out is the default; .is-plate below is the
   white-sweep opt-out.) */
.card-media {
  position: relative;
  aspect-ratio: 1 / 1;
  background:
    radial-gradient(58% 42% at 50% 87%, rgba(11, 42, 51, 0.14), rgba(11, 42, 51, 0) 72%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 42%),
    linear-gradient(rgba(11, 42, 51, 0.05) 1px, transparent 1px) 0 0/100% 26px,
    linear-gradient(90deg, rgba(11, 42, 51, 0.05) 1px, transparent 1px) 0 0/26px 100%,
    var(--well);
}

.card-media img { width: 100%; height: 100%; object-fit: contain; }

/* Corner registration brackets, drawn ABOVE the plate. Ornament only. */
.card-media::before, .detail-media::before, .cat::before {
  content: "";
  position: absolute;
  z-index: 1;
  pointer-events: none;
  background: var(--ticks);
  background-repeat: no-repeat;
  opacity: 0.55;
  transition: opacity 160ms ease-out;
}

.card-media::before, .cat::before { inset: 8px; }
.detail-media::before { inset: 12px; }

.card:hover .card-media::before, .card:focus-visible .card-media::before,
.cat:hover::before, .cat:focus-visible::before { opacity: 1; }

/* Scan sweep on hover: user-triggered, transform-only, removed under
   reduced-motion. Sold-out units are dormant — no sweep. */
.card:not(.card--out) .card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(105deg, rgba(255, 255, 255, 0) 42%, rgba(255, 255, 255, 0.35) 50%, rgba(255, 255, 255, 0) 58%);
  transform: translateX(-102%);
}

@media (hover: hover) {
  .card:not(.card--out):hover .card-media::after,
  .card:not(.card--out):focus-visible .card-media::after {
    transform: translateX(102%);
    transition: transform 650ms ease-out;
  }
}

/* Sold out: the cut-out recedes and a deactivation hatch overlays the well.
   Decorative — the "Sold out" stamp carries the state. */
.card--out .card-media img {
  filter: grayscale(0.7);
  opacity: 0.5;
  transition: filter 160ms ease-out, opacity 160ms ease-out;
}

.card--out:hover .card-media img { filter: grayscale(0.45); opacity: 0.65; }

.card--out .card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: repeating-linear-gradient(45deg, rgba(11, 42, 51, 0.05) 0 1px, transparent 1px 10px);
}

/* The white-sweep opt-out: a lit specimen plate inside the frame. The
   brackets darken via --tick so they stay visible on white. */
.card-media.is-plate, .detail-media.is-plate {
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(11, 42, 51, 0.22), inset 0 0 30px rgba(35, 159, 169, 0.1);
  --tick: rgba(11, 42, 51, 0.6);
}

/* Placeholder for products with no photograph. Typographic, on grid. */
.ph {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  gap: 12px; padding: 22px; text-align: center;
  background:
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / 100% 32px,
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / 32px 100%,
    var(--well);
}

/* No bright reaches 4.5:1 on the well, so the tiny format label is ink. */
.ph-fmt {
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 500;
  color: var(--ink);            /* 10.4:1 on the well */
}

.ph-title {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1rem; line-height: 1.3; color: var(--ink-2);   /* 7.6:1 on the well */
  max-width: 16ch;
}

/* Language chips: EN a dark frosted tag, JP a filled mustard tag. The
   text is the signal; the fill only reinforces it. */
.badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 3px;   /* fallback shape when clip-path is unsupported */
}

@supports (clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)) {
  .badge {
    border-radius: 0;
    clip-path: polygon(6px 0, 100% 0, calc(100% - 6px) 100%, 0 100%);
  }
}

.badge--en {
  background: rgba(11, 42, 51, 0.88);
  border: 1px solid rgba(240, 248, 254, 0.45);
  color: var(--panel-hi);        /* >=9.8:1 over the well */
}
.badge--jp { background: var(--mustard); color: var(--ink); }  /* 7.9:1 */

/* Panel seam between the viewport and the readout body. */
.card-body {
  padding: 14px 16px 16px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}

.card-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.01em;
  line-height: 1.3;
  color: var(--ink);
}

.card-spec {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dim);            /* 6.0:1 on the panel */
}

/* Price/stock readout strip: ruled division above the instruments. */
.card-foot {
  margin-top: auto;
  border-top: 1px solid var(--line);
  padding-top: 9px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* Prices are ink readouts: mono, tabular — no bright on the palette is
   readable as a figure on these surfaces. */
.price {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.98rem;
  letter-spacing: 0.02em;
  color: var(--ink);             /* 13.2:1 on the panel */
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.stock {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

/* In-Stock marker: a glowing mint node with a thin ink ring so it reads on
   the pale panel. Graphic only (1.3:1); the word beside it carries the state. */
.stock::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--mint);
  box-shadow: 0 0 0 1px rgba(11, 42, 51, 0.35), 0 0 6px rgba(74, 229, 171, 0.9),
    0 0 2px rgba(74, 229, 171, 0.9);
  flex: 0 0 auto;
}

/* Sold out: the node is gone and the words become an outlined stamp. */
.stock--out {
  color: var(--muted);
  padding: 3px 8px;
  border: 1px solid var(--line-hi);
  border-radius: 2px 8px 2px 8px;
  align-self: flex-start;
}

.stock--out::before { display: none; }

/* Both stock states the same height, so the price above stays level across
   a grid row whether the neighbouring card is in stock or sold out. The
   Sold-out stamp is a 15px line + 3px padding + 1px border, top and bottom,
   = 23px; the plain In-Stock line is pinned to the same 23px (fixed
   line-height + min-height, content centred by the existing align-items).
   Scoped to the card footer — the detail page's price-row is untouched. */
.card-foot .stock {
  line-height: 15px;
  min-height: 23px;
}

/* Legacy quantity tint from the old build; kept harmlessly. Dark mustard,
   6.0:1 on the panel — the only mustard dark enough to be text. */
.stock--low { color: #6e5900; }

/* ---------- product detail ---------- */

.detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 44px;
  padding-block: 48px;
  align-items: start;
}

.gallery { display: block; }

/* The main viewport: positive border, chamfer, brackets, grid, floor shadow. */
.detail-media {
  position: relative;
  background:
    radial-gradient(60% 44% at 50% 88%, rgba(11, 42, 51, 0.16), rgba(11, 42, 51, 0) 72%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 40%),
    linear-gradient(rgba(11, 42, 51, 0.06) 1px, transparent 1px) 0 0/100% 34px,
    linear-gradient(90deg, rgba(11, 42, 51, 0.06) 1px, transparent 1px) 0 0/34px 100%,
    var(--well);
  border-radius: var(--facet-l);
  border: 1px solid var(--line-hi);
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

/* .detail-media--photo is neutral (cut-out default); .is-plate opts back to
   the white plate, styled with .card-media.is-plate above. */
.detail-media img { width: 100%; height: 100%; object-fit: contain; }
.detail-media .ph-title { font-size: 1.3rem; max-width: 20ch; }

/* ---------- gallery ----------

   No-JS fallback is unchanged: thumbnails are plain links that open the
   photograph; gallery.js upgrades them to in-place swapping. */
.thumbs {
  display: flex; gap: 10px; flex-wrap: wrap;
  margin-top: 10px;
}

.thumb {
  width: 72px; height: 72px;
  border-radius: var(--facet-s);
  overflow: hidden;
  border: 1px solid var(--line-hi);
  background: var(--well);
  flex: 0 0 auto;
  opacity: 0.55;
  transition: opacity 140ms, border-color 140ms, box-shadow 140ms;
}

.thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }

.thumb.is-plate { background: #fff; }

/* Selected thumbnail: teal rim plus full opacity — two channels. */
.thumb.is-on {
  opacity: 1;
  border-color: var(--signal);
  box-shadow: 0 0 0 1px var(--signal), 0 0 10px rgba(35, 159, 169, 0.35);
}

@media (hover: hover) {
  .thumb:hover { opacity: 1; }
}

/* The focused thumb comes fully opaque so the ring stays >=3:1. */
.thumb:focus-visible {
  outline: 2px solid var(--signal-deep);
  outline-offset: 2px;
  opacity: 1;
}

/* Spec list as a readout panel: one hairline per row, indexed labels. */
.detail dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0 22px;
  margin: 24px 0;
  padding: 4px 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--facet-s);
}

.detail dl dt, .detail dl dd {
  padding: 9px 0;
  border-top: 1px solid var(--line);
}

.detail dl dt:first-of-type, .detail dl dd:first-of-type { border-top: 0; }

.detail dt {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dim);            /* 6.0:1 on the panel */
}

.detail dt::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 9px;
  background: var(--signal);
  transform: rotate(45deg);
}

.detail dd { margin: 0; color: var(--ink); }

.detail ul { padding-left: 18px; color: var(--ink); }
.detail ul li { margin-bottom: 5px; }

.price-row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin: 6px 0 0;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

/* The dominant readout on the page. IBM Plex Mono 500 — never Orbitron:
   Orbitron's zero is slashed, and a buyer must not misread the figure.
   Ink, 12.2:1 on --bg, and at 2.4rem it is large text besides. */
.price-lg {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 2.4rem;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  white-space: nowrap;
}

/* Case and box priced at once: both figures named, hairline between rows. */
.price-stack { display: flex; flex-direction: column; gap: 8px; }
.price-stack .price-unit + .price-unit {
  border-top: 1px solid var(--line);
  padding-top: 8px;
}
.price-unit { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.price-stack .price-unit .price-lg { font-size: 1.5rem; white-space: normal; }

.per, .price-from {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
}

.price-from { margin-right: 2px; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0 0; }
.chip {
  border: 1px solid var(--line-hi);
  border-radius: 3px;
  padding: 5px 11px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
}

/* Primary action: the pink console key. Ink label 5.15:1 on the fill. */
.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  background: var(--btn);
  color: var(--on-btn);
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.88rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 13px 22px;
  border: 1px solid transparent;
  vertical-align: middle;
  border-radius: var(--facet-s);
  min-height: 48px;
  line-height: 22px;
  margin-top: 22px;
  box-shadow: 0 0 18px rgba(244, 100, 159, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.4);
  transition: background 140ms ease-out, border-color 140ms ease-out,
    color 140ms ease-out, transform 140ms ease-out, box-shadow 140ms ease-out;
}

.ico { flex: 0 0 auto; display: block; overflow: visible; }

/* Scan sweep, user-triggered only: a light sheen across the pink fill. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, rgba(255, 255, 255, 0) 42%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 58%);
  transform: translateX(-102%);
}

@media (hover: hover) {
  .btn:hover::after, .btn:focus-visible::after {
    transform: translateX(102%);
    transition: transform 550ms ease-out;
  }
}

.btn:hover { background: var(--btn-hi); transform: translateY(-1px); }  /* ink label 6.3:1 */
.btn:active { background: var(--btn-lo); transform: translateY(0); }    /* 4.7:1 */

/* Focus ring clears the saturated fill: offset puts it on the page, with a
   ground-coloured gap ring so it never touches teal-on-pink. */
.btn:focus-visible {
  outline: 2px solid var(--signal-deep);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px var(--bg), 0 0 18px rgba(244, 100, 159, 0.35);
}

.btn--ghost {
  background: transparent;
  border-color: var(--line-hi);    /* 4.0:1 control border */
  color: var(--ink);               /* 12.2:1 */
  box-shadow: none;
}

.btn--ghost:hover {
  background: rgba(35, 159, 169, 0.08);
  border-color: var(--signal);
  color: var(--signal-deep);       /* 5.4:1 on the tint */
}
.btn--ghost:active { background: rgba(35, 159, 169, 0.14); }

/* The button group owns the vertical spacing, not the buttons: wrapped
   buttons then sit exactly `gap` apart instead of gap + margin. Standalone
   .btn keeps its own 22px margin-top. */
.ctas { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.ctas .btn { flex: 0 1 auto; margin-top: 0; }

.footer-contact { display: flex; flex-wrap: wrap; gap: 8px 18px; }

.notice {
  border-left: 2px solid var(--signal);
  padding: 10px 0 10px 14px;
  color: var(--muted);
  font-size: 0.9rem;
  margin: 20px 0 0;
}

.price-note {
  font-style: italic;
  color: var(--dim);              /* 5.5:1 on --bg */
  font-size: 0.9rem;
  margin: 18px 0 0;
  max-width: 46ch;
}

/* ---------- footer ---------- */

.site-footer {
  position: relative;
  border-top: 1px solid var(--line);
  background:
    linear-gradient(rgba(209, 235, 250, 0.05) 1px, transparent 1px) 0 0 / 100% 40px,
    linear-gradient(90deg, rgba(209, 235, 250, 0.05) 1px, transparent 1px) 0 0 / 40px 100%,
    var(--abyss);
  color: var(--on-abyss);              /* 12.2:1 on --abyss */
  padding-block: 38px 44px;
  font-size: 0.85rem;
}

/* Mirrors the header scanline, closing the page — in mint, the footer's
   accent, the one bright that is also text on the dark band. */
.site-footer::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, rgba(74, 229, 171, 0.4), var(--mint));
  pointer-events: none;
}

.site-footer .wrap { display: flex; gap: 22px; justify-content: space-between; flex-wrap: wrap; }

.site-footer .brand { color: var(--on-abyss); }
.site-footer .brand span, .site-footer .brand span:hover { color: var(--mint); }  /* 9.4:1 */

/* outline-color here wins over the global :focus-visible rule by specificity,
   so the focus ring stays >=3:1 on the dark band without a new rule. */
.site-footer a { color: var(--on-abyss-muted); outline-color: var(--mint); }  /* 8.1:1 */
.site-footer a:hover { color: var(--mint); }   /* 9.4:1 */

.contact-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.contact-link .ico { color: var(--mint); }

.disclaimer { max-width: 62ch; margin-top: 18px; font-size: 0.78rem; line-height: 1.5; color: var(--on-abyss-dim); }  /* 5.8:1 */

/* ---------- homepage rails ----------

   Mechanics unchanged: the row scrolls with CSS scroll-snap alone; the
   script only adds arrows and auto-advance on top. */
.rail-section + .rail-section { margin-top: 46px; }

.rail-section .section-head { margin-bottom: 18px; }

.rail-more {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-2);            /* 9.0:1 on --bg */
  white-space: nowrap;
  /* 44px tap target that leaves the heading row untouched: padding grows the
     clickable (border) box to ~46px, the matching negative margins pull the
     layout box back to its original size — row height and the baseline
     alignment with the h2 do not move. The overhang lands in the head's own
     margins, never on a neighbouring control. */
  padding-block: 14px;
  margin-block: -14px;
}

.rail-more:hover { color: var(--signal-deep); text-decoration: underline; }

.rail { position: relative; }

.rail-track {
  display: flex;
  gap: 26px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-left: 2px;
  padding: 4px 2px 12px;
  margin: -4px -2px -12px;
  scrollbar-width: thin;
  scrollbar-color: var(--line-hi) transparent;
  overscroll-behavior-x: contain;
}

.rail-track::-webkit-scrollbar { height: 8px; }
.rail-track::-webkit-scrollbar-track { background: transparent; }
.rail-track::-webkit-scrollbar-thumb {
  background: var(--line-hi);
  border-radius: 4px;
}

/* Edge fade — pure decoration; if mask-image is unsupported the rail simply
   renders without it. */
@supports (mask-image: linear-gradient(to right, black, black)) {
  .rail-track {
    mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 calc(100% - 28px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 28px, #000 calc(100% - 28px), transparent 100%);
  }
}

.rail-track > .card {
  flex: 0 0 clamp(160px, 40vw, 280px);
  scroll-snap-align: start;
}

.rail-nav {
  position: absolute;
  top: calc(50% - 40px);
  transform: translateY(-50%);
  z-index: 2;
  width: 44px;
  height: 44px;
  border-radius: var(--facet-s);
  border: 1px solid var(--line-hi);
  background: var(--panel);
  color: var(--ink);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  box-shadow: var(--shadow-panel);
  transition: opacity 220ms ease-out, background 140ms ease-out, border-color 140ms ease-out,
    color 140ms ease-out;
}

.rail:hover .rail-nav,
.rail-nav:focus-visible { opacity: 1; }

.rail-nav:hover { border-color: var(--signal); color: var(--signal-deep); }
.rail-nav:active { background: var(--panel-hi); }
.rail-nav:disabled { opacity: 0 !important; pointer-events: none; }
.rail-nav--prev { left: -6px; }
.rail-nav--next { right: -6px; }

@media (hover: none) {
  .rail-nav { display: none; }
}

@media (max-width: 560px) {
  .rail-track { gap: 12px; }
  .rail-section + .rail-section { margin-top: 34px; }
}

/* ---------- set blocks ---------- */

.setblock { margin: 0; padding-top: 48px; scroll-margin-top: 80px; }
.setblock:first-of-type { padding-top: 8px; }

.setblock > summary {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  padding-bottom: 12px;
  margin-bottom: 22px;
  cursor: pointer;
  list-style: none;
  min-height: 44px;
  transition: border-color 140ms ease-out;
}

.setblock > summary::-webkit-details-marker { display: none; }

@media (hover: hover) {
  .setblock > summary:hover { border-bottom-color: var(--line-hi); }
  .setblock > summary:hover h3 { color: var(--signal-deep); }
}

/* An open set block switches its rule to the signal channel; the plus marker
   rotates to a cross beside it, so the state never rides on the rim alone. */
.setblock[open] > summary { border-bottom-color: var(--signal); }

.setblock > summary h3 { transition: color 140ms ease-out; }
.setblock > summary > .mono { margin-left: auto; color: var(--dim); }

/* Plus marker that rotates to a cross when the channel opens. The rotation
   and the border carry the state together. */
.setblock > summary::after {
  content: "";
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  background:
    linear-gradient(var(--signal), var(--signal)) center/12px 2px no-repeat,
    linear-gradient(var(--signal), var(--signal)) center/2px 12px no-repeat;
  transition: transform 180ms ease-out;
}

.setblock[open] > summary::after { transform: rotate(45deg); }

.setblock:not([open]) > summary { margin-bottom: 0; }
.setblock:not([open]) { padding-top: 26px; }

/* The set name and its code chip lay out as one wrapping row. A chip that
   does not fit beside the name drops whole to the next line, flush left
   under the name, with a tidy gap — it never splits at its hyphen. (The
   chip's bordered box is ~4px taller than the name's line box, so a summary
   line carrying both gains up to ~4px of height at every width — flagged
   for review, visually negligible.) */
.setblock > summary h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 10px;
}

/* Set codes render as data tags. One label, never broken internally. */
.setblock h3 .mono {
  margin-left: 0;
  margin-right: 0;
  white-space: nowrap;
  color: var(--ink-2);
  background: var(--panel);
  border: 1px solid var(--line-hi);
  border-radius: 3px;
  padding: 2px 7px;
}

.setblock .grid { row-gap: 20px; }

/* ---------- FAQ (native <details>, no JS) ---------- */

.faq { margin-top: 64px; }
.faq h2 { margin-bottom: 22px; }

.faq-list {
  border-top: 1px solid var(--line);
  max-width: 78ch;
}

.faq-item { border-bottom: 1px solid var(--line); }

.faq-item summary {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 0;
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: 0.01em;
  line-height: 1.4;
  list-style: none;
  transition: color 140ms ease-out;
}

.faq-item summary::-webkit-details-marker { display: none; }

@media (hover: hover) {
  .faq-item summary:hover { color: var(--signal-deep); }
}

.faq-item[open] summary { color: var(--signal-deep); }   /* 5.7:1 on --bg */

.faq-item summary::after {
  content: "";
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  margin-left: auto;
  margin-top: 4px;
  background:
    linear-gradient(var(--signal), var(--signal)) center/12px 2px no-repeat,
    linear-gradient(var(--signal), var(--signal)) center/2px 12px no-repeat;
  transition: transform 180ms ease-out;
}

.faq-item[open] summary::after { transform: rotate(45deg); }

.faq-answer {
  padding: 0 34px 20px 0;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.6;
}

.faq-answer p { margin: 0; }

/* ---------- game bands ---------- */

.gameband { padding-top: 18px; scroll-margin-top: 80px; }
.gameband + .gameband { padding-top: 56px; }

.gameband-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-hi);
}

.gameband-head h2 { font-size: clamp(1.35rem, 2.8vw, 1.85rem); font-weight: 700; }

.gameband-head .mono { color: var(--dim); }

.gameband .setblock:first-of-type { padding-top: 30px; }
.gameband .setblock h3 { font-family: var(--font-display); font-size: 1.15rem; margin: 0; }

/* ---------- search ---------- */

.search { position: relative; margin: 0; }

.search input {
  width: 210px;
  max-width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: var(--facet-s);
  border: 1px solid var(--line-hi);
  background: var(--panel);
  color: var(--ink);
  caret-color: var(--signal-deep);
  font: inherit;
  font-size: 0.88rem;
  -webkit-appearance: none;
  appearance: none;
}

.search input::placeholder { color: var(--dim); }   /* 6.0:1 on the field */

.search input:focus {
  border-color: var(--signal-deep);
  outline: none;
  box-shadow: 0 0 0 3px rgba(35, 159, 169, 0.22);
}

/* The panel ships with the `hidden` attribute set in markup; the script
   removes it once there is something to show. */
.search-panel[hidden] { display: none; }

.search-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(380px, calc(100vw - 48px));
  /* 3px scanline stripe pinned to the panel top. */
  background:
    linear-gradient(90deg, var(--signal), rgba(35, 159, 169, 0.35)) top / 100% 3px no-repeat,
    var(--panel);
  border: 1px solid var(--line-hi);
  border-radius: var(--facet);
  box-shadow: var(--shadow-panel);
  max-height: min(420px, 70vh);
  overflow-y: auto;
  z-index: 30;
}

.search-results { list-style: none; margin: 0; padding: 8px 6px 6px; }

.search-results a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: 6px;
  text-decoration: none;
  color: var(--ink);
}

.search-results a:hover,
.search-results [aria-selected="true"] a {
  background: rgba(35, 159, 169, 0.1);
  color: var(--ink);
  box-shadow: inset 2px 0 0 var(--signal);
}

.search-thumb {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--well);
  border: 1px solid var(--line);
}

.search-thumb img { width: 100%; height: 100%; object-fit: contain; }
.search-thumb-blank { display: block; width: 100%; height: 100%; background: var(--panel-hi); }

.search-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }

.search-title {
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-meta {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-price {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);              /* 13.2:1 on the panel */
}

.search-empty { padding: 14px 12px; color: var(--muted); font-size: 0.88rem; }

/* ---------- responsive: <=820px — phones and small tablets ----------

   The phone layout is designed, not squeezed: the sticky header is one 56px
   bar (brand + a pure-CSS menu button); navigation and the script-revealed
   search field fold into a drop-down panel driven by .nav-check. With
   JavaScript off the panel shows the four nav destinations and nothing dead.
   The breakpoint sits at 820px, not 760px: between 761 and ~800px the desktop
   header wraps to a cramped two-row bar, so the collapsed header covers that
   band; from 821px up the desktop header fits on one line. */

@media (max-width: 820px) {
  .detail { grid-template-columns: 1fr; gap: 28px; padding-block: 32px; }
  .section { padding-block: 40px; }
  .setblock, .gameband { scroll-margin-top: 68px; }

  .site-header .wrap { min-height: 56px; padding-block: 6px; flex-wrap: nowrap; gap: 14px; }
  .brand { font-size: 1.05rem; }

  /* Visually hidden but focusable: keyboard users toggle it with space and
     see the ring on the label. clip-path hides it visually; the indicator
     survives on .nav-btn via the sibling rule below. */
  .nav-check {
    display: block;
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    overflow: hidden;
  }

  .nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    height: 44px;
    padding: 0 14px;
    border: 1px solid var(--line-hi);
    border-radius: var(--facet-s);
    background: var(--panel);
    color: var(--ink);
    cursor: pointer;
    flex: 0 0 auto;
  }

  .nav-btn .mono { color: var(--dim); font-size: 0.7rem; }

  .nav-btn-bars {
    width: 16px; height: 12px;
    background: linear-gradient(currentColor, currentColor) center/100% 2px no-repeat;
    position: relative;
    color: var(--ink-2);
  }

  .nav-btn-bars::before, .nav-btn-bars::after {
    content: "";
    position: absolute;
    left: 0; right: 0;
    height: 2px;
    background: currentColor;
    transition: transform 180ms ease-out;
  }

  .nav-btn-bars::before { top: 0; }
  .nav-btn-bars::after { bottom: 0; }

  .nav-btn:hover { border-color: var(--signal); }

  .nav-check:focus-visible ~ .nav-btn {
    outline: 2px solid var(--signal-deep);
    outline-offset: 2px;
  }

  /* Open state: the bars become a cross and the chip goes active. */
  .nav-check:checked ~ .nav-btn { border-color: var(--signal); }
  .nav-check:checked ~ .nav-btn .mono { color: var(--signal-deep); }
  .nav-check:checked ~ .nav-btn .nav-btn-bars { background: none; color: var(--signal-deep); }
  .nav-check:checked ~ .nav-btn .nav-btn-bars::before { transform: translateY(5px) rotate(45deg); }
  .nav-check:checked ~ .nav-btn .nav-btn-bars::after { transform: translateY(-5px) rotate(-45deg); }

  /* The drop-down console: search first (when the script reveals it), then
     the four destinations as full-width rows. A step lighter than the header
     so deep-teal active text keeps >=4.5:1 on it. */
  .header-end {
    position: absolute;
    top: 100%; left: 0; right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: #c9e5f7;
    border-bottom: 1px solid var(--line);
    padding: 12px 24px 16px;
    box-shadow: var(--shadow-panel);
  }

  .nav-check:checked ~ .header-end { display: flex; }

  .search { order: -1; width: 100%; margin: 0 0 8px; }
  .search input { width: 100%; min-height: 46px; }
  .search-panel { right: auto; left: 0; width: 100%; top: calc(100% + 6px); }

  .site-nav { flex-direction: column; gap: 0; width: 100%; }

  .site-nav a {
    display: flex;
    align-items: center;
    min-height: 48px;
    padding: 0 2px 0 10px;
    font-size: 0.78rem;
    border-bottom: 1px solid rgba(74, 118, 132, 0.5);
  }

  .site-nav a:last-child { border-bottom: 0; }

  /* Current page: deep-teal text plus an inset bar — two channels. */
  .site-nav a[aria-current="page"] {
    border-bottom-color: rgba(74, 118, 132, 0.5);
    box-shadow: inset 2px 0 0 var(--signal);
  }

  /* Phone hero: the frame and brackets stay, tightened. */
  .hero .wrap { padding-block: 44px 38px; }
  .hero h1 {
    font-size: clamp(1.55rem, 7.4vw, 2.1rem);
    max-width: 17ch;
    margin-top: 18px;
    padding: 14px 16px;
  }
  .hero .mono { font-size: 0.62rem; padding: 5px 10px; }
  .hero p.lede { font-size: 0.98rem; margin-top: 16px; }
  .hero::after { height: 72px; }

  .price-lg { font-size: 2rem; }
  .ctas .btn { flex: 1 1 100%; }
}

/* ---------- responsive: <=560px — small phones ---------- */

@media (max-width: 560px) {
  /* Set-block summary: marker pinned right across two rows; title above,
     count below. */
  .setblock > summary {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "title marker"
      "meta  marker";
    align-items: center;
    column-gap: 14px;
    row-gap: 4px;
  }

  .setblock > summary h3 { grid-area: title; }
  .setblock > summary > .mono { grid-area: meta; margin-left: 0; }
  .setblock > summary::after { grid-area: marker; align-self: center; }

  /* Category grid: 2-up from 360px (the 320-359px row layout is below). */
  .grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
  }

  .setblock .grid { row-gap: 12px; }

  .card-body { padding: 10px 10px 12px; gap: 5px; }
  .card-title { font-size: 0.82rem; line-height: 1.25; }
  .card-spec { font-size: 0.6rem; letter-spacing: 0.05em; }
  .card-foot { gap: 2px; padding-top: 6px; }
  .price { font-size: 0.92rem; }
  .stock { font-size: 0.6rem; gap: 5px; }
  .stock--out { padding: 2px 6px; }

  .badge { font-size: 0.55rem; padding: 3px 7px; top: 6px; left: 6px; }

  .ph { padding: 12px; gap: 8px; }
  .ph-fmt { font-size: 0.55rem; letter-spacing: 0.1em; }
  .ph-title { font-size: 0.8rem; max-width: 14ch; }

  .thumb { width: 56px; height: 56px; }
  .thumbs { gap: 8px; }

  .rail-track > .card { flex-basis: clamp(150px, 42vw, 240px); }

  .cats { grid-template-columns: 1fr; gap: 12px; padding-bottom: 36px; }
  .cat { padding: 18px 18px 16px; }

  .section-head::after, .gameband-head::after { flex-basis: 24px; }

  .footer-contact { flex-direction: column; align-items: flex-start; gap: 4px; }
}

/* ---------- responsive: 320-359px — the narrowest phones ----------

   Below the 2-up threshold the card becomes a horizontal scan-row: viewport
   left, readout right, so the catalogue stays dense instead of stacking
   full-width portraits. */

@media (max-width: 359px) {
  .grid { grid-template-columns: 1fr; }

  /* The horizontal scan-row is a category-GRID layout only — never the
     homepage rails. A rail card is ~150px wide, so a 92px viewport plus its
     body cannot sit side by side; rail cards keep the normal vertical
     layout at every width. */
  .grid > .card { flex-direction: row; align-items: stretch; }

  .grid > .card .card-media {
    flex: 0 0 92px;
    width: 92px;
    aspect-ratio: auto;
    align-self: stretch;
  }

  .grid > .card .card-body { border-top: 0; border-left: 1px solid var(--line); padding: 8px 10px; }
  .grid > .card .card-title { font-size: 0.8rem; }
  .grid > .card .badge { font-size: 0.5rem; padding: 2px 6px; top: 4px; left: 4px; }
}

/* Deep teal: 5.7:1 on --bg, 6.2:1 on --panel, 5.2:1 on the header. On the
   dark footer the links set their own outline-color (see .site-footer a). */
:focus-visible { outline: 2px solid var(--signal-deep); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  /* Kill the ambient scan line and every sweep layer; the sold-out hatch
     stays (it does not move). */
  .hero::before { animation: none; }
  .card:not(.card--out) .card-media::after, .btn::after { display: none; }
  .card, .cat, .rail-nav, .thumb, .btn,
  .card--out .card-media img,
  .card-media::before, .detail-media::before, .cat::before,
  .setblock > summary, .setblock > summary h3, .setblock > summary::after,
  .faq-item summary, .faq-item summary::after,
  .nav-btn-bars::before, .nav-btn-bars::after { transition: none; }
}
