/* Reikan — dark store. Foil lives ONLY on the language-tile edges;
   everything else near-monochrome. */

* { box-sizing: border-box; margin: 0; }

html { scroll-padding-top: 4.5rem; overflow-x: clip; }

body {
  background: var(--void);
  color: var(--ghost);
  font-family: var(--font-body);
  font-weight: 380;
  font-size: var(--text-body);
  line-height: 1.65;
  /* `clip`, never `hidden`. `overflow-x: hidden` forces overflow-y to
     compute to `auto`, which makes <body> a scroll container and silently
     kills `position: sticky` on every child — the store header and the
     chip bar both scrolled away on a 13,000px page. `clip` contains the
     same horizontal overflow without creating a scroll container. */
  overflow-x: clip;
}

.atmosphere {
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(64vw 46vh at 78% -8%, rgba(124, 108, 255, 0.13), transparent 62%),
    radial-gradient(50vw 40vh at 6% 30%, rgba(124, 108, 255, 0.05), transparent 60%),
    var(--void);
}
.atmosphere::after {
  content: ""; position: absolute; inset: 0; opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

.wrap { max-width: 72rem; margin: 0 auto; padding: 0 clamp(1.1rem, 4vw, 2rem); }

/* ---------- skip link ---------- */
.skip-link {
  position: absolute; left: -200vw; top: 0; z-index: 20;
  background: var(--psychic); color: var(--void);
  font-family: var(--font-mono); font-weight: 700; font-size: 0.8rem;
  padding: 0.8rem 1.2rem; text-decoration: none;
}
.skip-link:focus { left: 0; }

/* ---------- editorial hardware ---------- */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--dim);
}
.rule { border: 0; border-top: 1px solid var(--hairline); }
section { padding: var(--s12) 0 var(--s8); }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s2); margin-bottom: var(--s6);
  padding-top: var(--s3); border-top: 1px solid var(--hairline);
  flex-wrap: wrap;
}
@media (max-width: 640px) {
  section { padding: var(--s6) 0 var(--s4); }
  .section-head { margin-bottom: var(--s4); }
}
h2 {
  font-family: var(--font-display);
  font-weight: 700; font-size: clamp(1.5rem, 1.2rem + 1.6vw, 2.3rem);
  letter-spacing: 0.01em; text-wrap: balance;
}

/* ---------- store chrome ---------- */
.announce {
  display: grid; align-content: center; min-height: 44px; background: var(--psychic); color: var(--void);
  font-family: var(--font-mono); font-weight: 700; font-size: 0.72rem;
  letter-spacing: 0.18em; text-transform: uppercase;
  text-align: center; padding: 0.5rem 1rem;
  text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.announce:hover { background: var(--psychic-bright); }
@media (max-width: 480px) { .announce { letter-spacing: 0.06em; font-size: 0.7rem; } }
.store-head {
  position: sticky; top: 0; z-index: 10;
  border-bottom: 1px solid var(--hairline);
  background: rgba(10, 10, 15, 0.82);
}
@supports (backdrop-filter: blur(8px)) {
  .store-head { backdrop-filter: blur(8px); background: rgba(10, 10, 15, 0.72); }
}
.head-inner {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  height: 3.9rem;
}
.head-logo {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.35rem; letter-spacing: 0.05em; text-align: center;
}
.head-logo .jp { font-family: "Reikan JP", sans-serif; color: var(--psychic); margin-left: 0.4em; font-size: 0.8em; }
.head-actions { justify-self: end; display: flex; align-items: center; gap: 0.15rem; }
.head-discord { color: var(--ghost); padding: 0.5rem; display: grid; }
.head-discord:hover { color: var(--psychic); }

.pop { position: relative; }
.pop summary { list-style: none; cursor: pointer; padding: 0.75rem; display: grid; place-items: center; min-width: 44px; min-height: 44px; color: var(--ghost); position: relative; }
.pop summary::-webkit-details-marker { display: none; }
.pop summary:hover { color: var(--psychic); }
.badge {
  position: absolute; top: 0.1rem; right: 0;
  background: var(--psychic); color: var(--void);
  font-family: var(--font-mono); font-size: 0.58rem; font-weight: 700;
  min-width: 1rem; text-align: center; border-radius: 999px; padding: 0.05rem 0.2rem;
}
.pop-panel {
  position: absolute; right: 0; top: calc(100% + 0.6rem);
  width: 15rem; padding: 0.8rem 1rem;
  background: var(--ink); border: 1px solid var(--hairline); border-radius: 8px;
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.7);
  font-size: 0.85rem; color: var(--dim);
}
.pop-panel a { color: var(--psychic); text-decoration: none; }


.menu { position: relative; justify-self: start; }
.menu summary { list-style: none; cursor: pointer; padding: 1rem 1.3rem 1rem 0.35rem; margin-left: -0.35rem; display: grid; align-content: center; min-height: 44px; }
.menu summary::-webkit-details-marker { display: none; }
.bars, .bars::before, .bars::after {
  content: ""; display: block; width: 20px; height: 2px;
  background: var(--ghost); border-radius: 1px;
}
.bars { position: relative; }
.bars::before { position: absolute; top: -6px; }
.bars::after { position: absolute; top: 6px; }
.menu-panel {
  position: absolute; left: 0; top: calc(100% + 0.6rem);
  display: grid; min-width: 12rem;
  background: var(--ink); border: 1px solid var(--hairline); border-radius: 8px;
  padding: 0.4rem; box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.7);
}
.menu-panel a {
  font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ghost); text-decoration: none;
  padding: 0.85rem 0.8rem; border-radius: 5px; min-height: 44px; display: grid; align-content: center;
}
.menu-panel a:hover { background: rgba(124, 108, 255, 0.12); color: var(--psychic); }
.menu-socials {
  display: flex; flex-wrap: wrap; gap: 0.1rem;
  border-top: 1px solid var(--hairline); margin-top: 0.35rem; padding-top: 0.45rem;
}
.menu-socials a { color: var(--dim); padding: 0.7rem; min-width: 44px; min-height: 44px; display: grid; place-items: center; }
.menu-socials a:hover { background: none; color: var(--ghost); }
.w-mark {
  width: 18px; height: 18px; border: 1.6px solid currentColor; border-radius: 5px;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: 11px; line-height: 1;
}
.signup-line { color: var(--dim); max-width: 44ch; margin-bottom: var(--s3); }

