/* Counterhoop storefront template — presentation layer.
   Design tokens are material-derived: nickel/chrome greys (the hardware), brass (the lugs and
   tension rods), calf-skin warm white (the heads). One accent only. Light + dark are peers.
   No external fonts, no external CSS, no build step. */

:root {
  color-scheme: light dark;

  /* ink + ground */
  --paper:        #f7f7f5;
  --paper-raised: #ffffff;
  --paper-sunken: #eeeeec;
  --ink:          #1b1d1e;
  --ink-muted:    #62676b;
  --ink-faint:    #8b9096;
  --rule:         #dcdedb;
  --rule-strong:  #c3c6c2;

  /* the one accent: brass */
  --brass:        #806320;
  --brass-weak:   #f0e7d0;
  --brass-line:   #c9a851;

  /* state */
  --struck:       #8b9096;
  --focus:        #1b6ac9;

  /* type */
  --stamp: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
  --text:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* scale */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;
  --rail: 264px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:        #131516;
    --paper-raised: #1b1e1f;
    --paper-sunken: #0d0f10;
    --ink:          #e9e9e6;
    --ink-muted:    #9ba1a6;
    --ink-faint:    #6f757a;
    --rule:         #2a2d2f;
    --rule-strong:  #3c4043;
    --brass:        #cfa54a;
    --brass-weak:   #2a2415;
    --brass-line:   #7d642a;
    --struck:       #6f757a;
    --focus:        #6fb3ff;
  }
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: 15px;
  line-height: 1.5;
}

a { color: inherit; }

