/* Catalogue styles.
   Palette carried over from the storefront design system, contrast verified:
   #EDEAE4 on #131211 = 15.6:1  ·  #D8B25C on #131211 = 9.3:1
   #1A7F5E measures 3.8:1 on the background, so it is a FILL only, never text. */

:root {
  --bg: #131211;
  --surface: #1b1917;
  --surface-hi: #23211f;
  --ink: #edeae4;
  --muted: #9d9b97;
  --gold: #d8b25c;
  --green: #1a7f5e;
  --border: rgba(237, 234, 228, 0.08);
  --border-hi: rgba(237, 234, 228, 0.14);
  --page: 1200px;
  --radius: 8px;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: Archivo, Inter, system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0;
}

h1 { font-size: clamp(1.9rem, 4.2vw, 2.75rem); }
h2 { font-size: clamp(1.4rem, 3vw, 2rem); }
h3 { font-size: 1.15rem; }

a { color: var(--gold); }

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

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

.mono {
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  color: var(--muted);
}

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

.site-header {
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: rgba(19, 18, 17, 0.92);
  backdrop-filter: blur(10px);
  z-index: 20;
}

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

.brand {
  font-family: Archivo, sans-serif;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}

.brand span { color: var(--gold); }

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

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

.site-nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
}

.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--ink); }

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

.hero {
  position: relative;
  border-bottom: 1px solid var(--border);
  background: #0f0e0d center / cover no-repeat;
  min-height: 340px;
  display: flex;
  align-items: flex-end;
}

/* The banner carries gold highlights that reach near-white, so the scrim goes
   heavy wherever the text sits and stays light above it. The stops are derived
   from the text block's measured position, not guessed: the hero grows to fit
   its copy, so on a wide screen the words occupy the lower half while on a
   phone they fill it almost top to bottom — hence a separate profile below.
   Worst case measured over the banner: headline 12.8:1, lede 5.5:1. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(19,18,17,0.34) 0%,
    rgba(19,18,17,0.42) 22%,
    rgba(19,18,17,0.90) 36%,
    rgba(19,18,17,0.95) 100%);
}

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

.hero p.lede {
  color: var(--muted);
  max-width: 56ch;
  margin: 14px 0 0;
}

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

.section { padding-block: 56px; }

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

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

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

.card:hover, .card:focus-visible {
  transform: translateY(-2px);
  border-color: var(--border-hi);
  background: var(--surface-hi);
}

.card-media {
  position: relative;
  aspect-ratio: 1 / 1;
  background: #100f0e;
}

.card-media--photo { background: #fff; }

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

/* Placeholder for products with no photograph yet. Deliberately typographic
   so it reads as a catalogue convention rather than a failed image load. */
.ph {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  gap: 12px; padding: 22px; text-align: center;
  background:
    linear-gradient(180deg, rgba(216,178,92,0.05), transparent 60%), #100f0e;
  border-bottom: 1px solid var(--border);
}

.ph-fmt {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold);
}

.ph-title {
  font-family: Archivo, sans-serif; font-weight: 600;
  font-size: 1.02rem; line-height: 1.3; color: rgba(237,234,228,0.82);
  max-width: 16ch;
}

.badge {
  position: absolute;
  top: 10px;
  left: 10px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 5px 9px;
  border-radius: 4px;
  background: var(--gold);
  color: #131211;
  font-weight: 600;
}