.btn {
  display: inline-block; padding: 0.62rem 1.35rem; border-radius: 4px;
  color: var(--ghost);
  font-family: var(--font-display); font-weight: 700; font-size: 0.92rem;
  letter-spacing: 0.03em; text-decoration: none;
}
.btn-accent { background: var(--psychic); color: var(--void); }
.btn-accent:hover { background: var(--psychic-bright); }
.btn-ghost { border: 1px solid var(--edge); color: var(--ghost); }
.btn-ghost:hover { border-color: var(--psychic); }
a:focus-visible, button:focus-visible, summary:focus-visible { outline: 2px solid var(--psychic); outline-offset: 3px; }

/* ---------- CTA strip ---------- */
.cta-strip {
  display: flex; gap: var(--s2); justify-content: center; flex-wrap: wrap;
  padding: var(--s3) 1rem;
  border-bottom: 1px solid var(--hairline);
}

/* ---------- hero: positioning + the signature card ---------- */
.hero {
  display: grid; grid-template-columns: 1.2fr 0.8fr; align-items: center;
  gap: var(--s6); padding: var(--s6) 0 var(--s4); /* .hero outranks the bare `section` paddings at any width */
}
.hero-copy { display: grid; gap: var(--s2); justify-items: start; }
.display {
  font-size: var(--text-display); font-weight: 700; line-height: 1.02;
  letter-spacing: -0.01em; text-wrap: balance;
}
.display .glint {
  background: linear-gradient(100deg, var(--ghost) 38%, var(--glint-tint) 50%, var(--ghost) 62%);
  background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hero-sub { color: var(--dim); font-size: var(--text-sub); max-width: 44ch; text-wrap: balance; }
.hero .cta-strip { border: 0; padding: 0.4rem 0 0; justify-content: start; }
@media (max-width: 880px) {
  .hero { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: var(--s3); }
  .hero-copy { justify-items: center; }
  .hero .cta-strip { justify-content: center; }
  .display { font-size: clamp(2rem, 1.5rem + 3.4vw, 2.8rem); }
}

/* ---------- story ---------- */
.story-block { max-width: 58ch; font-size: var(--text-sub); line-height: 1.7; }
.story-block .sig {
  display: block; margin-top: var(--s3);
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--dim);
}
.story-block a { color: var(--psychic); text-decoration: none; }
.story-block a:hover { text-decoration: underline; }

/* ---------- buylist ---------- */
.buylist-rates {
  display: flex; gap: var(--s8); flex-wrap: wrap;
  margin: var(--s4) 0;
}
.rate { display: grid; gap: 0.3rem; }
.rate .fig {
  font-family: var(--font-mono); font-weight: 700; font-size: var(--text-rate);
  color: var(--jade); letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
}
.rate .lbl { font-family: var(--font-mono); font-size: var(--text-label); letter-spacing: 0.24em; color: var(--dim); text-transform: uppercase; }
.buylist p { max-width: 52ch; color: var(--dim); margin-bottom: var(--s3); }

/* ---------- process ---------- */
.process-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s3); counter-reset: step; }
.step { border-top: 1px solid var(--hairline); padding-top: var(--s2); display: grid; gap: 0.4rem; }
.step .num { font-family: var(--font-mono); font-size: var(--text-label); letter-spacing: 0.24em; color: var(--psychic); }
.step h3 { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; }
.step p { color: var(--dim); font-size: 0.92rem; }

/* ---------- footer ---------- */
footer {
  border-top: 1px solid var(--hairline); position: relative; overflow: hidden;
  padding: var(--s8) 0; margin-top: var(--s8);
}
.foot-grid {
  display: flex; justify-content: center; align-items: center;
  column-gap: var(--s4); row-gap: var(--s2); flex-wrap: wrap;
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dim);
}
.foot-grid a { color: var(--dim); text-decoration: none; display: inline-grid; align-content: center; min-height: 44px; padding: 0 0.25rem; }
.foot-grid > span { display: inline-grid; align-content: center; min-height: 44px; }
.foot-grid a:hover { color: var(--ghost); }
.watermark {
  position: absolute; right: -0.05em; bottom: -0.35em; z-index: -1;
  font-family: "Reikan JP", sans-serif; font-weight: 700;
  font-size: clamp(6rem, 18vw, 13rem); line-height: 1;
  color: rgba(124, 108, 255, 0.05); user-select: none;
}

