/* ============================================================
   DESIGN BRIEF — The Vault (James) · Sportscard showcase & shop
   Niche: Collectibles commerce (custom build) · Tier: Custom (Timber+ scope)
   Personality: private · premium · obsessive
   Direction: Refined Luxury — "a private bank vault for cardboard."
     Dark showroom, hushed cream type, one champagne-gold accent,
     mono ledger details for grades, certs and vault numbers.
   Fonts: Bodoni Moda (400/600) / Hanken Grotesk (300/400/500)
          + Fragment Mono (400) for ledger accents
   Palette: vault #131210 · cream #EDE5D3 · accent #C2A469 · paper #F1EBDE
   Image treatment: true color, corrected — card photos are the product;
     hairline frame + offset mat on every card image.
   Signature moment: "Tonight's Feature" — one card lit in a framed mat
     with a mono spec ledger (vault no. · grade · cert · price) beside it.
   Primary action: Browse the collection → Buy the card.
   ============================================================ */

/* ------------------------------------------------------------
   1 · TOKENS
   ------------------------------------------------------------ */
:root {
  /* Color — dark showroom base */
  --vault:      #131210;   /* dominant background, warm black */
  --vault-2:    #1B1916;   /* raised panels, alternate sections */
  --vault-3:    #242019;   /* hover / deepest panel */
  --cream:      #EDE5D3;   /* primary text on dark */
  --cream-soft: #A79D89;   /* secondary text on dark */
  --accent:     #C2A469;   /* THE accent — champagne gold, flat, never gradient */
  --accent-ink: #171408;   /* text on accent */
  --line:       #2E2A23;   /* hairlines on dark */
  --line-gold:  #4A4030;   /* emphasized hairline */

  /* Light inversion (one or two sections per page, for rhythm) */
  --paper:      #F1EBDE;
  --paper-2:    #E8E0CE;
  --ink:        #191611;
  --ink-soft:   #5D5647;
  --line-paper: #D8CEB8;

  /* Tier seals — flat metals, used only on seals/chips */
  --tier-reserve:  #C2A469;  /* gold — the crown jewels */
  --tier-showcase: #A8A6A0;  /* steel — graded, serious */
  --tier-stack:    #8A6F52;  /* bronze — raw & affordable */

  /* Status */
  --sold: #8C3B2E;

  /* Type */
  --font-display: 'Bodoni Moda', Georgia, 'Times New Roman', serif;
  --font-body: 'Hanken Grotesk', system-ui, sans-serif;
  --font-mono: 'Fragment Mono', 'Courier New', monospace;
  --text-hero: clamp(3rem, 0.75rem + 7.5vw, 7rem); /* sized so "The Vault" holds ONE line in Bodoni Moda */
  --text-h2: clamp(2rem, 1rem + 3.8vw, 3.5rem);
  --text-h3: clamp(1.3rem, 1rem + 1.3vw, 1.75rem);
  --text-body: 1.0625rem;
  --text-small: 0.875rem;
  --text-mono: 0.8125rem;
  --text-eyebrow: 0.75rem;

  /* Space */
  --s1: 0.5rem;  --s2: 1rem;   --s3: 1.5rem;
  --s4: 2.5rem;  --s5: 4rem;   --s6: 6.5rem;  --s7: 10rem;

  /* Shape & motion */
  --radius: 0px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --speed: 0.6s;

  /* Layout */
  --w-narrow: 42rem;
  --w-mid: 60rem;
  --w-wide: 78rem;
  --header-h: 4.5rem;
}

/* ------------------------------------------------------------
   2 · RESET / BASE
   ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background-color: var(--vault);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: 300;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img, picture, svg, video { display: block; max-width: 100%; }

/* the [hidden] attribute must beat component display rules
   (.btn sets display:inline-flex, which otherwise wins over the
   browser default and leaks hidden controls onto the page) */
[hidden] { display: none !important; }
input, button, textarea, select { font: inherit; color: inherit; }

::selection { background: var(--accent); color: var(--accent-ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 200;
  background: var(--accent); color: var(--accent-ink);
  padding: 0.6em 1.2em; font-weight: 500; text-decoration: none;
}
.skip-link:focus { left: var(--s2); top: var(--s2); }

[id] { scroll-margin-top: calc(var(--header-h) + 1rem); }

/* The room, as ONE composited layer.
   This used to be `background-attachment: fixed` on <body>, which
   forces a full-viewport repaint on every scroll frame — with five
   stacked layers that was the main cause of scroll jank. A fixed
   element instead gets its own compositor layer and simply doesn't
   repaint while the page moves. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
  background-color: var(--vault);
  background-image:
    radial-gradient(110% 85% at 82% -8%, rgba(56, 46, 32, 0.55) 0%, transparent 62%),
    radial-gradient(90% 70% at -12% 38%, rgba(43, 36, 27, 0.5) 0%, transparent 58%),
    radial-gradient(100% 80% at 55% 108%, rgba(38, 31, 22, 0.45) 0%, transparent 60%),
    linear-gradient(rgba(19, 18, 16, 0.52), rgba(19, 18, 16, 0.52)),
    url("../assets/img/page-texture.webp");
  background-size: auto, auto, auto, auto, cover;
  background-position: center;
}

/* Subtle site-wide grain.
   mix-blend-mode was removed here: blending a full-viewport fixed
   layer against everything under it costs a re-blend every frame.
   Plain opacity looks near-identical at this strength and is free. */
body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none;
  z-index: 999; opacity: 0.05;
  transform: translateZ(0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------
   3 · TYPOGRAPHY
   ------------------------------------------------------------ */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
h1 { font-size: var(--text-hero); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); line-height: 1.15; }

p { max-width: 65ch; }
@supports (text-wrap: pretty) { p { text-wrap: pretty; } }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--accent);
  display: block;
  margin-bottom: var(--s3);
}

.mono {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}

.lede { font-size: 1.2rem; font-weight: 300; color: var(--cream-soft); }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
a:hover { text-decoration-thickness: 2px; }

/* ------------------------------------------------------------
   4 · LAYOUT PRIMITIVES
   ------------------------------------------------------------ */
.page-grid {
  display: grid;
  grid-template-columns:
    [full-start] minmax(1.25rem, 1fr)
    [content-start] min(100% - 2.5rem, var(--w-wide)) [content-end]
    minmax(1.25rem, 1fr) [full-end];
}
.page-grid > * { grid-column: content; }
.full-bleed { grid-column: full; }

.section { padding-block: var(--s6); }
.section--tall { padding-block: var(--s7); }
.section--short { padding-block: var(--s5); }