:where(a, button, input, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip {
  position: absolute; left: var(--s3); top: -100px; z-index: 50;
  background: var(--paper-raised); color: var(--ink);
  border: 1px solid var(--rule-strong);
  padding: var(--s3) var(--s4);
  transition: top .12s;
}
.skip:focus { top: var(--s3); }

/* ── masthead ───────────────────────────────────────────────────────────── */

.masthead {
  border-bottom: 1px solid var(--rule);
  background: var(--paper-raised);
  position: sticky; top: 0; z-index: 20;
}

.masthead-inner {
  display: flex; align-items: center; gap: var(--s5);
  padding: var(--s3) var(--s5);
  max-width: 1600px; margin: 0 auto;
  flex-wrap: wrap;
}

.wordmark {
  font-family: var(--stamp);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark .rule {
  display: block;
  font-size: 9px; font-weight: 400; letter-spacing: .18em;
  color: var(--ink-faint);
  margin-top: 2px;
}

/* corpus switch — the two halves of the register */
.corpus {
  display: flex; border: 1px solid var(--rule-strong); border-radius: 2px; overflow: hidden;
}
.corpus a {
  font-family: var(--stamp); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  padding: 10px var(--s4); text-decoration: none; color: var(--ink-muted);
  background: var(--paper); white-space: nowrap;
  min-height: 44px; display: flex; align-items: center; gap: 6px;
}
.corpus a + a { border-left: 1px solid var(--rule-strong); }
.corpus a[aria-current="page"] { background: var(--ink); color: var(--paper); }
.corpus a .n { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.corpus a[aria-current="page"] .n { color: var(--brass-line); }

.search {
  flex: 1 1 260px; min-width: 200px;
  display: flex; align-items: center; gap: var(--s2);
  border: 1px solid var(--rule-strong); border-radius: 2px;
  background: var(--paper);
  padding: 0 var(--s3);
  min-height: 44px;
}
.search:focus-within { border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }
.search input {
  flex: 1; border: 0; background: none; color: inherit; font: inherit;
  padding: 10px 0; min-width: 0;
}
.search input:focus { outline: none; }
.search svg { flex: none; color: var(--ink-faint); }
.search kbd {
  font-family: var(--stamp); font-size: 10px; color: var(--ink-faint);
  border: 1px solid var(--rule); border-radius: 2px; padding: 2px 5px;
}

/* ── layout ─────────────────────────────────────────────────────────────── */

.shell {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  gap: var(--s6);
  max-width: 1600px;
  margin: 0 auto;
  padding: var(--s5);
  align-items: start;
}

/* ── the census bar: the catalog's real shape, in one glance ─────────────── */

.census { margin-bottom: var(--s5); }
.census h2 {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
  margin: 0 0 var(--s2);
}
.census-bar {
  display: flex; width: 100%; height: 34px;
  border: 1px solid var(--rule-strong); border-radius: 2px; overflow: hidden;
  background: var(--paper-sunken);
}
/* Bands are shaded by share, not painted a flat colour: the point of the bar is that you SEE
   half the catalog is one category. --w is set per band from its proportion of the corpus. */
.census-bar button {
  border: 0; padding: 0; margin: 0; cursor: pointer;
  background: color-mix(in srgb, var(--brass) calc(var(--w, .5) * 100%), var(--paper-sunken));
  border-right: 1px solid var(--paper-raised);
  position: relative;
  min-width: 2px;
  transition: filter .12s;
}
.census-bar button:last-child { border-right: 0; }
.census-bar button:hover,
.census-bar button:focus-visible { filter: brightness(1.25); }
.census-bar button[aria-pressed="true"] {
  background: var(--ink);
  box-shadow: inset 0 0 0 2px var(--brass-line);
}
.census-legend {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4);
  margin-top: var(--s2);
  font-family: var(--stamp); font-size: 10.5px; color: var(--ink-muted);
}
.census-legend span { white-space: nowrap; }
.census-legend b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ── facet rail: the parts drawer ───────────────────────────────────────── */

.rail { position: sticky; top: 80px; max-height: calc(100vh - 96px); overflow-y: auto; padding-right: var(--s2); }
.rail-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: var(--s4);
}
.rail-head h2 {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
  margin: 0;
}
.clear {
  font-family: var(--stamp); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  background: none; border: 0; color: var(--brass); cursor: pointer; padding: 4px;
}
.clear[hidden] { display: none; }

fieldset.facet { border: 0; border-top: 1px solid var(--rule); margin: 0; padding: var(--s4) 0; }
fieldset.facet:first-of-type { border-top: 0; padding-top: 0; }
fieldset.facet legend {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-muted);
  padding: 0; margin-bottom: var(--s2);
}
.facet-list { max-height: 268px; overflow-y: auto; margin: 0 -4px; padding: 0 4px; }
.facet-list.tall { max-height: 340px; }

/* The facet options arrive after the data does. Reserve each group's height up front, or the rail
   grows on load and shoves the whole page down — which is exactly the layout shift we are
   criticising the live store for. Heights match the rendered option count (32px per row). */
#facet-folder, #facet-make { min-height: 340px; }
#facet-grade { min-height: 224px; }
#facet-price { min-height: 160px; }
#facet-prov  { min-height: 96px; }
#facet-avail { min-height: 64px; }
.census-legend { min-height: 17px; }

.opt {
  display: flex; align-items: center; gap: var(--s2);
  padding: 6px 4px; min-height: 32px;
  cursor: pointer; border-radius: 2px;
  font-size: 13px;
}
.opt:hover { background: var(--paper-sunken); }
.opt input { flex: none; accent-color: var(--brass); width: 15px; height: 15px; cursor: pointer; }
.opt .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opt .count {
  font-family: var(--stamp); font-size: 10.5px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; flex: none;
}
.opt input:disabled + .label { color: var(--ink-faint); }
.opt:has(input:disabled) { cursor: default; }
.opt:has(input:disabled):hover { background: none; }

/* ── results toolbar ────────────────────────────────────────────────────── */

.toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  flex-wrap: wrap;
  margin-bottom: var(--s4);
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--rule);
}
.count-line { font-family: var(--stamp); font-size: 12px; color: var(--ink-muted); }
.count-line b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--stamp); font-size: 10.5px; letter-spacing: .04em;
  background: var(--brass-weak); color: var(--brass);
  border: 1px solid var(--brass-line); border-radius: 2px;
  padding: 5px 6px 5px 8px; cursor: pointer;
  min-height: 28px;
}
.chip:hover { background: var(--brass-line); color: var(--paper-raised); }
.chip .x { font-size: 13px; line-height: 1; }

.sort {
  font-family: var(--stamp); font-size: 11px;
  background: var(--paper-raised); color: var(--ink);
  border: 1px solid var(--rule-strong); border-radius: 2px;
  padding: 0 var(--s2); min-height: 36px;
}

/* ── the specimen grid ──────────────────────────────────────────────────── */

/* The scroller is windowed: `sizer` holds full scroll height, only visible rows are in the DOM.
   min-height reserves the grid's space BEFORE the data lands, so the footer is not sitting in the
   viewport at first paint waiting to be shoved down. That shove is cumulative layout shift. */
.grid-scroller { position: relative; min-height: 80vh; }
.grid-sizer { position: relative; width: 100%; }
.grid-window { position: absolute; top: 0; left: 0; right: 0; display: grid; gap: var(--s4); }

.card {
  display: flex; flex-direction: column;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 2px;
  text-decoration: none;
  overflow: hidden;
  transition: border-color .12s, transform .12s;
}
.card:hover { border-color: var(--rule-strong); }
.card:hover .thumb img { transform: scale(1.03); }

.thumb {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--paper-sunken);
  overflow: hidden;
  border-bottom: 1px solid var(--rule);
}
.thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .2s ease-out;
  /* The placeholder below is position:absolute and would otherwise paint OVER a photo that
     loaded fine — the img is in-flow and unpositioned, so it loses the paint order. Position
     the img so it sits ABOVE the placeholder, which is what the fallback was always meant to
     be: beneath. (Latent until now: the sample data carried no images, so nothing ever loaded
     on top of it.) onerror removes the img, revealing the placeholder again. */
  position: relative;
  z-index: 1;
}
/* Deterministic placeholder from the sku hue — used when the CDN image is absent or 404s.
   Not decoration: it keeps the grid stable and keeps each specimen visually distinguishable. */
.thumb .ph {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--stamp); font-size: 11px; letter-spacing: .1em;
  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.35);
}

/* the stamp: SKU + grade, struck into the corner of the specimen */
.stamp {
  position: absolute; left: 0; bottom: 0;
  display: flex; align-items: stretch;
  font-family: var(--stamp); font-size: 10px; letter-spacing: .06em;
  background: var(--paper-raised);
  border-top: 1px solid var(--rule); border-right: 1px solid var(--rule);
  border-top-right-radius: 2px;
}
.stamp .sku { padding: 3px 6px; color: var(--ink-muted); }
.stamp .grade {
  padding: 3px 6px; font-weight: 700; color: var(--brass);
  border-left: 1px solid var(--rule);
}

.card-body { padding: var(--s3); display: flex; flex-direction: column; gap: 5px; flex: 1; }
.make {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--brass);
}
.make.none { color: var(--ink-faint); }
/* Titles arrive as ALL-CAPS keyword-stuffed marketplace strings. We do not shout them back:
   they are set small, sentence-cased where the data allows, and clamped to two lines. The
   scannable identity is make + type + grade above, not the title. See DESIGN.md §Titles. */
.title {
  font-size: 13px; line-height: 1.35; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.leaf { font-size: 11.5px; color: var(--ink-faint); }
.card-foot {
  margin-top: auto; padding-top: var(--s2);
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2);
}
.price {
  font-family: var(--stamp); font-size: 14px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.avail {
  font-family: var(--stamp); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-faint);
}
.avail.out { color: var(--struck); }

/* "listed at" qualifier. The archive price is an ask, never a settlement — an unqualified number
   beside a Sold badge would claim a realized sale price the data cannot support. */