/* ---------- motion: ONE load reveal + the card interaction (spec §10) ---------- */
.reveal { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  /* the one orchestrated reveal — load-only, pure CSS, ends visible even
     with JS off (animation-fill both). No scroll triggers anywhere. */
  .reveal { animation: rise 0.48s cubic-bezier(0.2, 0.7, 0.2, 1) 0.12s both; }
  .hero .reveal:nth-child(2) { animation-delay: 0.16s; }
  .hero .reveal:nth-child(3) { animation-delay: 0.2s; }
  .hero .reveal:nth-child(4) { animation-delay: 0.26s; }
  .hero-stage.reveal { animation-delay: 0.26s; }
  @keyframes rise {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: none; }
  }
  .holo { transition: transform 0.18s ease-out; }
  .holo.settling {
    transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1),
      --mx 0.3s ease, --my 0.3s ease, --mxn 0.3s ease, --myn 0.3s ease;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .store-head { backdrop-filter: none; background: rgba(10, 10, 15, 0.97); }
}

/* ---------- buylist offer estimator (client-side, §4 band) ---------- */
.js-only { display: none; }
.js .js-only { display: block; }
.estimator {
  margin: var(--s3) 0; padding: var(--s3);
  border: 1px solid var(--hairline); border-radius: 12px;
  background: linear-gradient(165deg, var(--panel-mid), var(--panel-lo));
  max-width: 30rem;
}
.est-label { display: block; color: var(--dim); font-size: var(--text-label); margin-bottom: var(--s1); }
.est-row {
  display: flex; align-items: center; gap: 0.5rem;
  border: 1px solid var(--edge); border-radius: 8px;
  background: var(--void); padding: 0 var(--s2); min-height: 48px;
}
.est-row:focus-within { border-color: var(--psychic); }
.est-prefix { color: var(--dim); font-family: var(--font-mono); font-size: 0.85rem; }
.est-row input {
  flex: 1; min-width: 0; background: none; border: 0; outline: 0;
  color: var(--ghost); font-family: var(--font-mono); font-size: 1.05rem;
  padding: 0.6rem 0;
}
.est-row input::placeholder { color: var(--dim); opacity: 1; }
.est-out { display: grid; gap: 0.35rem; margin-top: var(--s2); }
.est-line { display: flex; justify-content: space-between; align-items: baseline; }
.est-line .lbl { color: var(--dim); font-size: var(--text-label); }
.est-line .fig { color: var(--jade); font-family: var(--font-mono); font-size: 1.05rem; }

/* ---------- condition-scale disclosure ---------- */
.cond { margin-top: var(--s3); }
.cond summary {
  list-style: none; cursor: pointer; display: inline-grid; align-content: center;
  min-height: 44px; padding-right: 1.2rem; position: relative;
}
.cond summary::-webkit-details-marker { display: none; }
.cond summary::after {
  content: ""; position: absolute; right: 0; top: 50%;
  width: 7px; height: 7px; margin-top: -5px;
  border-right: 1.5px solid var(--dim); border-bottom: 1.5px solid var(--dim);
  transform: rotate(45deg);
}
@media (prefers-reduced-motion: no-preference) {
  .cond summary::after { transition: transform 0.15s ease; }
}
.cond[open] summary::after { transform: rotate(225deg); margin-top: -2px; }
.cond summary:hover .eyebrow { color: var(--ghost); }
.cond-list { display: grid; gap: 0.4rem; padding: var(--s2) 0 0; max-width: 34rem; }
.cond-list div { display: flex; gap: var(--s2); align-items: baseline; }
.cond-list dt {
  font-family: var(--font-mono); color: var(--jade); font-size: 0.85rem;
  min-width: 2.2rem;
}
.cond-list dd { color: var(--dim); font-size: 0.9rem; margin: 0; }

/* ---------- guide pages ---------- */
.guide { padding-block: var(--s6) var(--s8); max-width: 46rem; }  /* block only — .wrap owns inline padding */
.guide-title { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem); text-wrap: balance; }
.guide h2 { margin-top: var(--s6); margin-bottom: var(--s2); }
.guide p { color: var(--dim); max-width: 60ch; }
.guide p a:not(.btn) { color: var(--psychic); }  /* .btn keeps its own fg/bg pair */
.guide-scale div { align-items: baseline; }
.guide-scale dd { max-width: 52ch; }
.guide-cta { margin-top: var(--s6); }
.head-logo { text-decoration: none; color: var(--ghost); }
.cond-more { margin-top: var(--s2); }
.cond-more a { color: var(--psychic); font-size: 0.9rem; }

/* ---------- guide index ---------- */
.guide-index { display: grid; gap: var(--s2); margin-top: var(--s3); }
.guide-card {
  display: grid; gap: 0.4rem; padding: var(--s3);
  border: 1px solid var(--hairline); border-radius: 12px;
  background: linear-gradient(165deg, var(--panel-mid), var(--panel-lo));
  text-decoration: none; color: var(--ghost);
}
.guide-card:hover { border-color: var(--psychic); }
.guide-card h2 { margin: 0; font-size: 1.15rem; }
.guide-card p { color: var(--dim); font-size: 0.92rem; margin: 0; }