.section--paper { background: var(--paper); color: var(--ink); }
.section--paper .eyebrow { color: #6E5730; }
.section--paper .lede { color: var(--ink-soft); }
.section--paper a { color: #7A5E2E; }

.section-head { margin-bottom: var(--s5); max-width: var(--w-mid); }

.hairline { border: 0; border-top: 1px solid var(--line); }

/* ------------------------------------------------------------
   5 · HEADER / NAV
   ------------------------------------------------------------ */
.site-header {
  position: absolute; top: 0; left: 0; right: 0; z-index: 100;
  height: var(--header-h);
}
.site-header--solid {
  position: sticky; top: 0;
  background: color-mix(in oklab, var(--vault) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.header-inner {
  height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3);
}
/* The wordmark is the real logo lockup ("THE" over an italic "Vault").
   Alt text carries the name for screen readers and for the moment
   before the image lands, so nothing is lost by using artwork here. */
.wordmark {
  color: var(--cream); text-decoration: none;
  display: flex; align-items: center; gap: 0.75rem;
  min-width: 0;
}
.wordmark:hover { text-decoration: none; }
.wordmark picture { display: block; line-height: 0; }
.wordmark img {
  display: block;
  height: 2.35rem; width: auto;
  transition: opacity var(--speed) var(--ease);
}
.wordmark:hover img { opacity: 0.82; }
.wordmark .tv-no {
  font-family: var(--font-mono); font-size: 0.65rem;
  color: var(--accent); letter-spacing: 0.2em;
  padding-top: 0.55em;                 /* optically settles on the "Vault" baseline */
  white-space: nowrap;
}
@media (max-width: 560px) {
  .wordmark img { height: 2rem; }
  .wordmark .tv-no { display: none; }  /* the mark alone at phone widths */
}

.site-nav { display: flex; align-items: center; gap: var(--s4); }
.site-nav a {
  color: var(--cream); text-decoration: none;
  font-size: var(--text-small); font-weight: 400; letter-spacing: 0.04em;
  position: relative; padding-block: 0.4em;
}
.site-nav a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.25s var(--ease);
}
.site-nav a:hover::after, .site-nav a[aria-current="page"]::after { transform: scaleX(1); }
.site-nav a[aria-current="page"] { color: var(--accent); }

.nav-toggle {
  display: none;
  background: none; border: 1px solid var(--line-gold);
  color: var(--cream); padding: 0.5em 0.9em;
  font-family: var(--font-mono); font-size: 0.75rem;
  letter-spacing: 0.15em; text-transform: uppercase; cursor: pointer;
}

@media (max-width: 900px) {
  .nav-toggle { display: block; }
  .site-nav {
    display: none;
    position: absolute; top: var(--header-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--vault-2);
    border-block: 1px solid var(--line-gold);
    padding: var(--s2) 0;
  }
  .site-nav.open { display: flex; }
  .site-nav a {
    padding: 0.9em 1.5rem; font-size: 1.05rem;
    border-bottom: 1px solid var(--line);
  }
  .site-nav a:last-child { border-bottom: 0; }
  .site-nav a::after { display: none; }
}

/* ------------------------------------------------------------
   6 · BUTTONS — The Hairline family (luxury)
   ------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; gap: 0.6em;
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  text-transform: uppercase; letter-spacing: 0.18em;
  text-decoration: none; cursor: pointer;
  transition: color 0.2s var(--ease), background 0.2s var(--ease),
              border-color 0.2s var(--ease);
}

/* Primary: framed gold hairline that fills on hover */
.btn--frame {
  color: var(--accent);
  border: 1px solid var(--accent);
  background: transparent;
  padding: 1em 1.9em;
}
.btn--frame:hover { background: var(--accent); color: var(--accent-ink); text-decoration: none; }
.btn--frame:active { background: color-mix(in oklab, var(--accent) 85%, var(--vault)); }

/* Secondary: underline only */
.btn--hairline {
  color: var(--cream);
  background: none; border: 0; padding: 0.4em 0;
  border-bottom: 1px solid var(--line-gold);
}
.btn--hairline:hover { color: var(--accent); border-bottom-color: var(--accent); text-decoration: none; }
.btn .arrow { transition: translate 0.2s var(--ease); }
.btn:hover .arrow { translate: 4px 0; }

/* Solid — reserved for the single Buy action */
.btn--buy {
  background: var(--accent); color: var(--accent-ink);
  border: 1px solid var(--accent);
  padding: 1.05em 2.2em; font-weight: 400;
}
.btn--buy:hover { background: color-mix(in oklab, var(--accent) 88%, var(--cream)); text-decoration: none; }
.btn--buy:disabled, .btn--buy[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn--frame:disabled:hover { background: transparent; color: var(--accent); }

.section--paper .btn--frame { color: #7A5E2E; border-color: #7A5E2E; }
.section--paper .btn--frame:hover { background: #7A5E2E; color: var(--paper); }

/* ------------------------------------------------------------
   7 · HERO — The Quiet Frame
   ------------------------------------------------------------ */
.hero {
  min-height: 100vh;
  min-height: calc(100svh - 3.5rem); /* deliberate scroll-scent reveal */
  display: grid;
  align-content: center;  /* type block + stat ledge centre as one unit */
  position: relative;
  padding-top: var(--header-h);
  overflow: hidden;
}

/* backdrop plate — the vault door. Type owns the dark left half.
   grid-column: full is load-bearing: as an abspos grid child, its
   containing block is its grid AREA — without this it pins to the
   content column and leaves gutters. */
/* Split Ledger: the door is a full-height plate on the RIGHT, bleeding to
   the viewport edge, with the wheel sitting between the type column and
   the dial. The type owns the dark left. */
.hero-bg {
  position: absolute; inset: 0 0 0 auto; z-index: 0; grid-column: full;
  /* always leaves ~32rem of clear dark for the type column, whatever the
     viewport — the plate takes what is left, up to 64% */
  width: clamp(20rem, min(64%, 100vw - 32rem), 62rem);
}
.hero-bg picture { display: block; width: 100%; height: 100%; }
.hero-bg img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center center;
}
/* Gradient scrim ONLY where the text sits. The door plate is lit, so the
   left of the frame is dropped into shadow and the wheel emerges into the
   light at centre-right — a designed lighting relationship, not a flat
   grey wash over the whole photograph. */
.hero-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    /* keeps the nav legible over the top of the plate */
    linear-gradient(180deg, rgba(16, 15, 13, 0.55) 0, rgba(16, 15, 13, 0) 22%),
    /* dissolves the plate's left edge into the page instead of ending on a line */
    linear-gradient(90deg,
      var(--vault) 0,
      rgba(16, 15, 13, 0.88) 12%,
      rgba(16, 15, 13, 0.42) 28%,
      rgba(16, 15, 13, 0.10) 44%,
      rgba(16, 15, 13, 0) 60%);
}
/* Preferred: mask the plate's left edge so it dissolves into the page's own
   lit texture. The opaque scrim above is the fallback. */
@supports (mask-image: linear-gradient(#000, transparent)) or
          (-webkit-mask-image: linear-gradient(#000, transparent)) {
  .hero-bg {
    -webkit-mask-image: linear-gradient(90deg, transparent 0%,
                          rgba(0, 0, 0, 0.4) 12%, #000 36%);
            mask-image: linear-gradient(90deg, transparent 0%,
                          rgba(0, 0, 0, 0.4) 12%, #000 36%);
  }
  .hero-bg::after {
    background:
      linear-gradient(180deg, rgba(16, 15, 13, 0.55) 0, rgba(16, 15, 13, 0) 22%),
      linear-gradient(90deg,
        rgba(16, 15, 13, 0.70) 0,
        rgba(16, 15, 13, 0.30) 26%,
        rgba(16, 15, 13, 0.08) 46%,
        rgba(16, 15, 13, 0) 64%);
  }
}
.hero-inner {
  justify-self: start;
  text-align: left;
  position: relative; z-index: 1;
  padding: var(--s4) var(--s3) 0 0;
  display: grid; justify-items: start;
  max-width: 46rem;
}
/* The hero mark is the logo artwork itself. It sizes off the viewport
   the same way the old type did, so the composition against the vault
   door is unchanged — only the letterforms are now the real ones. */
.hero-title {
  margin-block: var(--s3) var(--s4);
  line-height: 0;
}
.hero-title picture { display: block; }
.hero-title img {
  display: block;
  width: clamp(14rem, 5rem + 27vw, 30rem);
  height: auto;
  filter: drop-shadow(0 2px 18px rgba(0, 0, 0, 0.55));
}

/* scroll cue — phone only; the door fills the screen, so the fold
   needs a spoken instruction rather than an implied one */
.hero-scroll {
  display: none;
  font-family: var(--font-mono); font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: 0.32em;
  color: var(--cream-soft);
  padding-top: 0.9em;
}
.hero-sub {
  color: var(--cream-soft);
  font-size: 1.1rem;
  /* stays clear of the door plate as the viewport narrows */
  max-width: min(34rem, 42vw);
  margin-bottom: var(--s4);
}
.hero .eyebrow { margin-bottom: 0; }

/* the stat ledge hanging under the CTA.
   NOTE: the bare .hero-ledge rules are shared with the admin dashboard —
   hero-specific placement is scoped to `.hero > .hero-ledge` below. */
.hero-ledge {
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
  display: flex; gap: var(--s4); flex-wrap: wrap; justify-content: flex-start;
  width: 100%;
}
/* it is a grid child of .hero now (not of .hero-inner) so the ledge can
   sit below the fold on phones while the type block owns the viewport */
.hero > .hero-ledge {
  position: relative; z-index: 1;
  justify-self: start;
  max-width: min(34rem, 42vw); /* aligns to the right edge of .hero-sub */
  padding-bottom: var(--s4);   /* balances .hero-inner's top padding */
}
.hero-ledge .stat { text-align: left; }
.hero-ledge .stat b {
  display: block; font-family: var(--font-display); font-weight: 400;
  font-size: 1.6rem; color: var(--cream);
}
.hero-ledge .stat span {
  font-family: var(--font-mono); font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--cream-soft);
}

/* ---- PORTRAIT / PHONE: the door IS the first screen --------------
   The hero image runs full-bleed for exactly one viewport; the type
   sits in the lower third where the crop is quiet, over a vertical
   scrim that fades to solid vault at the bottom edge. The stat ledge
   is deliberately parked below the fold as scroll scent. The CTA and
   the scroll cue must both clear the fold at 375x667 — verified, not
   eyeballed (see §10 hard rule).
   Portrait up to 820px: the split hero needs real horizontal room, so
   narrow tablets get the billboard rather than a squeezed two-column. */
@media (max-width: 820px) and (orientation: portrait) {
  .hero { min-height: 0; padding-top: 0; }

  .wide-only { display: none; }

  /* The door plate: top-anchored and sized off the VIEWPORT WIDTH, not
     the height — that is what keeps the crop wide enough to hold the
     whole dial and the handle at every phone size (a height-driven box
     zooms in and eats them). It stays crisp through its top three
     quarters, then dissolves into solid vault so the type below sits on
     clean dark rather than on brass. */
  /* The plate is parked ABOVE THE TYPE, not at the top of the screen —
     otherwise tall phones open with the door jammed under the header and
     a dead zone in the middle. 22rem is the height of the type block, so
     the door drops down to meet it and overlaps its top edge slightly.
     max() keeps it below the header on short phones. */
  .hero-bg {
    display: block;
    inset: auto 0 auto 0;
    width: auto;
    top: var(--header-h);
    height: max(38vh, calc(100vh - 22rem - var(--header-h)));
    height: max(38svh, calc(100svh - 22rem - var(--header-h)));
  }
  .hero-bg img { object-position: center 42%; }
  .hero-bg::after {
    background: linear-gradient(180deg,
      rgba(19, 18, 16, 0.62) 0%,
      rgba(19, 18, 16, 0.10) 16%,
      rgba(19, 18, 16, 0.10) 52%,
      rgba(19, 18, 16, 0.38) 72%,
      rgba(19, 18, 16, 0.78) 86%,
      rgba(19, 18, 16, 0.96) 95%,
      var(--vault) 99.5%);
  }
  /* Preferred finish: dissolve the plate itself so it melts into the
     page's own lit texture instead of into a flat block of --vault
     (which leaves a faint horizontal seam). The scrim above is the
     fallback for browsers without mask-image. */
  @supports (mask-image: linear-gradient(#000, transparent)) or
            (-webkit-mask-image: linear-gradient(#000, transparent)) {
    .hero-bg {
      -webkit-mask-image: linear-gradient(180deg, transparent 0%,
                            rgba(0, 0, 0, 0.45) 7%, #000 20%, #000 58%,
                            rgba(0, 0, 0, 0.5) 82%, transparent 99%);
              mask-image: linear-gradient(180deg, transparent 0%,
                            rgba(0, 0, 0, 0.45) 7%, #000 20%, #000 58%,
                            rgba(0, 0, 0, 0.5) 82%, transparent 99%);
    }
    .hero-bg::after {
      background: linear-gradient(180deg,
        rgba(19, 18, 16, 0.62) 0%,
        rgba(19, 18, 16, 0.10) 16%,
        rgba(19, 18, 16, 0.10) 52%,
        rgba(19, 18, 16, 0.40) 76%,
        rgba(19, 18, 16, 0.70) 100%);
    }
  }

  .hero-inner {
    min-height: 100vh; min-height: 100svh;
    align-content: end;
    justify-self: center; justify-items: center; text-align: center;
    padding: calc(var(--header-h) + var(--s3)) var(--s3) var(--s4);
    max-width: 32rem; width: 100%;
  }
  .hero .eyebrow { font-size: 0.66rem; letter-spacing: 0.16em; }
  .hero-title { margin-block: var(--s2) var(--s3); }
  .hero-title img { width: min(70vw, 19rem); }
  .hero-sub { font-size: 1rem; margin-bottom: var(--s3); max-width: 24rem; }
  .hero-scroll { display: block; }

  /* below the fold: a three-up spec strip, ruled like a ledger */
  .hero > .hero-ledge {
    justify-self: stretch; max-width: none;
    margin-top: 0; padding-block: var(--s3) var(--s4);
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 0;
  }
  .hero > .hero-ledge .stat { text-align: center; padding-inline: 0.4rem; }
  .hero > .hero-ledge .stat + .stat { border-left: 1px solid var(--line); }
  .hero > .hero-ledge .stat b { font-size: 1.3rem; }
  .hero > .hero-ledge .stat span {
    display: block; font-size: 0.56rem; letter-spacing: 0.1em;
  }
  .hero-ledge { gap: var(--s3); }   /* admin dashboard keeps its flex row */
}

/* Wider portrait (small tablets): the same billboard, but with room to
   breathe — the door plate runs deeper, the scrim lifts off the wheel,
   and the mark grows. Phones keep the tighter crop tuned above. */
@media (min-width: 601px) and (max-width: 820px) and (orientation: portrait) {
  .hero-inner { max-width: 38rem; }
  .hero-title img { width: min(54vw, 22rem); }
  .hero-sub { font-size: 1.05rem; max-width: 28rem; }
  .hero > .hero-ledge .stat b { font-size: 1.6rem; }
  .hero > .hero-ledge .stat span { font-size: 0.68rem; letter-spacing: 0.14em; }
}

/* short landscape (a phone turned sideways): never force a viewport-tall
   hero into 360px of height. The hero takes the height its content needs,
   and the mark and rhythm tighten so the CTA still lands above the fold */
@media (orientation: landscape) and (max-height: 560px) {
  .hero {
    min-height: 0;
    padding-block: calc(var(--header-h) + var(--s1)) var(--s3);
  }
  .hero-title { margin-block: var(--s1) var(--s2); }
  .hero-title img { width: clamp(9rem, 18vw, 12rem); }
  .hero-sub { font-size: 1rem; margin-bottom: var(--s2); max-width: 30rem; }
  .hero > .hero-ledge { margin-top: var(--s3); padding-bottom: var(--s3); }
}

/* ------------------------------------------------------------
   8 · CARD TILES & IMAGE SLOTS
   ------------------------------------------------------------ */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--s4) var(--s3);
}

.card-tile {
  text-decoration: none; color: var(--cream);
  display: block; position: relative;
}
.card-tile:hover { text-decoration: none; }

.card-img {
  aspect-ratio: 3 / 4;
  /* the velvet bed — cards sit on the shoot's own display-tray plate */
  background-image:
    linear-gradient(rgba(19, 18, 16, 0.5), rgba(19, 18, 16, 0.72)),
    url("../assets/img/collection-velvet.webp");
  background-size: cover;
  background-position: center;
  border: 1px solid var(--line);
  outline: 1px solid var(--line);
  outline-offset: 6px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 14px 34px -18px rgba(0, 0, 0, 0.85);
  transition: outline-color 0.3s var(--ease), border-color 0.3s var(--ease),
              box-shadow 0.45s var(--ease), translate 0.45s var(--ease);
  margin: 7px; /* room for the offset mat */
}
.card-tile:hover .card-img {
  border-color: var(--accent); outline-color: var(--line-gold);
  translate: 0 -4px;
  box-shadow:
    0 22px 44px -18px rgba(0, 0, 0, 0.9),
    0 6px 40px -6px rgba(194, 164, 105, 0.22); /* gold under-glow */
}
.card-img img {
  width: 100%; height: 100%; object-fit: contain; padding: 5%; box-sizing: border-box;
  transition: scale 0.6s var(--ease);
}
.card-tile:hover .card-img img { scale: 1.03; }
/* vary the velvet crop so neighboring empty slots don't read as a repeat */
.card-tile:nth-child(2n) .card-img { background-position: 20% 30%; }
.card-tile:nth-child(3n) .card-img { background-position: 75% 60%; }
.card-tile:nth-child(4n) .card-img { background-position: 40% 80%; }
/* light sweep — a lamp passing across the slab */
.card-img::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg,
    transparent 42%, rgba(237, 229, 211, 0.13) 50%, transparent 58%);
  translate: -130% 0;
  transition: translate 0.7s var(--ease);
}
.card-tile:hover .card-img::after { translate: 130% 0; }
.card-tile .card-title { transition: color 0.3s var(--ease); }
.card-tile:hover .card-title { color: var(--accent); }

/* honest placeholder slot when no photo exists yet — label floats on the velvet bed */
.img-slot {
  position: absolute; inset: 0;
  display: grid; place-content: center; gap: 0.4rem;
  text-align: center;
  color: var(--cream);
  font-family: var(--font-mono); font-size: 0.7rem;
  letter-spacing: 0.15em; text-transform: uppercase;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.8);
}
.img-slot::before { content: "—"; color: var(--accent); font-size: 1rem; }

.card-meta { padding: var(--s2) 7px 0; }
.card-meta .card-title {
  font-family: var(--font-display); font-size: 1.1rem; line-height: 1.2;
  margin-bottom: 0.35rem;
}
.card-meta .card-specs {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2);
  color: var(--cream-soft);
}
.card-meta .price { color: var(--accent); font-family: var(--font-mono); font-size: 0.95rem; }

/* tier seal — flat stamped disc, top corner of tile */
.seal {
  position: absolute; top: 0; right: 0; z-index: 2;
  width: 2.4rem; height: 2.4rem; border-radius: 50%;
  display: grid; place-content: center;
  font-family: var(--font-mono); font-size: 0.65rem; letter-spacing: 0.05em;
  background: color-mix(in oklab, currentColor 14%, var(--vault));
  border: 1px solid currentColor;
  /* stamped-coin depth: inner ring + recessed shadow */
  box-shadow:
    inset 0 0 0 2.5px var(--vault),
    inset 0 2px 8px rgba(0, 0, 0, 0.55);
}
.seal--reserve  { color: var(--tier-reserve); }
.seal--showcase { color: var(--tier-showcase); }
.seal--stack    { color: var(--tier-stack); }

.chip {
  display: inline-block;
  font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  border: 1px solid var(--line-gold);
  padding: 0.25em 0.7em; color: var(--cream-soft);
}
.chip--grade { color: var(--cream); border-color: var(--line-gold); }
.chip--sold { color: var(--paper); background: var(--sold); border-color: var(--sold); }

/* sold overlay stamp on tiles */
.card-tile.is-sold .card-img::after {
  content: "SOLD";
  position: absolute; inset: 0;
  display: grid; place-content: center;
  font-family: var(--font-mono); letter-spacing: 0.35em; font-size: 0.9rem;
  color: var(--cream);
  background: color-mix(in oklab, var(--vault) 62%, transparent);
}

/* ------------------------------------------------------------
   9 · TONIGHT'S FEATURE — the signature moment
   ------------------------------------------------------------ */
.feature {
  background-color: var(--vault-2);
  /* the whole spotlight section sits on the velvet plate */
  background-image:
    linear-gradient(rgba(27, 25, 22, 0.86), rgba(27, 25, 22, 0.93)),
    url("../assets/img/collection-velvet.webp");
  background-size: cover;
  background-position: center;
  border-block: 1px solid var(--line-gold);
}
.feature-grid {
  display: grid; gap: var(--s5);
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  align-items: center;
}
.feature-img-wrap {
  justify-self: center;
  width: min(100%, 24rem);
  position: relative;
}
/* the lit mat: a soft radial glow behind the framed card — light, not gradient-decor */
.feature-img-wrap::before {
  content: ""; position: absolute; inset: -14%;
  background: radial-gradient(closest-side, color-mix(in oklab, var(--accent) 14%, transparent), transparent 75%);
  pointer-events: none;
}
.feature-img {
  aspect-ratio: 3 / 4;
  border: 1px solid var(--line-gold);
  outline: 1px solid var(--line-gold);
  outline-offset: 10px;
  background-image:
    linear-gradient(rgba(19, 18, 16, 0.4), rgba(19, 18, 16, 0.6)),
    url("../assets/img/collection-velvet.webp");
  background-size: cover;
  background-position: center;
  position: relative; overflow: hidden;
  box-shadow: 0 26px 60px -24px rgba(0, 0, 0, 0.9);
}
/* when a real photo is in, the frame hugs it exactly — photo fills edge to edge */
.feature-img:has(img) { aspect-ratio: auto; }
.feature-img img { width: 100%; height: auto; display: block; }

.spec-ledger { list-style: none; padding: 0; margin-block: var(--s4); max-width: 30rem; }
.spec-ledger li {
  display: flex; align-items: baseline; gap: 0.75em;
  padding-block: 0.65em;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono); font-size: var(--text-mono);
  font-variant-numeric: tabular-nums;
}
.spec-ledger .k { color: var(--cream-soft); text-transform: uppercase; letter-spacing: 0.12em; flex-shrink: 0; }
.spec-ledger .dots { flex: 1; border-bottom: 1px dotted var(--line-gold); translate: 0 -0.3em; }
.spec-ledger .v { color: var(--cream); text-align: right; }
.spec-ledger .v.gold { color: var(--accent); }

@media (max-width: 900px) {
  .feature-grid { grid-template-columns: 1fr; gap: var(--s4); }
  .feature-img-wrap { width: min(100%, 18rem); }
}

/* ------------------------------------------------------------
   10 · TIER LEDGER ROWS
   ------------------------------------------------------------ */
.tier-rows { border-top: 1px solid var(--line-gold); }
.tier-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; gap: var(--s4);
  padding-block: var(--s4);
  border-bottom: 1px solid var(--line-gold);
  text-decoration: none; color: var(--cream);
  transition: background 0.3s var(--ease);
}
.tier-row:hover { background: var(--vault-2); text-decoration: none; }
.tier-row .seal { position: static; width: 3.2rem; height: 3.2rem; font-size: 0.75rem; }
.tier-row h3 { margin-bottom: 0.3rem; }
.tier-row .tier-desc { color: var(--cream-soft); font-size: var(--text-small); max-width: 38rem; }
.tier-row .tier-count {
  font-family: var(--font-mono); font-size: var(--text-mono);
  color: var(--cream-soft); white-space: nowrap;
}
.tier-row .tier-go { color: var(--accent); font-family: var(--font-mono); }
@media (max-width: 720px) {
  .tier-row { grid-template-columns: auto minmax(0, 1fr); row-gap: var(--s2); }
  .tier-row .tier-count { grid-column: 2; }
  .tier-row .tier-go { display: none; }
}

/* ------------------------------------------------------------
   11 · RECORDS LEDGER (sold archive)
   ------------------------------------------------------------ */
.ledger { width: 100%; border-collapse: collapse; }
.ledger th {
  text-align: left; font-family: var(--font-mono); font-weight: 400;
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--cream-soft);
  padding: 0.8em 1em 0.8em 0;
  border-bottom: 1px solid var(--line-gold);
}
.ledger td {
  padding: 1em 1em 1em 0;
  border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  vertical-align: baseline;
}
.ledger td.mono { color: var(--cream-soft); }
.ledger .ledger-title { font-family: var(--font-display); font-size: 1.05rem; }
.ledger td:last-child, .ledger th:last-child { text-align: right; padding-right: 0; }
@media (max-width: 640px) {
  .ledger .hide-sm { display: none; }
}

/* ------------------------------------------------------------
   12 · FILTER BAR (collection)
   ------------------------------------------------------------ */
.filter-bar {
  display: grid; gap: var(--s2);
  grid-template-columns: minmax(0, 2fr) repeat(4, minmax(0, 1fr));
  align-items: end;
  padding-block: var(--s3);
  border-block: 1px solid var(--line-gold);
  margin-bottom: var(--s4);
}
.filter-field label {
  display: block;
  font-family: var(--font-mono); font-size: 0.65rem;
  text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--cream-soft); margin-bottom: 0.4em;
}
.filter-field input, .filter-field select {
  width: 100%;
  background: var(--vault-2);
  border: 1px solid var(--line-gold);
  color: var(--cream);
  padding: 0.65em 0.8em;
  font-size: 16px; /* iOS zoom guard */
  border-radius: var(--radius);
}
.filter-field input:focus, .filter-field select:focus {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
.filter-field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23C2A469'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.8em center;
  padding-right: 2.2em;
}
.result-count { font-family: var(--font-mono); font-size: var(--text-mono); color: var(--cream-soft); margin-bottom: var(--s3); }
@media (max-width: 900px) { .filter-bar { grid-template-columns: 1fr 1fr; } .filter-bar .filter-field:first-child { grid-column: 1 / -1; } }