.price .qual {
  font-family: var(--text);
  font-size: 9.5px; font-weight: 400; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-faint);
}

/* ── archive treatment: the struck register ─────────────────────────────── */

.card.archived .thumb { filter: grayscale(1); opacity: .78; }
.card.archived .price { color: var(--struck); text-decoration: line-through; text-decoration-thickness: 1px; }
.card.archived .make { color: var(--ink-muted); }

/* provenance is the archive's whole point: how do we KNOW this is gone? */
.prov {
  font-family: var(--stamp); font-size: 9.5px; letter-spacing: .07em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 6px; border-radius: 2px; border: 1px solid var(--rule-strong);
  color: var(--ink-muted); background: var(--paper-sunken);
  white-space: nowrap;
}
.prov::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.prov.sold    { color: var(--brass); border-color: var(--brass-line); background: var(--brass-weak); }
.prov.ended   { color: var(--ink-muted); }
.prov.unknown { color: var(--ink-faint); border-style: dashed; }

.relink {
  font-family: var(--stamp); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--brass);
}

/* ── notices ────────────────────────────────────────────────────────────── */

.note {
  border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--brass);
  background: var(--paper-raised);
  padding: var(--s3) var(--s4);
  margin-bottom: var(--s5);
  font-size: 13px; color: var(--ink-muted);
  border-radius: 2px;
}
.note b { color: var(--ink); font-weight: 600; }
.note code { font-family: var(--stamp); font-size: 12px; }

.empty {
  padding: var(--s7) var(--s5); text-align: center;
  border: 1px dashed var(--rule-strong); border-radius: 2px;
  color: var(--ink-muted);
}
.empty h3 { margin: 0 0 var(--s2); font-size: 16px; color: var(--ink); }
.empty button {
  margin-top: var(--s4);
  font-family: var(--stamp); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  background: var(--ink); color: var(--paper); border: 0; border-radius: 2px;
  padding: 12px var(--s5); cursor: pointer; min-height: 44px;
}

.sentinel { height: 1px; }

.foot {
  border-top: 1px solid var(--rule);
  margin-top: var(--s7);
  padding: var(--s5);
  font-size: 12px; color: var(--ink-faint);
  text-align: center;
}

/* ── responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1024px) {
  .shell { grid-template-columns: 1fr; gap: var(--s5); }
  .rail {
    position: static; max-height: none; overflow: visible;
    border: 1px solid var(--rule); border-radius: 2px;
    padding: var(--s4); background: var(--paper-raised);
  }
  /* the drawer collapses on small screens rather than burying the grid */
  .rail[data-collapsed="true"] .rail-body { display: none; }
  .rail-toggle {
    display: flex; width: 100%; align-items: center; justify-content: space-between;
    font-family: var(--stamp); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
    background: none; border: 0; color: var(--ink); cursor: pointer;
    padding: var(--s2) 0; min-height: 44px;
  }
}
@media (min-width: 1025px) {
  .rail-toggle { display: none; }
}