/* ---------- G-11 polish: hub cards borrow the tile foil edge ---------- */
.guide-card { position: relative; }
.guide-card::before {
  content: ""; position: absolute; inset: 0; border-radius: 12px; padding: 1px;
  background: var(--foil);
  -webkit-mask: linear-gradient(white 0 0) content-box, linear-gradient(white 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
.guide-card:hover::before { opacity: 0.35; }

/* copy-link button on the sell estimator */
.est-copy {
  margin-top: var(--s2); display: none; cursor: pointer;
  background: none; border: 1px solid var(--edge); border-radius: 4px;
  color: var(--ghost); font-family: var(--font-mono); font-size: 0.78rem;
  padding: 0.6rem 1rem; min-height: 44px;
}
.est-copy:hover { border-color: var(--psychic); }
.js .est-copy.ready { display: inline-block; }

/* G-12: icon copy button (homepage) + keyboard foil parity */
.est-copy-icon { display: none; place-items: center; min-width: 44px; padding: 0.6rem; }
.js .est-copy-icon.ready { display: inline-grid; }
.est-copy-icon.copied { border-color: var(--jade); color: var(--jade); }
.guide-card:focus-visible::before { opacity: 0.35; }

/* ---------- wear visualizer (condition guide) — schematic card, no real art ---------- */
.wear-demo { margin: var(--s3) 0 var(--s2); display: grid; gap: var(--s2); justify-items: start; }
.wear-card {
  --wear: 0; /* 0=NM .. 4=DMG, JS-driven */
  position: relative; width: min(230px, 60vw); aspect-ratio: 63 / 88;
  border-radius: 10px; overflow: hidden;
  border: 1px solid var(--slot-line);
  background: linear-gradient(155deg, var(--panel-hi), var(--panel-lo) 70%);
}
.wear-face {
  position: absolute; inset: 12% 10% 30%;
  border-radius: 6px;
  background: radial-gradient(80% 90% at 30% 20%, rgba(124, 108, 255, 0.4), transparent 65%),
              linear-gradient(160deg, var(--panel-art-b), var(--panel-flat));
}
/* wear layers, all driven by --wear (0..4) via opacity steps */
.wear-edges {
  position: absolute; inset: 0; border-radius: 10px; pointer-events: none;
  box-shadow: inset 0 0 0 3px rgba(245, 245, 242, 0.55);
  filter: blur(2px);
  opacity: calc(var(--wear, 0) * 0.22);
}
.wear-scratches {
  position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(64deg, transparent 0 14px, rgba(245, 245, 242, 0.16) 14px 15px, transparent 15px 34px),
              repeating-linear-gradient(-38deg, transparent 0 22px, rgba(245, 245, 242, 0.10) 22px 23px, transparent 23px 51px);
  opacity: calc(max(0, var(--wear, 0) - 1) * 0.3);
}
.wear-corners { position: absolute; inset: 0; pointer-events: none; opacity: calc(max(0, var(--wear, 0) - 0.5) * 0.28); }
.wear-corners::before, .wear-corners::after {
  content: ""; position: absolute; width: 16px; height: 16px;
  background: radial-gradient(circle at 0 0, rgba(245, 245, 242, 0.8), transparent 70%);
}
.wear-corners::before { top: -2px; left: -2px; }
.wear-corners::after { bottom: -2px; right: -2px; transform: rotate(180deg); }
.wear-crease {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 46%, rgba(245, 245, 242, 0.35) 49%, rgba(10, 10, 15, 0.4) 50%, transparent 54%);
  opacity: calc(max(0, var(--wear, 0) - 2) * 0.45);
}
.wear-stain {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(45% 35% at 70% 78%, rgba(138, 138, 150, 0.5), transparent 70%);
  opacity: calc(max(0, var(--wear, 0) - 3) * 0.8);
}
.wear-ctl { display: flex; align-items: center; gap: var(--s2); width: min(230px, 60vw); }
.wear-ctl input[type="range"] { flex: 1; accent-color: var(--psychic); min-height: 44px; }
.wear-ctl output { color: var(--jade); font-size: 0.95rem; min-width: 3ch; }

/* ---------- homepage featured: rarest cards actually in stock ---------- */
.featured { margin-bottom: var(--s6); }
.feat-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s2); padding-bottom: var(--s2);
}
.feat-head h3 {
  font-family: var(--font-display); font-weight: 700; margin: 0;
  font-size: clamp(1.15rem, 1rem + 0.8vw, 1.5rem); color: var(--ghost);
}

/* ---------- homepage shelves: real scans from the binder ---------- */
.shelf { margin-bottom: var(--s4); }
.shelf-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2);
  text-decoration: none; padding-bottom: var(--s1);
}
.shelf-head h3 { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; margin: 0; color: var(--ghost); }
.shelf-head:hover h3 { color: var(--psychic); }

/* ================= THE GLASS COUNTER (docs/design/OVERHAUL_SPEC.md) ================
   Money tier = big scans on abyss pedestals under a psychic spotlight with the
   pointer-driven holo stack. Browse tier = uniform 5:7 grids, placard captions.
   Foil whitelist: hero-tier holo layers, chase-tile ring, buylist underline.  */

/* ---------- catalog wrap: grid pages get the wide counter ---------- */
.guide.catalog { max-width: var(--wrap-wide); }

/* ---------- placard: THE caption idiom ---------- */
.placard {
  font: 500 var(--text-placard) / 1.4 var(--font-mono); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim); font-variant-numeric: tabular-nums;
}
.head-link { text-decoration: none; }
.head-link:hover { color: var(--ghost); }

/* ---------- card tile — standard grid tier (spec 7a) ---------- */
.tile {
  margin: 0; position: relative; display: grid; gap: 0.35rem; min-width: 0;
  align-content: start; scroll-margin-top: 5.5rem;
  content-visibility: auto; contain-intrinsic-size: auto 290px;
}
.tile .art {
  aspect-ratio: 63 / 88; border-radius: 6px; overflow: hidden; display: block;
  border: 1px solid var(--slot-line); background: var(--panel-flat); position: relative;
}
.tile .art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile-link { text-decoration: none; display: grid; gap: 0.35rem; min-width: 0; }
.tile-link:hover .t-name, .tile-link:focus-visible .t-name { color: var(--psychic); }
.t-name {
  font: 600 0.82rem / 1.25 var(--font-display); color: var(--ghost);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile figcaption { display: grid; gap: 0.15rem; min-width: 0; }
.qty {
  position: absolute; top: 0.35rem; right: 0.35rem; z-index: 2;
  font: 600 var(--text-micro) var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--ghost); background: rgba(7, 7, 11, 0.72);
  border: 1px solid var(--edge); border-radius: 4px; padding: 0.1rem 0.3rem;
}
/* cheap sheen — hover only, no blend modes, no transforms */
.tile .art::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 40%,
    color-mix(in srgb, var(--glint-tint) 22%, transparent) 50%, transparent 60%);
  background-size: 250% 100%; background-position: 120% 0;
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .tile:hover .art::after, .tile:focus-within .art::after {
    background-position: -30% 0; transition: background-position 0.55s ease;
  }
}
.tile:target { outline: 2px solid var(--psychic); outline-offset: 4px; border-radius: 8px; }