.empty-state {
  text-align: center; padding: var(--s6) var(--s3);
  border: 1px solid var(--line); color: var(--cream-soft);
}

/* ------------------------------------------------------------
   13 · CARD DETAIL PAGE
   ------------------------------------------------------------ */
.detail-grid {
  display: grid; gap: var(--s5);
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  align-items: start;
}
.detail-gallery { position: sticky; top: calc(var(--header-h) + var(--s3)); }
.detail-main-img {
  aspect-ratio: 3 / 4;
  border: 1px solid var(--line-gold);
  outline: 1px solid var(--line);
  outline-offset: 8px;
  /* card floats on the velvet tray, letterboxed edges included */
  background-image:
    linear-gradient(rgba(19, 18, 16, 0.42), rgba(19, 18, 16, 0.62)),
    url("../assets/img/collection-velvet.webp");
  background-size: cover;
  background-position: center;
  position: relative; overflow: hidden;
  margin: 9px;
  box-shadow: 0 26px 60px -24px rgba(0, 0, 0, 0.9);
}
.detail-main-img:has(img) { aspect-ratio: auto; }
.detail-main-img img { width: 100%; height: auto; display: block; }
.detail-main-img { cursor: zoom-in; }
.zoom-hint {
  display: block;
  margin-top: var(--s2);
  font-family: var(--font-mono); font-size: 0.65rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--cream-soft);
}
.detail-thumbs { display: flex; gap: var(--s2); margin-top: var(--s3); flex-wrap: wrap; }
.detail-thumbs button {
  width: 4.5rem; aspect-ratio: 3/4;
  border: 1px solid var(--line); background: var(--vault-2);
  cursor: pointer; overflow: hidden; padding: 0;
}
.detail-thumbs button[aria-current="true"] { border-color: var(--accent); }
.detail-thumbs img { width: 100%; height: 100%; object-fit: cover; }