.badge--jp { background: var(--gold); }
.badge--en { background: var(--green); color: #fff; }

.card-body { padding: 16px 16px 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; }

.card-title {
  font-family: Archivo, sans-serif;
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.3;
}

.card-spec { font-family: "IBM Plex Mono", monospace; font-size: 0.7rem; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }

.card-foot { margin-top: auto; display: flex; flex-direction: column; gap: 3px; }

.price { font-weight: 600; font-size: 1.1rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

.stock { font-family: "IBM Plex Mono", monospace; font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }

.stock--low { color: var(--gold); }

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

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

.detail-media {
  background: #100f0e;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.detail-media--photo { background: #fff; }
.detail-media img { width: 100%; height: 100%; object-fit: contain; }
.detail-media .ph-title { font-size: 1.4rem; max-width: 20ch; }

.detail dl { display: grid; grid-template-columns: max-content 1fr; gap: 8px 22px; margin: 22px 0; }
.detail dt { font-family: "IBM Plex Mono", monospace; font-size: 0.72rem; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }
.detail dd { margin: 0; }

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

.price-row { display: flex; align-items: baseline; gap: 14px; margin: 6px 0 0; flex-wrap: wrap; }
.price-lg { font-size: 1.8rem; font-weight: 600; font-variant-numeric: tabular-nums; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0 0; }
.chip { border: 1px solid var(--border-hi); border-radius: 999px; padding: 5px 12px; font-size: 0.78rem; color: var(--muted); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  background: var(--green);
  color: #fff;
  text-decoration: none;
  font-weight: 600;
  padding: 13px 24px;
  /* A transparent border so a button with one and a button without are the
     same height, and vertical-align:middle so an icon inside one does not
     shift it off its neighbour's baseline. */
  border: 1px solid transparent;
  vertical-align: middle;
  border-radius: 6px;
  min-height: 48px;
  line-height: 22px;
  margin-top: 22px;
}

/* The envelope is decorative, so it never sets the line box — it rides along
   with whatever text it sits beside and takes that text's colour. */
.ico {
  flex: 0 0 auto;
  display: block;
  overflow: visible;
}

.btn:hover { background: #167052; }
.btn--ghost { background: transparent; border-color: var(--border-hi); color: var(--ink); }
.btn--ghost:hover { background: var(--surface-hi); }

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

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

.site-footer {
  border-top: 1px solid var(--border);
  padding-block: 34px 44px;
  color: var(--muted);
  font-size: 0.85rem;
}

.site-footer .wrap { display: flex; gap: 22px; justify-content: space-between; flex-wrap: wrap; }
.site-footer a { color: var(--muted); }

.contact-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.contact-link:hover { color: var(--ink); }

.disclaimer { max-width: 62ch; margin-top: 18px; font-size: 0.78rem; line-height: 1.5; }

/* ---------- responsive ---------- */

@media (max-width: 760px) {
  .detail { grid-template-columns: 1fr; gap: 28px; padding-block: 32px; }
  .section { padding-block: 40px; }
  .hero { min-height: 260px; }
  .site-header .wrap { min-height: 58px; padding-block: 10px; }

  /* The copy wraps to about 215px here, so a hero sized to the text alone
     leaves it almost no clear space and the banner cannot show through
     whatever the scrim does. Height is set so roughly the top third stays
     free of text, which is the part of the banner people actually see. */
  .hero { min-height: 420px; }

  .hero::after {
    background: linear-gradient(180deg,
      rgba(19,18,17,0.22) 0%,
      rgba(19,18,17,0.30) 26%,
      rgba(19,18,17,0.90) 38%,
      rgba(19,18,17,0.95) 100%);
  }
}

/* Narrower than this the copy wraps to another couple of lines and starts
   higher up the hero, so the dark part has to begin sooner. Less of the banner
   shows here than on a wider phone, which is the unavoidable trade when the
   text needs most of the height. */
@media (max-width: 400px) {
  .hero::after {
    background: linear-gradient(180deg,
      rgba(19,18,17,0.22) 0%,
      rgba(19,18,17,0.26) 15%,
      rgba(19,18,17,0.90) 25%,
      rgba(19,18,17,0.95) 100%);
  }
}

:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- category tiles ---------- */

.cats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
  margin-top: 22px;
}

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

.cat:hover, .cat:focus-visible {
  transform: translateY(-2px);
  border-color: var(--border-hi);
  background: var(--surface-hi);
}

.cat h3 { margin-bottom: 8px; }
.cat p { margin: 0 0 14px; color: var(--muted); font-size: 0.92rem; }
.cat .mono { color: var(--gold); }

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

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

/* The heading row is the toggle. Native <details>, so it folds with no
   JavaScript, is keyboard-operable, and the block's id still anchors to it
   whether it is open or closed. */
.setblock > summary {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
  margin-bottom: 22px;
  cursor: pointer;
  list-style: none;
  transition: border-color 140ms ease-out;
}

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

/* Hover only where there is a real pointer. On a touch screen :hover sticks
   after a tap, which left one heading gold and the rest not. */
@media (hover: hover) {
  .setblock > summary:hover { border-bottom-color: var(--border-hi); }
  .setblock > summary:hover h3 { color: var(--gold); }
}

.setblock > summary h3 { transition: color 140ms ease-out; }

/* Direct child only — the set code sits in a .mono inside the h3 and must not
   be pushed anywhere. Pushes the count and chevron right as a pair, so the
   heading keeps the left edge however long the set name is. */
.setblock > summary > .mono { margin-left: auto; }

.setblock > summary::after {
  content: "";
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  transform: rotate(45deg);
  transition: transform 180ms ease-out;
  position: relative;
  top: -2px;
}

.setblock[open] > summary::after { transform: rotate(-135deg); top: 1px; }

/* Closed, the rule under the heading is the only thing separating one set
   from the next, so it does not need the gap an open block leaves for its
   grid. */
.setblock:not([open]) > summary { margin-bottom: 0; }
.setblock:not([open]) { padding-top: 26px; }

.setblock h3 .mono { margin-left: 10px; margin-right: 0; color: var(--gold); }

@media (prefers-reduced-motion: reduce) {
  .setblock > summary,
  .setblock > summary h3,
  .setblock > summary::after { transition: none; }
}

/* Rows within a block sit closer together than the gap between blocks, so the
   grouping reads structurally rather than as one long undifferentiated run. */
.setblock .grid { row-gap: 20px; }

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

/* One horizontally scrolling row per category, so adding products widens the
   homepage rather than lengthening it. The scrolling is CSS — the script only
   adds the arrows and the auto-advance on top. */

.rail-section + .rail-section { margin-top: 46px; }

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

.rail-more {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

.rail-more:hover { text-decoration: underline; }

.rail { position: relative; }

.rail-track {
  display: flex;
  gap: 26px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-left: 2px;
  /* Room for the card's hover lift, which would otherwise be clipped. */
  padding: 4px 2px 6px;
  margin: -4px -2px -6px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-hi) transparent;
  overscroll-behavior-x: contain;
}

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

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

.rail-nav {
  position: absolute;
  top: calc(50% - 40px);
  transform: translateY(-50%);
  z-index: 2;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--border-hi);
  background: rgba(19, 18, 17, 0.92);
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 140ms ease-out, background 140ms ease-out;
}

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

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

/* Touch devices have no hover to reveal the arrows, and swiping is the
   native gesture there, so the arrows stay out of the way. */
@media (hover: none) {
  .rail-nav { display: none; }
}

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

/* ---------- FAQ ---------- */

/* Native <details>, so opening and closing costs no JavaScript. */

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

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

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

.faq-item summary {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 0;
  cursor: pointer;
  font-family: Archivo, Inter, system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  line-height: 1.4;
  list-style: none;
  transition: color 140ms ease-out;
}

/* Both are needed: the pseudo-element for WebKit, list-style for the rest. */
.faq-item summary::-webkit-details-marker { display: none; }

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

/* Chevron, drawn in CSS so there is no icon file to keep in step. */
.faq-item summary::after {
  content: "";
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  margin-left: auto;
  margin-top: 6px;
  border-right: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  transform: rotate(45deg);
  transform-origin: center;
  transition: transform 180ms ease-out;
}

.faq-item[open] summary::after { transform: rotate(-135deg); margin-top: 10px; }

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

.faq-answer p { margin: 0; }

@media (prefers-reduced-motion: reduce) {
  .faq-item summary::after { transition: none; }
}

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

/* Every category splits by game first, then by set (or grading company). The
   game heading is the louder of the two so the two levels stay readable when a
   game holds a lot of sets. */
.gameband { padding-top: 18px; scroll-margin-top: 80px; }
.gameband + .gameband { padding-top: 56px; }

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

.gameband-head h2 { font-size: clamp(1.5rem, 3.2vw, 2.1rem); }

.gameband .setblock:first-of-type { padding-top: 30px; }
.gameband .setblock h3 { font-family: Archivo, sans-serif; font-size: 1.25rem; margin: 0; }

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

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

.search input {
  width: 210px;
  max-width: 100%;
  padding: 8px 12px;
  border-radius: 6px;
  border: 1px solid var(--border-hi);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  -webkit-appearance: none;
  appearance: none;
}

.search input::placeholder { color: var(--muted); }
.search input:focus { border-color: var(--gold); outline: none; }

.search-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(380px, calc(100vw - 48px));
  background: var(--surface);
  border: 1px solid var(--border-hi);
  border-radius: var(--radius);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
  max-height: min(420px, 70vh);
  overflow-y: auto;
  z-index: 30;
}

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

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

.search-results a:hover,
.search-results [aria-selected="true"] a { background: var(--surface-hi); }

.search-thumb {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
}

.search-thumb img { width: 100%; height: 100%; object-fit: contain; }
.search-thumb-blank { display: block; width: 100%; height: 100%; background: #100f0e; }

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

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

.search-meta {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-price {
  font-size: 0.82rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

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

@media (max-width: 760px) {
  .header-end { width: 100%; gap: 12px; }
  .search { width: 100%; order: -1; }
  .search input { width: 100%; }
  .search-panel { right: auto; left: 0; width: 100%; }
}

/* ---------- phone product grid ---------- */

/* Phones get two products per row instead of one, so a set is scannable
   without a lot of scrolling. Only the product cards shrink — page structure,
   headings and the rest of the site are untouched, and nothing above this
   width changes at all. */
@media (max-width: 560px) {
  /* Below this the heading row cannot hold title, code, count and chevron on
     one line, and flex-wrap dropped whichever piece did not fit to the next
     line — so the chevron landed hard left on one row and hard right on the
     next. A grid fixes each piece to a cell instead: title on the first row,
     count beneath it, chevron pinned to the right edge across both. Every row
     then has the same shape however long the set name is. */
  .setblock > summary {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "title chevron"
      "meta  chevron";
    align-items: center;
    column-gap: 14px;
    row-gap: 4px;
  }

  .setblock > summary h3 { grid-area: title; }
  .setblock > summary > .mono { grid-area: meta; margin-left: 0; }

  .setblock > summary::after {
    grid-area: chevron;
    align-self: center;
    top: 0;
  }

  .setblock[open] > summary::after { top: 0; }

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

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

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

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

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