/* ---------- chase ring (spec 7b): marks money at grid distance ---------- */
.tile-chase .art { border-color: transparent; }
.tile-chase .art::before {
  content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit;
  padding: 1px; background: var(--foil); opacity: 0.5;
  -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
}

/* ---------- ghost tile (spec 7d): honest gaps, nothing pretends ---------- */
.tile-ghost .art, .art-ghost {
  display: grid; place-items: center; align-content: center; gap: 0.4rem;
  aspect-ratio: 63 / 88; border-radius: 6px; border: 1px solid var(--slot-line);
  background: radial-gradient(120% 90% at 50% 0%, var(--panel-art-a), var(--panel-lo));
}
.tile-ghost .art::after { content: none; }
.g-kanji {
  font: 700 2.4rem "Reikan JP", sans-serif;
  color: color-mix(in srgb, var(--psychic) 16%, transparent); line-height: 1;
}
.g-num {
  font: 500 var(--text-placard) var(--font-mono); color: var(--dim);
  letter-spacing: 0.14em; font-variant-numeric: tabular-nums;
}

/* ---------- hero tier: the holo stack (spec 7c) ---------- */
.holo {
  --mx: 50%; --my: 50%; --mxn: 50; --myn: 50;
  position: relative; display: block; border-radius: 10px; overflow: hidden;
  transform: perspective(900px)
    rotateX(calc((50 - var(--myn)) * 0.16deg))
    rotateY(calc((var(--mxn) - 50) * 0.20deg));
}
/* THE ART IS THE TRUTH. At rest the foil layers are fully off, so every
   card renders pixel-true to its scan (pinned by the colour-fidelity
   check in scripts/site_smoke.py). The holo is an INTERACTION — it wakes
   only under a real pointer, and touch devices never see it at all.
   (Operator, twice: cards read white. Measured: the dodge+glare stack
   lifted hero cards +14 with a violet cast. Not a look — a lie about
   the card.) */
.holo::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--holo-foil); background-size: 320% 320%;
  background-position: var(--mx) var(--my);
  mix-blend-mode: color-dodge;
  filter: brightness(0.7) contrast(1.7) saturate(0.6);
  opacity: 0; pointer-events: none;
}
.holo::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: radial-gradient(farthest-corner at var(--mx) var(--my),
    rgba(255, 255, 255, 0.45), transparent 70%);
  mix-blend-mode: overlay; opacity: 0; pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .holo:hover::before { opacity: 0.38; }
  .holo:hover::after { opacity: 0.24; }
  @media (prefers-reduced-motion: no-preference) {
    .holo::before, .holo::after { transition: opacity 0.22s ease; }
  }
}
@media (pointer: coarse) {
  .holo { --mx: 36%; --my: 24%; transform: none; }
  .holo::before, .holo::after { content: none; }
}

/* ---------- the stage: abyss pedestal + spotlight ---------- */
.stage {
  position: relative; padding: var(--s4); background: var(--abyss);
  border: 1px solid var(--hairline); border-radius: 12px;
}
.stage::before {
  content: ""; position: absolute; inset: -12%; z-index: 0;
  background: radial-gradient(closest-side, var(--spot), transparent 70%);
  pointer-events: none;
}
.stage > * { position: relative; z-index: 1; }

/* hero stage: the glass case beside the copy */
.hero-stage { margin: 0; display: grid; gap: var(--s2); justify-items: center; max-width: 380px; justify-self: center; }
.hero-stage .art { display: block; width: min(340px, 100%); }
.hero-stage img { width: 100%; height: auto; display: block; border-radius: 10px; }
.holo-link { text-decoration: none; }
@media (max-width: 880px) {
  .hero { grid-template-columns: 1fr; }
  .hero-stage { max-width: 320px; }
}

/* ---------- stat band (home S3) + stat row (hub mastheads) ---------- */
/* `padding: 0` here zeroed .wrap's own `padding: 0 clamp(...)`, so the
   stat band lost its gutter entirely and ran to the screen edge at
   390px. Vertical padding was already 0 from .wrap, so the rule only
   ever removed the horizontal gutter. Second `.wrap` shorthand
   collision in this file; tests/test_site_gates.py now bars them. */
.stat-section { padding-block: 0; }
.stat-band {
  display: grid; grid-template-columns: repeat(4, auto); justify-content: space-between;
  gap: var(--s2) var(--s4); padding: var(--s3) 0; margin-top: var(--s4);
  border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline);
}
@media (max-width: 560px) { .stat-band { grid-template-columns: repeat(2, 1fr); } }
.stat { display: grid; gap: 0.2rem; text-decoration: none; justify-items: start; }
.stat-n {
  font: 300 var(--text-stat) / 1 var(--font-display); color: var(--ghost);
  font-variant-numeric: tabular-nums;
}
a.stat:hover .stat-n { color: var(--psychic); }
.stat-l {
  font: 500 var(--text-label) var(--font-mono); letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--dim);
}
.stat-row { display: flex; gap: var(--s6); flex-wrap: wrap; margin: var(--s2) 0 var(--s4); }
.stat-row .stat { display: grid; }