.detail-info .vault-no { margin-bottom: var(--s2); }
.detail-price {
  font-family: var(--font-mono); font-size: 1.6rem; color: var(--accent);
  margin-block: var(--s3); font-variant-numeric: tabular-nums;
}
.buy-note { font-size: var(--text-small); color: var(--cream-soft); margin-top: var(--s2); }
.sold-banner {
  display: inline-block;
  font-family: var(--font-mono); letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--paper); background: var(--sold);
  padding: 0.6em 1.4em; margin-block: var(--s3);
}
.detail-desc { margin-top: var(--s4); color: var(--cream-soft); }
.detail-desc p + p { margin-top: var(--s2); }
@media (max-width: 900px) {
  .detail-grid { grid-template-columns: 1fr; }
  .detail-gallery { position: static; }
}

/* ------------------------------------------------------------
   13b · LIGHTBOX — inspect the card up close
   Buyers judge corners, surfaces and autographs. This is the
   closest thing to holding it, so it gets real magnification
   with pan, not a modestly bigger picture.
   ------------------------------------------------------------ */
.lightbox {
  position: fixed; inset: 0; z-index: 500;
  display: none;
  background: color-mix(in oklab, var(--vault) 94%, transparent);
  backdrop-filter: blur(6px);
  overscroll-behavior: contain;
}
.lightbox[open], .lightbox.is-open { display: grid; grid-template-rows: auto 1fr auto; }
body.lb-locked { overflow: hidden; }