@media (max-width: 600px) {
  .shell { padding: var(--s4); }
  .masthead-inner { padding: var(--s3) var(--s4); gap: var(--s3); }
  .wordmark { font-size: 13px; }
  .census-bar { height: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .card:hover .thumb img { transform: none; }
}

/* print: the register, as a register */
@media print {
  .masthead, .rail, .toolbar .sort, .census { display: none; }
  .shell { display: block; }
  .card { break-inside: avoid; border: 1px solid #999; }
}

/* ══════════════════════════════════════════════════════════════════════════
   counterhoop-v1 additions over the apps/storefront template:
   the NEW stamp, the listed-date line, and the item detail page.
   ══════════════════════════════════════════════════════════════════════════ */

/* NEW stamp — brass, top-right of the thumb. Earned from published_at within
   the 90-day window ending at the export's newest listing (a watermark, not
   wall-clock: the export is a snapshot, so "new" is relative to the snapshot). */
.stamp .new {
  padding: 3px 6px; font-weight: 700; letter-spacing: .1em;
  color: var(--paper-raised); background: var(--brass);
  border-left: 1px solid var(--rule);
}
.date-line {
  font-family: var(--stamp); font-size: 10px; letter-spacing: .05em;
  color: var(--ink-faint); font-variant-numeric: tabular-nums;
}

/* ── item detail page ──────────────────────────────────────────────────── */

.item-shell {
  max-width: 1100px; margin: 0 auto; padding: var(--s5);
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(280px, 5fr);
  gap: var(--s6); align-items: start;
}
@media (max-width: 900px) {
  .item-shell { grid-template-columns: 1fr; gap: var(--s5); }
}

.crumbs {
  font-family: var(--stamp); font-size: 10.5px; letter-spacing: .06em;
  color: var(--ink-faint); margin-bottom: var(--s3);
}
.crumbs a { color: var(--ink-muted); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }

/* The gallery is zero-JS on purpose: every photograph, stacked, scroll-snapped.
   Each frame is CSS-dimensioned (aspect-ratio box), so there is no layout shift
   by construction — the failure mode the old store paid 0.393 CLS for. */
.gallery {
  display: flex; flex-direction: column; gap: var(--s3);
  scroll-snap-type: y proximity;
}
.gallery figure {
  margin: 0; position: relative;
  aspect-ratio: 4 / 3; overflow: hidden;
  border: 1px solid var(--rule); border-radius: 2px;
  background: var(--paper-sunken);
  scroll-snap-align: start;
}
.gallery img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block;
}
.gallery figcaption {
  position: absolute; left: 0; bottom: 0;
  font-family: var(--stamp); font-size: 9.5px; letter-spacing: .08em;
  color: var(--ink-muted); background: var(--paper-raised);
  border-top: 1px solid var(--rule); border-right: 1px solid var(--rule);
  border-top-right-radius: 2px; padding: 3px 7px;
}

/* the buy box: the thing the old store buried under share buttons */
.buybox {
  border: 1px solid var(--rule-strong); border-radius: 2px;
  background: var(--paper-raised); padding: var(--s4);
  position: sticky; top: 96px;
}
.buybox .price { font-size: 22px; }
.buybox .price .qual { font-size: 11px; }
.buy-cta {
  display: flex; align-items: center; justify-content: center; gap: var(--s2);
  font-family: var(--stamp); font-size: 12px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  background: var(--ink); color: var(--paper);
  text-decoration: none; border-radius: 2px;
  padding: 14px var(--s4); margin: var(--s3) 0 var(--s2);
  min-height: 44px;
}
.buy-cta:hover { background: var(--brass); }
.buy-cta.archived { background: var(--paper-sunken); color: var(--ink-muted); border: 1px solid var(--rule-strong); }
.buy-note { font-size: 12px; color: var(--ink-faint); text-align: center; }
.buy-note a { color: var(--ink-muted); }

.specs { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: var(--s4); }
.specs caption {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
  text-align: left; padding-bottom: var(--s2);
}
.specs th, .specs td { text-align: left; padding: 7px 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
.specs th { font-weight: 400; color: var(--ink-faint); width: 38%; padding-right: var(--s3); }
.specs td { color: var(--ink); }

.desc { max-width: 72ch; }
.desc h2 {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
  margin: var(--s6) 0 var(--s2);
}
.desc p { margin: 0 0 var(--s3); }
.desc .plain { color: var(--ink-muted); font-style: italic; }

/* related strip reuses the grid card, wider cards */
.related { margin-top: var(--s7); }
.related h2 {
  font-family: var(--stamp); font-size: 10px; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
  margin: 0 0 var(--s3);
}
.related .rel-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: var(--s3);
}

/* archive banner on detail pages */
.state-banner {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--stamp); font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 2px; border: 1px solid var(--rule-strong);
  color: var(--ink-muted); background: var(--paper-sunken); margin-bottom: var(--s3);
}
.state-banner.sold { color: var(--brass); border-color: var(--brass-line); background: var(--brass-weak); }
.state-banner::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ── about page ─────────────────────────────────────────────────────────── */