/* ---------- chase rail (home S4 / hub rails, spec 7 rail) ---------- */
.rail {
  display: flex; gap: var(--s2); overflow-x: auto; scroll-snap-type: x mandatory;
  padding: var(--s2) 0 var(--s3); -webkit-overflow-scrolling: touch;
}
.rail .tile { flex: 0 0 var(--card-w-rail); scroll-snap-align: start; content-visibility: visible; contain-intrinsic-size: none; }
.featured { margin-bottom: var(--s8); }

/* ---------- set tile (spec 7e) ---------- */
.set-tile {
  position: relative; display: block; aspect-ratio: 4 / 5; border-radius: 10px;
  overflow: hidden; border: 1px solid var(--slot-line); text-decoration: none;
  content-visibility: auto; contain-intrinsic-size: auto 380px;
  background: var(--panel-flat);
}
.set-tile img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  object-position: 50% var(--crop, 14%);
}
.set-tile .art-ghost { position: absolute; inset: 0; aspect-ratio: auto; border: 0; border-radius: 0; }
.set-tile .scrim {
  position: absolute; inset: 0; display: grid; align-content: end; gap: 0.15rem;
  padding: var(--s2); background: var(--scrim);
}
.set-tile .placard { color: var(--placard-art); }
.set-tile h3, .set-tile h2 { font: 700 1.05rem / 1.2 var(--font-display); color: var(--ghost); margin: 0; }
.set-tile:hover h3, .set-tile:hover h2, .set-tile:focus-visible h3 { color: var(--psychic-bright); }
.set-door { aspect-ratio: 16 / 9; contain-intrinsic-size: auto 240px; }
.set-door h2 { font-size: 1.3rem; }
.door-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); margin: var(--s4) 0; }
@media (max-width: 720px) { .door-grid { grid-template-columns: 1fr; } }

/* set walls (hubs) + home set rows */
.set-wall {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(264px, 1fr));
  gap: var(--s2); margin: var(--s3) 0;
}
@media (max-width: 640px) {
  .set-wall { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .set-tile { contain-intrinsic-size: auto 240px; }
}
.set-row {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(150px, 1fr);
  gap: var(--s2); overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: var(--s2);
}
@media (min-width: 880px) { .set-row { grid-auto-columns: 1fr; grid-template-columns: repeat(6, 1fr); grid-auto-flow: row; overflow: visible; } }
.set-row .set-tile { scroll-snap-align: start; }
.game-row { margin-bottom: var(--s6); }
.shelf-head .placard { align-self: center; }

/* ---------- chip bar ---------- */
.chip-bar {
  position: sticky; top: 3.4rem; z-index: 5; background: var(--void);
  display: flex; gap: var(--s1); overflow-x: auto; padding: var(--s1) 0;
  margin: var(--s2) 0;
}
/* A chip group in a narrow column WRAPS rather than scrolling. `.chip-bar`
   is the sticky filter rail — it spans 72rem and a horizontal scroller is
   discoverable there. In a 356px column it is not: four set names need
   633px, so two options sit off-screen behind a scroller with no
   affordance, and a picker where half the options are invisible is worse
   than a tall one. Opt in; the sticky bars keep their behaviour. */
.chip-wrap {
  display: flex; flex-wrap: wrap; gap: var(--s1); margin: var(--s1) 0 0;
}
.chip {
  font: 500 var(--text-label) var(--font-mono); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim); text-decoration: none;
  padding: 0.45rem 0.7rem; border: 1px solid var(--edge); border-radius: 999px;
  white-space: nowrap; cursor: pointer; background: none;
  /* Measured at 31.4px before this floor — under the 44px touch minimum on
     every set page and the rare hub, not only on the buylist picker. */
  min-height: 2.75rem; display: inline-flex; align-items: center;
}
.chip:hover, .chip:focus-visible { color: var(--ghost); border-color: var(--dim); }
.chip[aria-pressed="true"], .chip.active { border-color: var(--psychic); color: var(--psychic); }
.rare-sec, section[id] { scroll-margin-top: 7rem; }

/* ---------- chase block on set pages ---------- */
.chase-block { margin: var(--s4) 0 var(--s6); }
.chase-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--s3) var(--s2); margin-top: var(--s2);
}
@media (max-width: 640px) { .chase-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } }

/* ---------- the counter (rare page glass case) ---------- */
.counter {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3);
  margin: var(--s4) 0;
}
@media (max-width: 720px) { .counter { grid-template-columns: repeat(2, 1fr); gap: var(--s2); } }
.counter .tile { content-visibility: visible; contain-intrinsic-size: none; }

/* ---------- grids: browse tier ---------- */
.card-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--s3) var(--s2); margin: var(--s4) 0;
}
@media (min-width: 880px) { .card-grid { grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); } }
.rare-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: var(--s2) var(--s1); }
@media (min-width: 880px) { .rare-grid { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); } }
.rare-grid .tile { contain-intrinsic-size: auto 200px; }