.lb-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
}
.lb-title {
  font-family: var(--font-mono); font-size: var(--text-mono);
  color: var(--cream-soft); letter-spacing: 0.06em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-close {
  background: none; border: 1px solid var(--line-gold); color: var(--cream);
  font-family: var(--font-mono); font-size: 0.7rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  padding: 0.6em 1.1em; cursor: pointer; flex-shrink: 0;
}
.lb-close:hover { border-color: var(--accent); color: var(--accent); }

.lb-stage {
  position: relative;
  overflow: hidden;
  touch-action: none;
  /* grid items default to min-height:auto, which lets content push
     the row taller than the viewport instead of fitting inside it. */
  min-height: 0; min-width: 0;
}
/* The image is absolutely positioned so its percentages resolve
   against the stage's padding box, which is always definite after
   layout. Percentages against a `1fr` grid row are not reliable —
   the image renders at full intrinsic size and overflows. */
.lb-stage img {
  position: absolute;
  top: var(--s3); left: var(--s3);
  width: calc(100% - 2 * var(--s3));
  height: calc(100% - 2 * var(--s3));
  object-fit: contain;
  cursor: zoom-in;
  transition: transform 0.35s var(--ease);
  will-change: transform;
}
.lb-stage.is-zoomed img { cursor: zoom-out; transition: transform 0.08s linear; }
@media (prefers-reduced-motion: reduce) { .lb-stage img { transition: none; } }

.lb-foot {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s3);
  padding: var(--s3);
  border-top: 1px solid var(--line);
}
.lb-nav {
  background: none; border: 0; color: var(--cream);
  font-family: var(--font-mono); font-size: 1.1rem;
  cursor: pointer; padding: 0.3em 0.8em;
}
.lb-nav:hover { color: var(--accent); }
.lb-nav[disabled] { opacity: 0.25; cursor: default; }
.lb-count {
  font-family: var(--font-mono); font-size: var(--text-mono);
  color: var(--cream-soft); font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  .lb-bar { padding: var(--s2); }
  .lb-title { font-size: 0.65rem; }
}

/* ------------------------------------------------------------
   14 · FORMS
   ------------------------------------------------------------ */