.prose { max-width: 68ch; margin: 0 auto; padding: var(--s5); }
.prose h1 { font-size: 24px; letter-spacing: -.01em; margin: 0 0 var(--s4); }
.prose h2 { font-size: 16px; margin: var(--s6) 0 var(--s2); }
.prose p { color: var(--ink-muted); }
.prose .lead { color: var(--ink); font-size: 16.5px; }
.contact-card {
  border: 1px solid var(--rule-strong); border-left: 3px solid var(--brass);
  border-radius: 2px; background: var(--paper-raised);
  padding: var(--s4); margin: var(--s5) 0;
}
.contact-card a { color: var(--brass); font-weight: 600; text-decoration: none; }
.contact-card a:hover { text-decoration: underline; }

/* ── utilities that replaced inline styles (CSP style-src 'self' blocks style attrs) ── */

.sr-only {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.page-h1 { font-size: 22px; margin: 0 0 4px; letter-spacing: -.01em; }
.lede { margin: 0 0 24px; color: var(--ink-muted); font-size: 14px; max-width: 62ch; }
.item-h1 { font-size: 21px; line-height: 1.3; margin: 0 0 8px; }
.contact-h { margin-top: 0; }
.contact-line { margin: 4px 0; }
.contact-line.faint { color: var(--ink-faint); }

/* ════════════════════ rev 2: gallery, cart, checkout, de-cluttered browse ════════════════════ */

/* compact h1 on browse pages: kept for SEO/a11y (the old store's missing-h1 failure stays
   fixed), demoted visually per operator — no blurb, no census bar above the grid */
.page-h1.compact { font-size: 15px; color: var(--ink-muted); margin: 0 0 12px; letter-spacing: 0; }

.cart-link {
  font-family: var(--stamp); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  border: 1px solid var(--rule-strong); border-radius: 2px; background: var(--paper);
  color: var(--ink-muted); text-decoration: none; padding: 0 var(--s3);
  min-height: 44px; display: flex; align-items: center; gap: 6px; white-space: nowrap;
}
.cart-link .n { color: var(--brass); font-variant-numeric: tabular-nums; }

/* ── item gallery: main viewer + thumbnail strip ── */
.gallery { display: flex; flex-direction: column; gap: var(--s2); }
.g-main {
  margin: 0; position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  border: 1px solid var(--rule); border-radius: 2px; background: var(--paper-sunken);
  cursor: zoom-in;
}
.g-main img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
.g-main figcaption {
  position: absolute; left: 0; bottom: 0;
  font-family: var(--stamp); font-size: 9.5px; letter-spacing: .08em;
  color: var(--ink-muted); background: var(--paper-raised);
  border-top: 1px solid var(--rule); border-right: 1px solid var(--rule);
  border-top-right-radius: 2px; padding: 3px 7px;
}
.g-thumbs { display: flex; flex-wrap: wrap; gap: var(--s1); }
.g-thumb {
  width: 64px; height: 64px; padding: 0; border: 1px solid var(--rule); border-radius: 2px;
  overflow: hidden; background: var(--paper-sunken); cursor: pointer; min-width: 44px; min-height: 44px;
  position: relative;
}
.g-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.g-thumb[aria-selected="true"] { border-color: var(--brass-line); box-shadow: inset 0 0 0 2px var(--brass-line); }
.g-thumb:hover, .g-thumb:focus-visible { border-color: var(--brass); }

/* lightbox: full-size photo; click toggles 2x zoom; esc/click-outside closes */
.lightbox {
  border: 0; padding: 0; background: rgba(10, 10, 10, .92);
  max-width: 100vw; max-height: 100vh; width: 100vw; height: 100vh;
  margin: 0; position: fixed; inset: 0;
  display: none; align-items: center; justify-content: center; overflow: auto;
}
.lightbox[open] { display: flex; }
.lightbox img {
  max-width: 96vw; max-height: 92vh; object-fit: contain;
  cursor: zoom-in; transition: transform .12s ease-out;
}
.lightbox img.zoom { transform: scale(2); max-width: none; max-height: none; cursor: zoom-out; }
.lb-hint {
  position: fixed; bottom: 12px; left: 50%; transform: translateX(-50%);
  font-family: var(--stamp); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255,255,255,.55); margin: 0;
}
.lightbox::-backdrop { background: rgba(10,10,10,.92); }