/* ---------- binder map index ---------- */
.all-sets { margin: var(--s4) 0; }
.all-sets summary {
  list-style: none; cursor: pointer; display: flex; gap: var(--s2);
  align-items: center; padding: var(--s2) 0; border-top: 1px solid var(--hairline);
  min-height: 44px;
}
.all-sets summary::-webkit-details-marker { display: none; }
.all-sets summary .mono { color: var(--jade); font-variant-numeric: tabular-nums; }
.idx-game { font: 700 1.05rem var(--font-display); margin: var(--s3) 0 var(--s1); }
.idx-wrap { margin-bottom: var(--s2); }
.idx-list { display: grid; }
@media (min-width: 880px) { .idx-wrap { column-count: 2; column-gap: var(--s6); } .idx-game { column-span: all; } }
.idx-row {
  display: flex; align-items: baseline; gap: 0.6rem; text-decoration: none;
  padding: 0.35rem 0; break-inside: avoid; min-height: 32px;
}
.idx-name { color: var(--ghost); font-size: 0.92rem; min-width: 0; }
.idx-row:hover .idx-name { color: var(--psychic); }
.idx-row::after { content: ""; order: 1; flex: 1; border-bottom: 1px dotted var(--slot-line); }
.idx-count { order: 2; color: var(--dim); font-size: 0.8rem; font-variant-numeric: tabular-nums; }

/* Load-bearing. Any author rule that sets `display` beats the browser's own
   [hidden] handling, so an element with a display rule needs an explicit
   [hidden] partner or setting the attribute does nothing at all. This has
   now bitten twice — .tile (the browse filter moved nothing) and .est-line
   (the estimator's empty rows stayed on screen with JS ON, not just off).
   tests/test_site_gates.py enforces the pairing so there is no third time. */
.tile[hidden], .set-tile[hidden], .idx-row[hidden],
.est-line[hidden] { display: none; }

/* ask for photos of the actual copy (U32). The page already discloses
   that most images are reference scans; this is the only way to close
   that gap when there is no price and no checkout. Quiet at rest so it
   reads as an affordance, not a shout across 113 tiles. */
.ask-photo {
  justify-self: start; font: 500 var(--text-label) / 1 var(--font-mono);
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  color: var(--dim); padding: 0.15rem 0; border-bottom: 1px solid transparent;
}
.ask-photo:hover, .ask-photo:focus-visible {
  color: var(--psychic-bright); border-bottom-color: currentColor;
}

/* nothing matched — say so where the cards were, not just in a counter */
.filter-empty {
  display: none; padding: var(--s6) 0; color: var(--dim);
  border-top: 1px solid var(--hairline); margin-top: var(--s2);
}
.filter-empty[data-on] { display: grid; gap: var(--s2); justify-items: start; }

/* ---------- tools slot: JS filter lands in reserved space (no CLS) ---------- */
.hub-tools { min-height: 0; }
.js .hub-tools { min-height: 3.6rem; }

/* ---------- CTA strip invariant (spec 7h) ---------- */
.cta-end { margin-top: var(--s8); padding-top: var(--s3); border-top: 1px solid var(--hairline); }

/* ---------- reduced motion: paint stays, motion dies ---------- */
@media (prefers-reduced-motion: reduce) {
  .reveal, .holo { animation: none !important; transition: none !important; }
  .holo { transform: none !important; --mx: 36%; --my: 24%; }
  .tile .art::after { transition: none; background-position: 120% 0; }
  html { scroll-behavior: auto; }
}

/* screen-reader live region + non-color copy confirmation */
.sr-live {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.est-copy-icon.copied::after { content: "\2713"; margin-left: 0.3rem; }

/* ---------- product page (PDP) ----------
   From the Claude Design handoff (docs/design/pdp-handoff/). The prototype
   used inline style="" throughout; CSP here is style-src 'self', so every
   one of those is a class. Values are carried across unchanged. */
.pdp {
  display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 1fr);
  gap: var(--s6); align-items: start; padding-block: var(--s4) var(--s6);
}
@media (max-width: 900px) { .pdp { grid-template-columns: 1fr; gap: var(--s4); } }

.pdp-art { display: flex; flex-direction: column; gap: var(--s2); }
.pdp-stage { margin: 0; display: grid; gap: var(--s3); justify-items: center; }
.pdp-stage .art, .pdp-stage .holo, .pdp-stage img { width: 100%; max-width: 480px; }
/* The ghost has to occupy the card slot, not shrink to its glyph. 58 rows
   have no scan and all 15 One Piece rows never will, so this IS the hero
   on those pages — a small box reads as a broken image, not a state. */
.pdp-stage .art-ghost {
  width: 100%; max-width: 480px; aspect-ratio: 63 / 88;
}
.pdp-stage .art-ghost .g-kanji { font-size: clamp(3rem, 8vw, 5rem); }
.pdp-scan-note { color: var(--dim); font-size: 0.88rem; max-width: 52ch; }

.pdp-head { display: flex; flex-direction: column; gap: var(--s2); padding-top: var(--s1); }
.pdp-head h1 { margin: 0; }

/* the printing chip — 745 of 782 rows carry a value the site never showed */
.pdp-printing { display: flex; gap: var(--s1); flex-wrap: wrap; align-items: center; }