.form-grid { display: grid; gap: var(--s3); max-width: var(--w-narrow); }
.form-field label {
  display: block; font-family: var(--font-mono);
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--cream-soft); margin-bottom: 0.5em;
}
.form-field .req { color: var(--accent); }
.form-field input, .form-field textarea, .form-field select {
  width: 100%;
  background: var(--vault-2);
  border: 1px solid var(--line-gold);
  color: var(--cream);
  padding: 0.8em 1em;
  font-size: 16px;
  border-radius: var(--radius);
}
.form-field input:focus, .form-field textarea:focus, .form-field select:focus {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
.form-field textarea { min-height: 8rem; resize: vertical; }
.form-note { font-size: var(--text-small); color: var(--cream-soft); }
.form-msg { padding: 1em 1.2em; font-size: var(--text-small); display: none; }
.form-msg.show { display: block; }
.form-msg--ok { border: 1px solid var(--accent); color: var(--accent); }
.form-msg--err { border: 1px solid var(--sold); color: #D98A7C; }
.hp-field { position: absolute; left: -9999px; opacity: 0; pointer-events: none; }

/* paper section variants */
.section--paper .form-field input, .section--paper .form-field textarea, .section--paper .form-field select {
  background: var(--paper); border-color: var(--line-paper); color: var(--ink);
}
.section--paper .form-field label { color: var(--ink-soft); }

/* inline email capture row */
.capture-row {
  display: flex; gap: var(--s2); max-width: 30rem; flex-wrap: wrap;
}
.capture-row input {
  flex: 1 1 14rem;
  background: var(--vault-2); border: 1px solid var(--line-gold);
  color: var(--cream); padding: 0.85em 1em; font-size: 16px;
}
.capture-row input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ------------------------------------------------------------
   14b · ATMOSPHERE BANDS (collection velvet · sell back room)
   ------------------------------------------------------------ */
.page-band {
  border-block: 1px solid var(--line-gold);
}
.page-band img {
  width: 100%;
  height: clamp(10rem, 26vw, 20rem);
  object-fit: cover;
  display: block;
}

/* framed 404 art */
.err-img {
  width: min(100%, 24rem);
  margin-inline: auto;
  border: 1px solid var(--line-gold);
  outline: 1px solid var(--line);
  outline-offset: 8px;
  margin-block: var(--s2);
}
.err-img img { width: 100%; height: auto; }

/* ------------------------------------------------------------
   15 · INTERLUDE / STATEMENT
   ------------------------------------------------------------ */
.interlude { text-align: center; position: relative; overflow: hidden; padding-inline: var(--s3); }
/* type-as-texture: a ghost of the wordmark behind the statement */
.interlude::before {
  content: "VAULT" / "";
  position: absolute; top: 50%; left: 50%;
  translate: -50% -50%;
  font-family: var(--font-display);
  /* viewport-scale watermark — the section is full-bleed so all five
     letters span the screen without ever cropping */
  font-size: clamp(6rem, 24vw, 26rem);
  letter-spacing: 0.08em;
  color: transparent;
  -webkit-text-stroke: 1px var(--line-gold);
  opacity: 0.55;
  pointer-events: none;
  white-space: nowrap;
}
.interlude .big {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 1rem + 3vw, 3rem);
  line-height: 1.2; max-width: 26ch; margin-inline: auto;
  position: relative;
}
.interlude .big em { color: var(--accent); font-style: italic; }

/* ------------------------------------------------------------
   16 · FOOTER
   ------------------------------------------------------------ */
.site-footer {
  border-top: 1px solid var(--line-gold);
  padding-block: var(--s5) var(--s4);
  color: var(--cream-soft);
  font-size: var(--text-small);
}
.footer-grid {
  display: grid; gap: var(--s4);
  grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 1fr));
}
.footer-grid h4 {
  font-family: var(--font-mono); font-weight: 400; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.2em; color: var(--cream);
  margin-bottom: var(--s2);
}
.site-footer ul { list-style: none; padding: 0; display: grid; gap: 0.5em; }
.site-footer a { color: var(--cream-soft); }
.site-footer a:hover { color: var(--accent); }
.footer-word {
  margin-bottom: var(--s3);
  line-height: 0;
}
.footer-word img {
  display: block;
  width: min(10rem, 52%); height: auto;
  opacity: 0.88;
}
.footer-legal {
  margin-top: var(--s5); padding-top: var(--s3);
  border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; gap: var(--s3); flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em;
}
@media (max-width: 720px) { .footer-grid { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------
   17 · REVEALS & MOTION
   ------------------------------------------------------------ */
[data-reveal] {
  opacity: 0; translate: 0 24px;
  transition: opacity var(--speed) var(--ease), translate var(--speed) var(--ease);
}
[data-reveal].in { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; translate: none; transition: none; }
  .card-tile:hover .card-img img { scale: none; }
  .card-img::after { display: none; }
  .card-tile:hover .card-img { translate: none; }
}

/* ------------------------------------------------------------
   18 · ADMIN (utilitarian, same family)
   ------------------------------------------------------------ */
/* ---- The admin is a TOOL, not the showroom ------------------
   James works in here for hours at a stretch. The atmospheric
   background, the grain and the tight display type all belong on
   the public site; in here they cost legibility and make long
   sessions tiring. This page gets a calm flat surface, bigger
   type, and more air between rows. */
body.admin-page::before {
  background-image: none;
  background-color: #14130F;
}
body.admin-page::after { display: none; }   /* no grain over data */
body.admin-page {
  font-size: 1rem;
  line-height: 1.6;
}

.admin-wrap { max-width: 74rem; margin-inline: auto; padding: var(--s4) var(--s3) var(--s7); }
.admin-bar {
  display: flex; justify-content: space-between; align-items: center; gap: var(--s3);
  padding-block: var(--s3); border-bottom: 1px solid var(--line-gold); margin-bottom: var(--s4);
  flex-wrap: wrap;
}
.admin-banner {
  border: 1px solid var(--accent); color: var(--accent);
  font-family: var(--font-mono); font-size: var(--text-mono);
  padding: 1em 1.2em; margin-bottom: var(--s4);
}
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.admin-table th {
  text-align: left; font-family: var(--font-mono); font-weight: 400; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--cream-soft);
  padding: 0.9em 1em 0.9em 0; border-bottom: 1px solid var(--line-gold);
  /* stay visible while scrolling a long inventory */
  position: sticky; top: 0; z-index: 3;
  background: #14130F;
}
.admin-table td {
  padding: 1.05em 1em 1.05em 0;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
/* quiet banding so the eye tracks across a wide row */
.admin-table tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.018); }
.admin-table tbody tr:hover { background: rgba(194, 164, 105, 0.055); }
.admin-table .c-title {
  max-width: 24rem;
  font-family: var(--font-body);
  font-size: 0.95rem; line-height: 1.45; color: var(--cream);
}
.admin-table .c-meta { color: var(--cream-soft); font-size: 0.8rem; letter-spacing: 0.01em; }
/* short columns shouldn't wrap — "The Showcase" and "available"
   breaking onto two lines is what made the rows look ragged */
.admin-table td[data-label="Tier"],
.admin-table td[data-label="Status"],
.admin-table td[data-label="Price"],
.admin-table td[data-label="Featured"],
.admin-table td[data-label="Views"] { white-space: nowrap; }
.admin-table td[data-label="Views"] { text-align: right; padding-right: 1.5em; }
.admin-table th:nth-child(7) { text-align: right; padding-right: 1.5em; }
.admin-table .thumb {
  width: 3rem; aspect-ratio: 3/4; object-fit: cover;
  border: 1px solid var(--line); border-radius: 2px;
}
.admin-actions { display: flex; gap: 0.45rem; flex-wrap: wrap; justify-content: flex-end; }

/* ---- row actions menu ---- */
.admin-table .c-actions { text-align: right; width: 3rem; }
.kebab {
  background: none; border: 1px solid transparent; color: var(--cream-soft);
  font-size: 1.15rem; line-height: 1; letter-spacing: 0.08em;
  padding: 0.35em 0.55em; cursor: pointer; border-radius: 2px;
}
.kebab:hover, .kebab[aria-expanded="true"] {
  color: var(--accent); border-color: var(--line-gold); background: var(--vault-2);
}