/* split buy buttons + compact facts */
.buy-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); }
.buy-cta.add { background: var(--paper-raised); color: var(--ink); border: 1px solid var(--ink); }
.buy-cta.add:hover { background: var(--paper-sunken); }
.qty-line { font-family: var(--stamp); font-size: 11px; color: var(--ink-faint); margin-top: var(--s1); }
.facts { display: flex; flex-wrap: wrap; gap: 4px var(--s3); margin-top: var(--s3); padding-top: var(--s2); border-top: 1px solid var(--rule); }
.facts .fact { font-size: 12px; color: var(--ink-muted); }
.facts .fact b { font-weight: 600; color: var(--ink-faint); }

/* cart + checkout */
.cart-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.cart-table td { padding: var(--s2) var(--s1); border-bottom: 1px solid var(--rule); vertical-align: middle; }
.c-thumb img { width: 56px; height: 56px; object-fit: cover; border: 1px solid var(--rule); border-radius: 2px; display: block; }
.c-title a { color: var(--ink); text-decoration: none; }
.c-title a:hover { text-decoration: underline; }
.c-meta { display: block; font-size: 11px; color: var(--ink-faint); margin-top: 2px; }
.c-price, .c-qty { font-family: var(--stamp); font-variant-numeric: tabular-nums; white-space: nowrap; }
.c-qty { display: flex; align-items: center; gap: var(--s2); }
.c-qty button, .c-rm button {
  font-family: var(--stamp); font-size: 13px; background: var(--paper-raised);
  border: 1px solid var(--rule-strong); border-radius: 2px; cursor: pointer;
  min-width: 32px; min-height: 32px;
}
.c-qty button:disabled { opacity: .4; cursor: default; }
.c-rm button { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-muted); padding: 0 8px; min-height: 32px; }
.cart-summary { margin-top: var(--s4); display: flex; flex-direction: column; gap: var(--s1); }
.sum-row { display: flex; justify-content: space-between; font-size: 14px; padding: var(--s1) 0; border-bottom: 1px solid var(--rule); }
.sum-row b { font-variant-numeric: tabular-nums; }
.sum-row.muted { color: var(--ink-faint); font-size: 12.5px; }
.cart-summary .buy-cta { margin: var(--s3) 0 var(--s1); text-align: center; }
#co-form label { display: flex; flex-direction: column; gap: 4px; margin: var(--s3) 0; font-size: 13px; color: var(--ink-muted); }
#co-form input, #co-form textarea {
  font: inherit; color: var(--ink); background: var(--paper-raised);
  border: 1px solid var(--rule-strong); border-radius: 2px; padding: 10px var(--s2);
}
.co-list { list-style: none; padding: 0; margin: 0 0 var(--s4); }
.co-list li { padding: var(--s2) 0; border-bottom: 1px solid var(--rule); font-size: 14px; }

.buy-note.warn {
  border: 1px solid var(--brass-line); border-left: 3px solid var(--brass);
  background: var(--brass-weak); color: var(--ink);
  padding: var(--s2) var(--s3); border-radius: 2px;
}