.pdp-buy {
  border-top: 1px solid var(--hairline); margin-top: var(--s2);
  padding-top: var(--s3); display: flex; flex-direction: column; gap: var(--s2);
}
.pdp-price-row { display: flex; align-items: flex-end; gap: var(--s2); flex-wrap: wrap; }
.pdp-price {
  font: 700 2.4rem / 1 var(--font-mono); color: var(--ghost);
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
.pdp-price-note { padding-bottom: 0.35rem; }
.pdp-stock {
  font: 500 0.85rem var(--font-mono); color: var(--jade); letter-spacing: 0.14em;
  text-transform: uppercase; font-variant-numeric: tabular-nums; margin: 0;
}
.pdp-stock[data-out] { color: var(--dim); }
.pdp-cart { width: 100%; max-width: 24rem; min-height: 48px; border: 0; cursor: pointer; font-size: 1rem; }
.pdp-actions { display: flex; gap: var(--s1); flex-wrap: wrap; align-items: center; }
.pdp-actions .btn { min-height: 44px; display: inline-grid; align-content: center; }
/* the secondary path sits beside a button, so it reads as a quiet peer
   rather than a default browser link. `.guide` is on the selector because
   `.guide p a:not(.btn)` (0,2,2) outranks a bare `.pdp-actions > a` — the
   colour silently lost and only a rendered check caught it. */
.guide .pdp-actions > a:not(.btn) {
  font-size: 0.9rem; color: var(--dim); text-decoration: none;
  border-bottom: 1px solid var(--edge); padding-bottom: 1px;
}
.guide .pdp-actions > a:not(.btn):hover,
.guide .pdp-actions > a:not(.btn):focus-visible {
  color: var(--psychic); border-bottom-color: currentColor;
}

/* quantity stepper — only 56% of rows are qty 1, so this earns its place */
.pdp-qty { display: flex; align-items: center; gap: var(--s1); }
.pdp-qty button {
  min-width: 44px; min-height: 44px; border: 1px solid var(--edge);
  background: none; color: var(--ghost); border-radius: 8px; cursor: pointer;
  font: 500 1rem var(--font-mono);
}
.pdp-qty button:hover:not(:disabled) { border-color: var(--psychic); color: var(--psychic); }
.pdp-qty button:disabled { opacity: 0.4; cursor: default; }
.pdp-qty output {
  min-width: 3ch; text-align: center; font: 500 1rem var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* spec sheet — placard grammar, one field per row */
.pdp-specs { margin: var(--s3) 0 0; display: flex; flex-direction: column; }
.pdp-specs > div {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s2); padding: 0.6rem 0; border-top: 1px solid var(--hairline);
}
.pdp-specs > div:last-child { border-bottom: 1px solid var(--hairline); }
.pdp-specs dt {
  font: 500 var(--text-placard) var(--font-mono); letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--dim);
}
.pdp-specs dd {
  margin: 0; font: 500 0.8rem var(--font-mono); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ghost); text-align: right;
}
.pdp-specs dd[data-empty] { color: var(--dim); }
.pdp-specs .num { font-variant-numeric: tabular-nums; }

.pdp-cond-wrap { padding: var(--s6) 0 var(--s4); }
.pdp-cond { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--s6); align-items: start; }
@media (max-width: 760px) { .pdp-cond { grid-template-columns: 1fr; gap: var(--s3); } }
.pdp-cond-aside { border-left: 1px solid var(--hairline); padding-left: var(--s4); }
@media (max-width: 760px) {
  .pdp-cond-aside { border-left: 0; border-top: 1px solid var(--hairline); padding: var(--s3) 0 0; }
}
.pdp-observed {
  font: 500 0.85rem var(--font-mono); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim); margin: 0;
}
.pdp-ships { color: var(--dim); font-size: 0.88rem; max-width: 44ch; margin: 0; }

/* sold / retired — the URL survives so printed QRs and Discord links do too */
.pdp-retired {
  border: 1px solid var(--edge); border-radius: 10px; padding: var(--s3);
  display: flex; flex-direction: column; gap: var(--s2);
  background: linear-gradient(165deg, var(--panel-mid), var(--panel-lo));
}
.pdp-retired .pdp-price { color: var(--dim); }

/* ---------- buylist intake composer (/sell/list/) ---------- */
/* The site cannot POST — form-action is 'none' — so this composes a list
   in the browser and the customer carries it. Everything here is layout
   for that one job. */
.intake {
  display: flex; flex-direction: column; gap: var(--s2);
  border: 1px solid var(--hairline); border-radius: 12px;
  padding: var(--s3) var(--s2) var(--s3);
  background: linear-gradient(165deg, var(--panel-mid), var(--panel-lo));
  margin: var(--s4) 0;
}
.intake textarea {
  width: 100%; box-sizing: border-box; background: var(--abyss);
  border: 1px solid var(--edge); border-radius: 8px; color: var(--ghost);
  font: 400 0.82rem/1.75 var(--font-mono); padding: var(--s1);
  resize: vertical;
}
.intake textarea:focus-visible { outline: 2px solid var(--psychic); outline-offset: 2px; }
.intake-meta { display: flex; justify-content: space-between; gap: var(--s2); margin: 0; }
.intake-count { color: var(--jade); }
.intake-block {
  border-top: 1px solid var(--hairline); padding-top: var(--s2);
  display: flex; flex-direction: column; gap: var(--s1);
}
.intake-block p { margin: 0; max-width: 44ch; }
.intake-warn { color: var(--ember); }
.intake-pick { display: flex; flex-direction: column; gap: var(--s1); margin-top: var(--s2); }
.intake-pick-name { margin: 0; color: var(--ghost); }
/* A 44px target, and the label reads at arm's length. `.chip` alone is
   uppercase mono at --text-label, which is right for a filter rail and
   thin for a set name you are choosing between. */
.intake-pick .chip { text-transform: none; letter-spacing: 0.04em; }
.intake-copy { min-height: 2.75rem; align-self: stretch; justify-content: center; }
.intake-status { margin: 0; color: var(--dim); min-height: 1.4em; }
.intake-steps {
  margin: 0; padding-left: 1.2rem; display: flex; flex-direction: column;
  gap: var(--s1); max-width: 46ch;
}
.intake-steps li { color: var(--ghost); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