.row-menu {
  position: fixed; z-index: 600; display: none;
  min-width: 15rem;
  background: #1C1A16;
  border: 1px solid var(--line-gold);
  box-shadow: 0 18px 40px -14px rgba(0, 0, 0, 0.85);
  padding: 0.35rem;
}
.row-menu.is-open { display: block; }
.row-menu button {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; cursor: pointer;
  color: var(--cream); font-family: var(--font-body); font-size: 0.9rem;
  padding: 0.62em 0.8em; border-radius: 2px;
}
.row-menu button:hover { background: rgba(194, 164, 105, 0.12); color: var(--accent); }
.row-menu hr { border: 0; border-top: 1px solid var(--line); margin: 0.35rem 0; }
.row-menu .is-danger { color: #C87F72; }
.row-menu .is-danger:hover { background: rgba(140, 59, 46, 0.22); color: #E6A79A; }
.row-menu .is-danger.is-armed {
  background: var(--sold); color: var(--paper);
  animation: armed-pulse 1s ease-in-out infinite;
}
.admin-table .btn--sm {
  padding: 0.45em 0.75em; font-size: 0.66rem; letter-spacing: 0.1em;
  border-bottom-color: var(--line-gold);
}
/* the bar across the top of the admin */
body.admin-page .admin-bar { margin-bottom: var(--s4); padding-block: var(--s3) var(--s3); }
body.admin-page .hero-ledge .stat b { font-size: 1.75rem; }
body.admin-page .hero-ledge { gap: var(--s5); }
body.admin-page .form-field label { font-size: 0.72rem; letter-spacing: 0.12em; }
body.admin-page .admin-form { gap: var(--s4) var(--s3); }
.admin-table .c-meta::before { display: none; } /* labels are desktop headers */

/* --- Phone: the table becomes a stack of cards ---------------
   James adds inventory from his phone (that's where the card
   photos are), so this view is a first-class layout, not a
   squeezed-down desktop table. */
@media (max-width: 760px) {
  .admin-table, .admin-table tbody, .admin-table tr, .admin-table td { display: block; width: 100%; }
  .admin-table thead { display: none; }
  .admin-table tr {
    display: grid;
    grid-template-columns: 3.6rem minmax(0, 1fr);
    gap: 0 var(--s2);
    align-items: center;
    border: 1px solid var(--line-gold);
    padding: var(--s2);
    margin-bottom: var(--s2);
  }
  .admin-table td { border: 0; padding: 0; width: auto; }

  .admin-table .c-thumb { grid-column: 1; grid-row: 1; }
  .admin-table .c-thumb .thumb { width: 100%; }

  .admin-table .c-title {
    grid-column: 2; grid-row: 1;
    max-width: none;
    font-family: var(--font-display);
    font-size: 1.02rem; line-height: 1.2;
    text-wrap: balance;
  }

  /* labelled meta rows, full width under the header */
  .admin-table .c-meta {
    grid-column: 1 / -1;
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--s2);
    padding-block: 0.5em;
    border-top: 1px solid var(--line);
  }
  .admin-table .c-meta:nth-of-type(3) { margin-top: var(--s2); }
  .admin-table .c-meta::before {
    display: block;
    content: attr(data-label);
    font-family: var(--font-mono); font-size: 0.62rem;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--cream-soft);
  }

  .admin-table .c-actions {
    grid-column: 1 / -1;
    padding-top: var(--s2);
    border-top: 1px solid var(--line-gold);
    margin-top: 0.4rem;
  }
  .admin-table .admin-actions .btn { flex: 1 1 auto; justify-content: center; }
}
.btn--sm { padding: 0.5em 0.9em; font-size: 0.68rem; }
.btn--danger { color: #C87F72; border-color: #5A2E25; }
.btn--danger:hover { background: var(--sold); color: var(--paper); border-color: var(--sold); }
/* armed = one more click actually deletes; make that unmistakable */
.btn--danger.is-armed {
  background: var(--sold); color: var(--paper); border-color: var(--sold);
  animation: armed-pulse 1s ease-in-out infinite;
}
@keyframes armed-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.72; } }
@media (prefers-reduced-motion: reduce) { .btn--danger.is-armed { animation: none; } }
.admin-form { display: grid; gap: var(--s3); grid-template-columns: repeat(2, minmax(0,1fr)); }
.admin-form .span-2 { grid-column: 1 / -1; }
@media (max-width: 720px) { .admin-form { grid-template-columns: 1fr; } }
.upload-previews { display: flex; gap: var(--s2); flex-wrap: wrap; }
.upload-previews figure { width: 4.5rem; position: relative; }
.upload-previews img { aspect-ratio: 3/4; object-fit: cover; border: 1px solid var(--line-gold); width: 100%; }
.upload-previews button {
  position: absolute; top: -0.5rem; right: -0.5rem;
  width: 1.4rem; height: 1.4rem; border-radius: 50%;
  background: var(--sold); color: var(--paper); border: 0; cursor: pointer;
  font-size: 0.7rem; line-height: 1;
}
/* "Keep me signed in" on the admin login */
.remember-row {
  display: flex; align-items: center; gap: 0.7em;
  cursor: pointer; color: var(--cream); font-size: var(--text-small);
}
.remember-row input { width: auto; accent-color: var(--accent); }

/* ---- Bulk add + draft review queue ---- */
.bulk-bar { margin-top: var(--s3); }
.bulk-progress {
  height: 3px; background: var(--line); overflow: hidden; margin-bottom: var(--s2);
}
.bulk-progress span { display: block; height: 100%; width: 0; background: var(--accent); transition: width 0.3s var(--ease); }
.bulk-log {
  list-style: none; padding: 0; margin-top: var(--s4);
  max-height: 22rem; overflow-y: auto;
  font-family: var(--font-mono); font-size: 0.72rem; line-height: 1.9;
  color: var(--cream-soft);
  border-top: 1px solid var(--line);
}
.bulk-log li { padding-block: 0.15em; border-bottom: 1px solid var(--line); }
.bulk-log .is-ok { color: var(--accent); }
.bulk-log .is-err { color: #D98A7C; }

.queue-tools {
  display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
  padding-block: var(--s3); border-block: 1px solid var(--line-gold);
  margin-bottom: var(--s3);
}
.queue-tools .mono { display: flex; align-items: center; gap: 0.5em; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--cream-soft); }
.q-bulk-price, .q-bulk-tier {
  background: var(--vault-2); border: 1px solid var(--line-gold); color: var(--cream);
  padding: 0.55em 0.8em; font-size: 16px; max-width: 12rem;
}

.queue-list { display: grid; gap: var(--s2); }
.q-row {
  display: grid;
  /* the photo is the fastest way to recognise a card — give it room */
  grid-template-columns: auto 7rem minmax(0, 1fr) auto;
  gap: var(--s3); align-items: center;
  border: 1px solid var(--line); padding: var(--s3) var(--s2);
}
.q-row:hover { border-color: var(--line-gold); }
.q-thumb img {
  width: 100%; aspect-ratio: 3/4; object-fit: cover;
  border: 1px solid var(--line-gold); border-radius: 2px;
  background: var(--vault-2);
}

/* any admin photo can be opened full size */
img.is-zoomable { cursor: zoom-in; transition: outline-color 0.2s var(--ease); outline: 1px solid transparent; }
img.is-zoomable:hover { outline-color: var(--accent); }
.q-title {
  width: 100%; background: transparent; border: 0; border-bottom: 1px solid var(--line);
  color: var(--cream); font-family: var(--font-display); font-size: 1.02rem; padding: 0.25em 0;
}
.q-title:focus { outline: none; border-bottom-color: var(--accent); }
.q-meta { color: var(--cream-soft); margin-top: 0.3rem; }
.q-psa { display: flex; gap: var(--s2); margin-top: 0.35rem; font-family: var(--font-mono); font-size: 0.68rem; }
.q-set { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.q-price, .q-tier {
  background: var(--vault-2); border: 1px solid var(--line-gold); color: var(--cream);
  padding: 0.5em 0.7em; font-size: 16px; width: 7.5rem;
}
@media (max-width: 760px) {
  .q-row { grid-template-columns: auto 5.5rem minmax(0, 1fr); }
  .q-set { grid-column: 1 / -1; }
  .q-price, .q-tier { flex: 1 1 6rem; width: auto; }
}

/* PSA lookup links in the card editor */
.psa-links { display: flex; gap: var(--s2); flex-wrap: wrap; }
.psa-links .btn::after { content: " ↗"; }
.psa-links .btn.is-off {
  opacity: 0.35; pointer-events: none; cursor: default;
}

/* AI assist row in the card editor */
.ai-row {
  margin-top: var(--s3);
  padding-top: var(--s3);
  border-top: 1px dashed var(--line-gold);
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
}
.ai-status {
  flex: 1 1 16rem;
  font-size: var(--text-small);
  color: var(--cream-soft);
  margin: 0;
}
.ai-status.is-ok { color: var(--accent); }
.ai-status.is-err { color: #D98A7C; }
/* brief flash on fields the reader filled, so it's obvious what changed */
@keyframes ai-filled {
  from { border-color: var(--accent); background: color-mix(in oklab, var(--accent) 14%, var(--vault-2)); }
  to   { border-color: var(--line-gold); background: var(--vault-2); }
}
.ai-filled { animation: ai-filled 1.6s var(--ease); }
@media (prefers-reduced-motion: reduce) { .ai-filled { animation: none; } }

/* Status markers differ by FILL as well as colour, so they stay
   readable side by side and don't depend on colour vision.
   available = solid gold · sold = solid oxblood · hidden = hollow */
.status-dot {
  display: inline-block; width: 0.55rem; height: 0.55rem;
  border-radius: 50%; margin-right: 0.55em;
  vertical-align: 0.02em; box-sizing: border-box;
}
.status-dot--available { background: #6FA867; box-shadow: 0 0 0 2px rgba(111, 168, 103, 0.18); }
.status-dot--sold { background: var(--sold); box-shadow: 0 0 0 2px rgba(140, 59, 46, 0.2); }
.status-dot--hidden { background: transparent; border: 1.5px solid var(--cream-soft); opacity: 0.7; }

/* ------------------------------------------------------------
   19 · 404
   ------------------------------------------------------------ */
.err-page {
  min-height: 100svh; display: grid; place-content: center;
  text-align: center; gap: var(--s3); padding: var(--s3);
}
.err-page .mono-big { font-family: var(--font-mono); color: var(--accent); letter-spacing: 0.3em; }

/* ------------------------------------------------------------
   14 · CART — header link, cart page, summary
   The cart holds one-of-one cards, so there are no quantity
   steppers anywhere: a row is either in the cart or it isn't.
   ------------------------------------------------------------ */
.header-inner { justify-content: flex-start; }
.header-inner > .wordmark { margin-right: auto; }

.cart-link {
  color: var(--cream); text-decoration: none;
  font-size: var(--text-small); letter-spacing: 0.04em;
  display: inline-flex; align-items: center; gap: 0.5em;
  padding-block: 0.4em; position: relative; white-space: nowrap;
}
.cart-link::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.25s var(--ease);
}
.cart-link:hover { text-decoration: none; }
.cart-link:hover::after, .cart-link[aria-current="page"]::after { transform: scaleX(1); }
.cart-link[aria-current="page"] { color: var(--accent); }
.cart-count {
  font-family: var(--font-mono); font-size: 0.62rem; line-height: 1;
  min-width: 1.6em; padding: 0.38em 0.4em 0.32em;
  display: inline-grid; place-items: center;
  background: var(--accent); color: var(--accent-ink);
  border-radius: 999px; font-variant-numeric: tabular-nums;
}

/* --- card page: the two buy actions --------------------------- */
.buy-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-block: var(--s3) var(--s2); }
.buy-row .btn { flex: 1 1 12rem; }
.cart-state {
  font-family: var(--font-mono); font-size: 0.72rem;
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--accent); margin-bottom: var(--s2);
}
.cart-state a { color: var(--accent); }

/* --- cart page ------------------------------------------------ */
.cart-grid {
  display: grid; align-items: start;
  grid-template-columns: minmax(0, 1fr) 21rem;
  gap: var(--s5) var(--s5);
}
.cart-grid > .cart-empty { grid-column: 1 / -1; }
@media (max-width: 900px) { .cart-grid { grid-template-columns: 1fr; gap: var(--s4); } }

.cart-list h1 { font-size: var(--text-h2); margin-block: var(--s2) 0; }
.cart-rows { list-style: none; margin: var(--s4) 0 0; padding: 0; border-top: 1px solid var(--line); }
.cart-row {
  display: grid; gap: var(--s3); align-items: center;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto auto;
  padding-block: var(--s3); border-bottom: 1px solid var(--line);
}
.cart-row-img { display: block; line-height: 0; }
.cart-row-img img { width: 100%; height: auto; border: 1px solid var(--line); }
.cart-row-no { font-size: 0.62rem; letter-spacing: 0.14em; color: var(--cream-soft); margin: 0 0 0.3em; }
.cart-row-title { color: var(--cream); text-decoration: none; font-size: 1.05rem; line-height: 1.3; }
.cart-row-title:hover { color: var(--accent); text-decoration: none; }
.cart-row-price { font-family: var(--font-display); font-size: 1.15rem; font-variant-numeric: tabular-nums; margin: 0; }
.cart-row-remove {
  background: none; border: 0; cursor: pointer; padding: 0.6em 0.2em;
  font-family: var(--font-mono); font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--cream-soft);
}
.cart-row-remove:hover { color: var(--accent); }
.cart-row.is-sold .cart-row-img, .cart-row.is-sold .cart-row-title { opacity: 0.45; }
.cart-row-gone { color: var(--accent); font-size: 0.8rem; margin: 0.35em 0 0; }

.cart-summary {
  border: 1px solid var(--line-gold); background: var(--vault-2);
  padding: var(--s4) var(--s3);
  position: sticky; top: calc(var(--header-h) + var(--s3));
}
.cart-summary-h {
  font-size: 0.72rem; font-family: var(--font-mono); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--cream-soft); margin: 0;
}
.cart-totals { margin: var(--s3) 0 var(--s2); }
.cart-totals > div { display: flex; justify-content: space-between; gap: var(--s2); padding-block: 0.55em; border-bottom: 1px solid var(--line); }
.cart-totals dt { color: var(--cream-soft); font-size: 0.9rem; }
.cart-totals dd { margin: 0; font-variant-numeric: tabular-nums; }
.cart-totals .is-total { border-bottom: 0; padding-top: var(--s2); align-items: baseline; }
.cart-totals .is-total dt { color: var(--cream); }
.cart-totals .is-total dd { font-family: var(--font-display); font-size: 1.5rem; color: var(--accent); }
.cart-ship-note { font-size: 0.82rem; color: var(--cream-soft); margin-bottom: var(--s3); }
.cart-checkout { width: 100%; }
.cart-empty { max-width: 42rem; padding-block: var(--s4) var(--s6); }
.cart-empty h1 { font-size: var(--text-h2); margin-block: var(--s2) var(--s3); }
/* the base .img-slot is absolutely positioned (it fills a card tile);
   inside a cart row it has to sit in its own cell instead, or it covers
   the row and swallows clicks on Remove */
.img-slot--tiny {
  position: static; inset: auto;
  min-height: 4.5rem; font-size: 0.62rem;
  display: grid; place-items: center;
  border: 1px solid var(--line);
}
.img-slot--tiny::before { font-size: 0.8rem; }

/* cart rows on a phone: the title needs the full width, so price and
   Remove drop to their own line under it rather than squeezing it */
@media (max-width: 640px) {
  .cart-row {
    grid-template-columns: 5.5rem minmax(0, 1fr);
    grid-template-areas: "img body" "img meta";
    align-items: start; row-gap: var(--s2);
  }
  .cart-row-img { grid-area: img; }
  .cart-row-body { grid-area: body; }
  .cart-row-price { grid-area: meta; justify-self: start; align-self: center; }
  .cart-row-remove { grid-area: meta; justify-self: end; padding-block: 0.2em; }
  .cart-summary { position: static; }
}

/* The homepage header floats over the door plate, which is lit metal —
   without this the nav sits at ~3:1 against the brightest part of it.
   A gradient behind the header strip only; the plate below is untouched. */
.site-header:not(.site-header--solid)::before {
  content: ""; position: absolute; inset: 0 0 auto 0; z-index: -1;
  height: calc(var(--header-h) + 2.5rem); pointer-events: none;
  background: linear-gradient(180deg,
    rgba(16, 15, 13, 0.80) 0%,
    rgba(16, 15, 13, 0.62) 40%,
    rgba(16, 15, 13, 0.28) 72%,
    rgba(16, 15, 13, 0) 100%);
}

/* ------------------------------------------------------------
   15 · TOUCH TARGETS
   The 44px floor applies to fingers, not mice — scoping to a
   coarse pointer buys the height with padding and leaves the
   desktop proportions exactly as designed.
   ------------------------------------------------------------ */
@media (pointer: coarse) {
  .cart-link { padding-block: 0.8rem; padding-inline: 0.35rem; }
  .nav-toggle { padding: 0.95em 1.1em; }
  .cart-row-remove { padding-block: 1.25em; }
  .btn--hairline { padding-block: 0.85em; }
  .wordmark { padding-block: 0.4rem; }
  .site-footer ul a { display: inline-block; padding-block: 0.78em; }
  .footer-legal a { display: inline-block; padding-block: 1.1em; }
  .detail-thumbs button { min-height: 44px; }
  main > nav[aria-label="Breadcrumb"] a { display: inline-block; padding-block: 0.9em; }
}
