

/* ---------------------------------------------------------------------------
   Design tokens.

   The stylesheet had grown 34 distinct font sizes, 22 spacing values and 14
   border radii — nobody notices 0.84rem beside 0.85rem, but the eye reads the
   missing rhythm as amateur. Everything below is a fixed scale; new rules pick
   a step, they don't invent a value.
   --------------------------------------------------------------------------- */
:root {
  /* Type — a 1.25 ratio, 8 steps. `--fs-2xs` is the floor; nothing smaller. */
  --fs-2xs:  0.6875rem;   /* 11px  tags, counts */
  --fs-xs:   0.75rem;     /* 12px  captions, meta */
  --fs-sm:   0.8125rem;   /* 13px  secondary text, table cells */
  --fs-base: 0.9375rem;   /* 15px  body */
  --fs-md:   1.0625rem;   /* 17px  card titles */
  --fs-lg:   1.375rem;    /* 22px  section headings */
  --fs-xl:   1.75rem;     /* 28px  page titles */
  --fs-2xl:  2.25rem;     /* 36px  hero */

  --lh-tight: 1.25;
  --lh-body:  1.6;

  /* Space — a 4px grid. */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 24px;  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;

  /* Radius — three steps plus a pill. */
  --r-sm: 6px;  --r-md: 10px;  --r-lg: 16px;  --r-full: 999px;

  /* Elevation — surfaces sit at one of three heights, never in between. */
  --e-1: 0 1px 2px rgba(0, 0, 0, 0.25);
  --e-2: 0 4px 12px rgba(0, 0, 0, 0.32);
  --e-3: 0 14px 34px rgba(0, 0, 0, 0.5);

  /* --- Dark, the default look -------------------------------------------
     Graphite rather than navy. The old palette was blue-tinted all the way
     through, which is what made it read as a default bootstrap dark theme;
     a near-neutral base lets the gold be the only real colour on screen. */
  --bg: #0d0f13;
  --surface: #14171e;
  --surface-2: #191d25;
  --surface-3: #222732;
  --slot-bg: #101319;

  --line: #262b36;
  --line-strong: #363d4b;

  --ink: #e9ecf2;
  --ink-dim: #99a1b0;
  --ink-faint: #868e9c;   /* 4.53:1 on --surface-3, the lightest plate it sits on */

  --accent: #e63946;
  --accent-soft: #ff6b6b;
  --gold: #d1ab52;
  --gold-ink: #d4b56a;        /* gold used as text */
  --gold-dim: #967026;
  /* text green/red; matches the chart strokes in app.js. Darkened for light
     mode, where the bright pair is unreadable — see the light block below. */
  --good: #4ade80;
  --bad: #f87171;

  --graded-ink: #9ad5ff;     /* the blue ◆ that marks a graded copy, as type */
  --jp-ink: #9fb4dd;         /* the JP tag on Japanese printings */
  --link: #8fb8d8;
  --focus: 0 0 0 3px rgba(209, 171, 82, 0.42);

  /* A set tile is a poster: dark all the way through in BOTH themes, the way
     an album or film card stays dark on a light page. Bandai's set wordmarks
     are light-ink artwork drawn for dark backgrounds — 43 of them with no light
     versions — so a white tile could never carry them. */
  --poster: #191d25;
  /* A set tile stays dark in both themes, so its text can't use the theme ink */
  --tile-ink: #e9ecf2;
  --tile-ink-dim: #99a1b0;
  --tile-ink-faint: #7d8598;
  --tile-line: #2b3140;
  --scrim-0: rgba(25, 29, 37, 0);
  --scrim-1: rgba(25, 29, 37, 0.96);

  /* kept: older rules still reference these */
  --bg-page: var(--surface-2);
  --radius: var(--r-md);
}

/* --- Light -----------------------------------------------------------------
   Applied when the reader's system asks for light, unless they've explicitly
   chosen dark; and always when they've explicitly chosen light. No attribute
   at all means "follow the system", which is the default.
   --------------------------------------------------------------------------- */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { color-scheme: light; }
}
:root[data-theme="light"] { color-scheme: light; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #f4f3ef;
    --surface: #fffcf8;
    --surface-2: #fffcf8;
    --surface-3: #eceae4;
    --slot-bg: #f0eeea;

    /* A tile stays dark so it can carry the light-ink set wordmarks, but on
    a light page it lifts to a softer slate rather than near-black. */
    --poster: #2b303c;
    --scrim-0: rgba(43, 48, 60, 0);
    --scrim-1: rgba(43, 48, 60, 0.96);
    --tile-line: #3b4254;
    /* the tile is lighter here, so its dim ink has to lift too */
    --tile-ink-faint: #9aa2b4;
    --tile-ink-dim: #b2b9c8;
    --scrim-0: rgba(20, 23, 30, 0);
    --scrim-1: rgba(20, 23, 30, 0.96);

    --line: #e2e5ec;
    --line-strong: #c9cfda;

    --ink: #14171d;
    --ink-dim: #59616f;
    --ink-faint: #666d7b;   /* 5.2:1 on white — #858c9b only reached 3.38 */

    /* The fill gold is too light on white, so text gold darkens while
       fills keep the brand colour. */
    /* Green and red are read at a glance here, so they have to be legible:
       the dark theme's #4ade80 sits at 1.74:1 on a white card. These clear AA
       (4.89:1 and 5.33:1) while still reading as up and down. */
    --good: #12794a;
    --bad: #c02434;
    --graded-ink: #1f6f9e;   /* #9ad5ff is 1.57:1 on white */
    --jp-ink: #4a6698;       /* #9fb4dd is 1.83:1 on --surface-3 */
    --gold-ink: #8f660c;
    --link: #1f5f96;
    --focus: 0 0 0 3px rgba(143, 102, 12, 0.32);
  }
}
:root[data-theme="light"] {
  --bg: #f4f3ef;
  --surface: #fffcf8;
  --surface-2: #fffcf8;
  --surface-3: #eceae4;
  --slot-bg: #f0eeea;

  /* A tile stays dark so it can carry the light-ink set wordmarks, but on
  a light page it lifts to a softer slate rather than near-black. */
  --poster: #2b303c;
  --scrim-0: rgba(43, 48, 60, 0);
  --scrim-1: rgba(43, 48, 60, 0.96);
  --tile-line: #3b4254;
  /* the tile is lighter here, so its dim ink has to lift too */
  --tile-ink-faint: #9aa2b4;
  --tile-ink-dim: #b2b9c8;
  --scrim-0: rgba(20, 23, 30, 0);
  --scrim-1: rgba(20, 23, 30, 0.96);

  --line: #e2e5ec;
  --line-strong: #c9cfda;

  --ink: #14171d;
  --ink-dim: #59616f;
  --ink-faint: #666d7b;   /* see the note in the media block above */

  /* see the note in the prefers-color-scheme block above */
  --good: #12794a;
  --bad: #c02434;
  --graded-ink: #1f6f9e;   /* #9ad5ff is 1.57:1 on white */
  --jp-ink: #4a6698;       /* #9fb4dd is 1.83:1 on --surface-3 */
  --gold-ink: #8f660c;
  --link: #1f5f96;
  --focus: 0 0 0 3px rgba(143, 102, 12, 0.32);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-optical-sizing: auto;
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  letter-spacing: -0.011em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv05" 1, "ss03" 1, "tnum" 1;
  min-height: 100vh;
}

/* Numbers in columns should line up: prices, counts, grades, dates. */
.cl-price, .t-pct, .hc-stat strong, .sc-value, .ni-count, .lt-count,
.page-count, .cg-val, .sb-value { font-variant-numeric: tabular-nums; }

/* A visible, consistent focus ring — keyboard users currently get whatever
   the browser decides, which differs per browser and looks unfinished. */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--focus);
  border-radius: var(--r-sm);
}

.topbar {
  text-align: center;
  padding: var(--s-6) var(--s-4) var(--s-5);
  position: relative;
  border-bottom: 1px solid var(--line);
}
.topbar h1 { font-size: 1.6rem; letter-spacing: 0.5px; max-width: 40%; margin-inline: auto; }
.subtitle { color: var(--ink-dim); font-size: var(--fs-sm); margin-top: var(--s-1); }
/* Home only: a quiet caption under the wordmark, not a second headline. */
.subtitle.tagline {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  margin-top: var(--s-3);
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-ink);
  white-space: nowrap;
}
.subtitle.tagline::before,
.subtitle.tagline::after {
  content: "";
  width: 18px;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}

.crumbs[hidden] { display: none !important; }
.crumbs {
  position: absolute;
  left: var(--s-4);
  top: var(--s-6);
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: nowrap;
  /* The crumb trail and the centred page title share this row, so each side
     gets a reserved share of the width. Without this a long set name — the
     Japanese ones especially — slid straight under the breadcrumb. */
  max-width: 28%;
}
/* the last crumb names the current page, which the big title repeats anyway,
   so it's the one that gives way */
.crumb:last-child {
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.crumb {
  background: none;
  border: 0;
  font: inherit;
  font-size: var(--fs-sm);
  padding: 7px 9px;
  border-radius: var(--r-sm);
  color: var(--ink-dim);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.crumb[data-go]:hover { background: var(--surface-3); color: var(--ink); }
.crumb.here {
  color: var(--ink);
  font-weight: 600;
  cursor: default;
  padding: 7px 9px;
}
/* --line-strong is a hairline colour; as type it sat at 1.46:1 */
.crumb-sep { color: var(--ink-faint); font-size: 0.8rem; }

/* ---------- Set picker ---------- */
.set-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
  gap: var(--s-4);
  max-width: 1140px;
  margin: var(--s-5) auto;
  padding: 0 var(--s-4) var(--s-7);
}
.set-tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 0;
  cursor: pointer;
  text-align: center;
  color: var(--ink);
  font: inherit;
  overflow: hidden;
  box-shadow: var(--e-1);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  display: flex;
  flex-direction: column;
}
.set-tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--e-3);
}
.set-tile:hover .t-cover img { transform: scale(1.045); }
/* set-specific artwork across the top of the tile */
.set-tile .t-cover {
  overflow: hidden;
  background: var(--poster);
  aspect-ratio: 16 / 9;
  position: relative;
}
.set-tile .t-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--scrim-0) 34%, var(--scrim-1) 88%);
}
.set-tile .t-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* pulled up slightly so the banner's release-date strip crops away */
  object-position: center 42%;
  display: block;
  transition: transform 0.35s ease;
}
/* card art is portrait — frame the illustration near the top, above the text box */
.set-tile .t-cover img.from-card { object-position: center 16%; }

.set-tile .t-logo {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  min-height: 66px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-1);
  padding: 0 var(--s-4) var(--s-3);
  z-index: 2;
}
/* official stylised wordmark, when the set has one */
.set-tile .t-logo-box {
  display: block;
  width: 100%;
  max-width: 218px;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6));
}
.set-tile .t-logo-img {
  display: block;
  width: 100%;
  height: 66px;
  object-fit: contain;
  object-position: center bottom;
}

.set-tile .t-logo-fallback[hidden] { display: none !important; }
.set-tile .t-logo-fallback {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

/* the set name rendered as a written logo, Collectr-style */
.set-tile .t-logo-text {
  font-weight: 900;
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 0 6px;
  color: var(--gold);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.6));
}
.set-tile .t-logo-text.long { font-size: 1.02rem; }
.set-tile .t-logo-eyebrow {
  font-weight: 700;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 2px;
  color: var(--tile-ink-dim);
}
/* One meta row: what the set is on the left, how far you are on the right. */
/* everything below the artwork, painted in the theme's surface colour */
.set-tile .t-foot {
  margin-top: auto;
  padding-bottom: var(--s-3);
}
.set-tile .t-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4) 0;
}
.set-tile .t-id {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  color: var(--ink-dim);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.set-tile .t-jp {
  padding: 1px 5px;
  border-radius: var(--r-sm);
  background: var(--surface-3);
  color: var(--ink-dim);
  font-size: 0.62rem;
}
.set-tile .t-pct { font-size: var(--fs-xs); color: var(--ink-dim); }
.set-tile .t-pct b { color: var(--ink); font-weight: 600; }
.set-tile .t-pctnum { color: var(--gold-ink); font-weight: 600; }

.set-tile .t-mini {
  height: 4px;
  background: var(--line);
  border-radius: var(--r-full);
  margin: var(--s-3) var(--s-4) 0;
  overflow: hidden;
}
.set-tile .t-mini[hidden] { display: none !important; }
.set-tile .t-mini > div {
  height: 100%;
  background: linear-gradient(90deg, var(--gold-dim), var(--gold));
  border-radius: var(--r-full);
  transition: width 0.4s ease;
}

/* ---------- Progress header ---------- */
.set-controls[hidden], .set-grid[hidden], .binder[hidden], .binder-nav[hidden] { display: none !important; }
/* One card above the binder instead of four loose controls: where you are in
   the set, then the two things that change what you're looking at. */
.set-controls {
  max-width: 780px;
  margin: var(--s-5) auto 0;
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--e-1);
}
.sc-stats {
  display: flex;
  gap: var(--s-6);
  margin-bottom: var(--s-3);
}
.sc-stat { display: flex; flex-direction: column; gap: 2px; }
.sc-stat span {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.sc-stat strong {
  font-size: var(--fs-md);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.sc-stat strong.gold { color: var(--gold-ink); }
.sc-stat[hidden] { display: none !important; }

.sc-options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}
.progress-wrap { flex: 1 1 340px; }
.progress-labels {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: var(--ink-dim);
  margin-bottom: 5px;
}
#progressPct { color: var(--gold-ink); font-weight: 700; }
.progress-bar {
  height: 6px;
  background: var(--line);
  border-radius: var(--r-full);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--gold-dim), var(--gold));
  border-radius: var(--r-full);
  transition: width 0.4s ease;
}
.value-line { font-size: 0.78rem; color: var(--ink-dim); margin-top: 5px; }
.mode-toggle {
  display: flex;
  gap: var(--s-2);
  align-items: center;
  font-size: var(--fs-sm);
  color: var(--ink-dim);
  cursor: pointer;
  user-select: none;
  position: relative;
}
.mode-toggle:hover { color: var(--ink); }
.mode-toggle input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
/* the system checkbox rendered in accent red, which reads as an error */
.mt-box {
  width: 16px;
  height: 16px;
  flex: none;
  border: 1.5px solid var(--line-strong);
  border-radius: 4px;
  background: var(--bg);
  display: grid;
  place-items: center;
  transition: background 0.14s, border-color 0.14s;
}
.mt-check {
  display: block;
  width: 11px;
  height: 11px;
  opacity: 0;
  transform: scale(0.7);
  transform-origin: center;
  transition: opacity 0.12s, transform 0.12s;
}
.mode-toggle input:checked + .mt-box {
  background: var(--gold);
  border-color: var(--gold);
}
.mode-toggle input:checked + .mt-box .mt-check {
  opacity: 1;
  transform: scale(1);
}
.mode-toggle input:focus-visible + .mt-box { box-shadow: var(--focus); }

/* ---------- Binder ---------- */
.binder {
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  justify-content: center;
  align-items: start;
  padding: 24px 12px 10px;
  max-width: 1200px;
  margin: 0 auto;
}

/* page flipping — the binder shows one two-page spread at a time */
.binder-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 4px 16px 30px;
}
.flip-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.12s, transform 0.12s, background 0.12s;
}
.flip-btn:hover:not(:disabled) {
  border-color: var(--line-strong);
  background: var(--surface-3);
  transform: translateY(-1px);
}
.flip-btn:disabled { opacity: 0.3; cursor: default; }
.page-count {
  min-width: 168px;
  text-align: center;
  font-size: 0.82rem;
  color: var(--ink-dim);
  letter-spacing: 0.4px;
}
.binder-page {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-4);
  width: min(440px, calc(50vw - 32px));
  box-shadow: var(--e-2);
}
.page-label {
  text-align: center;
  color: var(--ink-dim);
  font-size: 0.78rem;
  margin-bottom: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.page-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.card-slot {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  background: var(--slot-bg);
  aspect-ratio: 600 / 838;
  border: 1px solid transparent;
  transition: transform 0.1s;
}
.card-slot:hover { transform: scale(1.03); }
/* flash after jumping here from the checklist */
.card-slot.just-found {
  animation: found-pulse 2.2s ease-out;
  z-index: 3;
}
@keyframes found-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(244, 201, 93, 0.9); transform: scale(1.06); }
  15%  { box-shadow: 0 0 0 5px rgba(244, 201, 93, 0.55); transform: scale(1.06); }
  70%  { box-shadow: 0 0 0 5px rgba(244, 201, 93, 0.35); transform: scale(1.02); }
  100% { box-shadow: 0 0 0 0 rgba(244, 201, 93, 0); transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .card-slot.just-found { animation: none; box-shadow: 0 0 0 3px var(--gold); }
}
.card-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: filter 0.25s, opacity 0.25s;
}
.card-slot.missing img {
  filter: grayscale(1) brightness(0.85);
  opacity: 0.55;
}
.card-slot.missing { border: 1px dashed var(--line-strong); }
/* placeholder for cards whose scan hasn't been published yet */
.no-art-label { display: none; }
.card-slot.no-art img { display: none; }
.card-slot.no-art {
  background: repeating-linear-gradient(
    -45deg, var(--surface), var(--surface) 6px, var(--surface-2) 6px, var(--surface-2) 12px
  );
}
.card-slot.no-art .no-art-label {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  height: 100%;
  padding: 10px 8px 22px;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
}
.card-slot.no-art .no-art-label em {
  font-style: normal;
  font-weight: 400;
  font-size: 0.6rem;
  color: var(--ink-dim);
}

.card-slot .num {
  position: absolute;
  bottom: 4px;
  left: 4px;
  background: rgba(8, 10, 15, 0.88);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  /* fixed light ink: this chip is dark in both themes because it sits on artwork */
  color: #f3f5f9;
  font-size: 0.62rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  letter-spacing: 0.3px;
  z-index: 2;
}
.card-slot.missing .num { color: #b9c0cc; }
.card-slot .owned-check {
  position: absolute;
  top: 4px;
  right: 4px;
  cursor: pointer;
  transition: transform 0.12s, background 0.12s, color 0.12s;
  background: var(--gold);
  color: #1a1a1a;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  font-size: 0.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
}
/* the badge is the un-mark control, so it reacts on hover */
.card-slot .owned-check:hover {
  transform: scale(1.22);
  background: var(--accent);
  color: #fff;
}
.card-slot.is-graded .owned-check:hover { background: #9ad5ff; color: #062032; }

/* details button — always available, never changes what you own */
.card-slot .slot-info {
  position: absolute;
  bottom: 4px;
  right: 4px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(8, 10, 15, 0.85);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  color: #f3f5f9;                 /* fixed: the button is dark over artwork */
  font: inherit;
  font-size: 0.66rem;
  z-index: 2;
  font-weight: 800;
  font-style: italic;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s, background 0.12s, border-color 0.12s, transform 0.12s;
}
.card-slot:hover .slot-info, .card-slot .slot-info:focus-visible { opacity: 1; }
.card-slot .slot-info:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: #241c05;
  transform: scale(1.15);
}
/* touch screens have no hover, so keep it visible there */
@media (hover: none) {
  .card-slot .slot-info { opacity: 0.85; width: 26px; height: 26px; font-size: 0.72rem; }
  /* 26px is still a small thumb target, but growing the circle would cover more
     of the artwork — so extend the tappable area past the visible edge instead,
     which brings it to 42px without changing how the slot looks. */
  .card-slot .slot-info::after { content: ""; position: absolute; inset: -8px; }
}

.card-slot .alt-tag {
  position: absolute;
  top: 5px;
  left: 5px;
  /* The plate has to be dark enough on its own, because what sits behind it is
     either a pale empty slot or full-colour artwork. At 0.72 the gold read
     3.82:1 over a light slot and 3.63:1 over bright art; 0.85 clears AA against
     both (6.04 and 5.89) and still looks like glass. */
  background: rgba(12, 14, 19, 0.85);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  border: 1px solid rgba(244, 201, 93, 0.5);
  color: var(--gold);
  font-size: 0.56rem;
  font-weight: 800;
  padding: 2px 5px;
  border-radius: 4px;
  letter-spacing: 0.06em;
  z-index: 2;
}

.site-footer {
  border-top: 1px solid var(--line);
  padding: var(--s-6) var(--s-4) var(--s-8);
  margin-top: var(--s-4);
}
.site-footer p {
  max-width: 36rem;
  margin: 0 auto;
  text-align: center;
  color: var(--ink-faint);
  font-size: var(--fs-2xs);
  line-height: 1.65;
}
.site-footer p + p { margin-top: var(--s-2); }

/* too narrow for a spread — show one readable page at a time */
@media (max-width: 620px) {
  .binder-page { width: min(440px, 94vw); }
  .binder-nav { gap: 12px; }
  .page-count { min-width: 130px; font-size: 0.76rem; }
}

@media (max-width: 700px) {
  .topbar h1 { font-size: 1.25rem; }
  .crumbs { position: static; margin-bottom: 8px; justify-content: center; max-width: calc(100% - 56px); flex-wrap: wrap; }
  .topbar h1 { max-width: 100%; }
  /* the menu stays pinned in the corner on phones, where that's where a
     hamburger is expected; the stacked content reserves room for it */
  .navmenu { right: 12px; top: 16px; }
  .nav-toggle { width: 38px; height: 38px; }
  .topbar { display: flex; flex-direction: column; align-items: center; }
  .subtitle.tagline { letter-spacing: 0.1em; gap: var(--s-2); }
  .binder { gap: 18px; }
  .binder-page { padding: 10px; }
  .page-grid { gap: 7px; }
}

/* ---------- Set checklist ---------- */
.checklist[hidden] { display: none !important; }
.checklist {
  max-width: 900px;
  margin: 10px auto 0;
  padding: 26px 16px 60px;
  border-top: 1px solid var(--line);
}
.checklist-head h2 {
  font-size: 1.15rem;
  letter-spacing: 0.3px;
}
.checklist-head p {
  color: var(--ink-dim);
  font-size: 0.82rem;
  margin-top: 4px;
}
.cl-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 16px 0 10px;
}
.cl-search {
  flex: 1 1 260px;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 9px 12px;
  color: var(--ink);
  font: inherit;
  font-size: 0.86rem;
}
.cl-search:focus { outline: none; border-color: var(--gold); box-shadow: var(--focus); }
.cl-search::placeholder { color: var(--ink-faint); }
.cl-sort-wrap {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.82rem;
  color: var(--ink-dim);
}
.cl-sort {
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  cursor: pointer;
}
.cl-sort:focus { outline: none; border-color: var(--gold); box-shadow: var(--focus); }

.cl-missing {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.82rem;
  color: var(--ink-dim);
  cursor: pointer;
  user-select: none;
}
.cl-missing input { accent-color: var(--gold); width: 15px; height: 15px; }

.cl-table {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-page);
}
.cl-head-row, .cl-row {
  display: grid;
  grid-template-columns: 34px 92px 1fr 62px 74px;
  gap: 8px;
  align-items: center;
  padding: 0 12px;
  text-align: left;
}
.cl-head-row {
  height: 34px;
  font-size: 0.68rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-dim);
  background: var(--slot-bg);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 2;
}
.cl-row {
  width: 100%;
  height: 38px;
  background: none;
  border: 0;
  border-top: 1px solid var(--surface-2);
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.82rem;
  cursor: pointer;
}
.cl-row:first-of-type { border-top: 0; }
.cl-row:hover { background: var(--surface-2); }
.cl-row.have { color: var(--ink); }
.cl-box {
  width: 19px;
  height: 19px;
  border-radius: 5px;
  border: 1px solid var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 800;
  color: #1a1a1a;
}
.cl-row.have .cl-box {
  background: var(--gold);
  border-color: var(--gold);
}
/* the number is the "find it in the binder" target */
.cl-num {
  font-variant-numeric: tabular-nums;
  font-size: 0.76rem;
  color: var(--ink-dim);
  justify-self: start;
  padding: 3px 6px;
  margin-left: -6px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.cl-row:hover .cl-num { background: var(--surface-3); }
.cl-num:hover { background: var(--gold) !important; color: #241c05 !important; }
.cl-row.have .cl-num { color: var(--gold-ink); }
.cl-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  justify-self: start;
  max-width: 100%;
}
/* The name is the hover target for the card preview, so it carries a standing
   cue: a dotted underline you can see at rest (the old hover-only hint sat at
   2:1 contrast and was invisible), plus a magnifier cursor over the text. */
.cl-name {
  cursor: zoom-in;
  text-decoration: underline dotted rgba(139, 147, 167, 0.5);
  text-underline-offset: 3px;
}
.cl-row:hover .cl-name { text-decoration-color: var(--ink-dim); }
.cl-row:hover .cl-name:hover {
  color: #fff;
  text-decoration: underline solid var(--gold);
  text-underline-offset: 3px;
}
.cl-row.have .cl-name { text-decoration-color: rgba(244, 201, 93, 0.45); }
.cl-rarity em {
  font-style: normal;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--ink-dim);
}
/* Rarity chips are deep plates with light ink on a dark row. On a white row
   the same plates go muddy, so light mode flips them: a pale tint with
   saturated ink, which reads brighter and keeps each rarity recognisable. */
.cl-rarity .r-SEC, .cl-rarity .r-SPCARD { background: #5a2233; color: #ffc2cf; }
.cl-rarity .r-SR, .cl-rarity .r-TR { background: #4a3a12; color: #f4c95d; }
.cl-rarity .r-P { background: #3a2a4d; color: #d5bcff; }
.cl-rarity .r-L { background: #26405c; color: #a9d4ff; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .cl-rarity em { background: #eceff4; color: #4a5364; }
  :root:not([data-theme="dark"]) .cl-rarity .r-SEC,
  :root:not([data-theme="dark"]) .cl-rarity .r-SPCARD { background: #ffe0e8; color: #a8103c; }
  :root:not([data-theme="dark"]) .cl-rarity .r-SR,
  :root:not([data-theme="dark"]) .cl-rarity .r-TR { background: #fdefc9; color: #8a5b00; }
  :root:not([data-theme="dark"]) .cl-rarity .r-P { background: #ede1ff; color: #5c2ba6; }
  :root:not([data-theme="dark"]) .cl-rarity .r-L { background: #d9ecff; color: #14548f; }
}
:root[data-theme="light"] .cl-rarity em { background: #eceff4; color: #4a5364; }
:root[data-theme="light"] .cl-rarity .r-SEC,
:root[data-theme="light"] .cl-rarity .r-SPCARD { background: #ffe0e8; color: #a8103c; }
:root[data-theme="light"] .cl-rarity .r-SR,
:root[data-theme="light"] .cl-rarity .r-TR { background: #fdefc9; color: #8a5b00; }
:root[data-theme="light"] .cl-rarity .r-P { background: #ede1ff; color: #5c2ba6; }
:root[data-theme="light"] .cl-rarity .r-L { background: #d9ecff; color: #14548f; }
.cl-move {
  display: block;
  font-style: normal;
  font-size: 0.66rem;
  font-weight: 700;
  margin-top: 1px;
}
.cl-move.up { color: var(--good); }
.cl-move.down { color: var(--bad); }
.cl-move.flat { color: var(--line-strong); }

.cl-price {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
}
.cl-row.have .cl-price { color: var(--gold-ink); }
.cl-empty {
  text-align: center;
  color: var(--ink-dim);
  font-size: 0.84rem;
  padding: 18px;
}

/* floating card preview on row hover */
.cl-preview {
  position: fixed;
  width: 210px;
  border-radius: 8px;
  box-shadow: 0 12px 34px rgba(0,0,0,0.6);
  pointer-events: none;
  z-index: 50;
  border: 1px solid var(--line);
}
.cl-preview[hidden] { display: none; }

@media (max-width: 560px) {
  .cl-head-row, .cl-row { grid-template-columns: 28px 76px 1fr 64px; padding: 0 9px; }
  .cl-rarity { display: none; }
  .cl-preview { display: none; }
}

/* ---------- Card page (modal) ---------- */
.card-modal[hidden] { display: none !important; }
.card-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
body.modal-open { overflow: hidden; }
.cm-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 9, 15, 0.82);
  backdrop-filter: blur(3px);
}
.cm-panel {
  position: relative;
  background: var(--bg-page);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.65);
  width: min(760px, 100%);
  max-height: 90vh;
  overflow-y: auto;
}
.cm-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface-3);
  color: var(--ink);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  z-index: 3;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.cm-close:hover {
  background: var(--surface-3);
  border-color: var(--line-strong);
  color: var(--ink);
}
.cm-body {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 24px;
  padding: 24px;
}
.cm-art {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  background: var(--slot-bg);
  aspect-ratio: 600 / 838;
}
.cm-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cm-art img[hidden] { display: none !important; }  /* beats the display:block above */
.cm-noart[hidden] { display: none !important; }  /* display:flex below would win otherwise */
.cm-noart {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 16px;
  font-size: 0.78rem;
  color: var(--ink-dim);
  background: repeating-linear-gradient(-45deg, var(--surface), var(--surface) 6px, var(--surface-2) 6px, var(--surface-2) 12px);
}
.cm-set { color: var(--ink-dim); font-size: 0.76rem; letter-spacing: 0.6px; text-transform: uppercase; }
.cm-name { font-size: 1.45rem; line-height: 1.15; margin: 5px 0 6px; }
.cm-meta { color: var(--ink-dim); font-size: 0.82rem; margin-bottom: 16px; }

.cm-prices { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.cm-price {
  flex: 1 1 120px;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
}
.cm-price span { display: block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-dim); }
.cm-price strong { font-size: 1.25rem; color: var(--gold-ink); }
.cm-price.alt strong { color: var(--ink); font-size: 1.05rem; }

.cm-own {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  width: 100%;
  padding: var(--s-3);
  border-radius: var(--r-md);
  border: 1px solid transparent;
  background: var(--gold);
  color: #1a1408;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
  margin-bottom: var(--s-4);
  transition: background 0.14s, border-color 0.14s, color 0.14s;
}
.cm-own:hover { background: #f8d780; }
.cm-own:hover { border-color: var(--gold); }
/* already owned: a status, not a call to action */
.cm-own.have {
  background: none;
  border-color: var(--line-strong);
  color: var(--ink-dim);
  font-weight: 600;
}
.cm-own.have:hover { background: var(--surface-3); color: var(--ink); }
.own-tick {
  color: var(--gold-ink);
  font-weight: 800;
}

/* price history range buttons */
.cm-ranges { display: flex; gap: 5px; margin-bottom: 10px; }
.cm-ranges[hidden] { display: none !important; }
.cm-range {
  flex: 1;
  padding: 6px 4px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--slot-bg);
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  cursor: pointer;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.cm-range:hover { border-color: var(--line-strong); color: var(--ink); }
.cm-range.on { background: var(--surface-3); border-color: var(--gold); color: var(--gold-ink); }

/* price history chart */
.cm-chart { margin-bottom: 18px; }
.cm-chart h3 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
  font-weight: 700;
  margin-bottom: 8px;
}
.cm-chart h3 em {
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-faint);
  font-weight: 400;
  margin-left: 6px;
}
.cm-changes { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.cm-chg {
  font-size: 0.74rem;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 6px;
  background: var(--surface-3);
  color: var(--ink-dim);
}
.cm-chg.up { color: var(--good); background: rgba(74, 222, 128, 0.12); }
.cm-chg.down { color: var(--bad); background: rgba(248, 113, 113, 0.12); }

.cm-graph {
  position: relative;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 6px 8px;
}
.cm-graph svg { display: block; width: 100%; height: 130px; }
.cm-hi, .cm-lo {
  position: absolute;
  right: 10px;
  font-size: 0.64rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: var(--surface-3);
  border: 1px solid var(--line);
  padding: 1px 4px;
  border-radius: 3px;
}
.cm-hi { top: 6px; }
.cm-lo { bottom: 20px; }
.cm-axis {
  display: flex;
  justify-content: space-between;
  font-size: 0.66rem;
  color: var(--ink-faint);
  padding: 5px 2px 0;
}
.cm-nochart {
  font-size: 0.78rem;
  color: var(--ink-dim);
  line-height: 1.5;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
}
.cm-source { font-size: 0.66rem; color: var(--ink-faint); margin-top: 7px; }

.cm-links { display: flex; gap: 10px; flex-wrap: wrap; }
.cm-link {
  flex: 1 1 160px;
  text-align: center;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 0.86rem;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.12s, filter 0.12s;
}
.cm-link:hover { transform: translateY(-1px); filter: brightness(1.08); }
.cm-link.tcg,
.cm-link.ebay {
  background: var(--surface-3);
  color: var(--ink);
  border: 1px solid var(--line-strong);
}
.cm-link:hover { transform: translateY(-1px); filter: brightness(1.12); }
.cm-disclose { font-size: 0.68rem; color: var(--ink-faint); margin-top: 10px; text-align: center; }

@media (max-width: 620px) {
  .card-modal { padding: 0; align-items: stretch; }
  .cm-panel { border-radius: 0; max-height: 100vh; width: 100%; }
  .cm-body { grid-template-columns: 1fr; gap: 18px; padding: 18px; }
  .cm-art { width: min(230px, 62%); margin: 6px auto 0; }
}

/* ---------- Binder fit advice ---------- */
.binder-advice[hidden] { display: none !important; }
.binder-advice {
  max-width: 900px;
  margin: 0 auto;
  padding: 14px 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
}
.ba-text { flex: 1 1 380px; }
.ba-title {
  display: block;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
  margin-bottom: 3px;
}
.ba-text p { font-size: 0.84rem; line-height: 1.5; color: var(--ink); }
.ba-text strong { color: var(--ink); }
.ba-shop {
  flex: 0 0 auto;
  padding: 10px 18px;
  border-radius: 9px;
  background: var(--gold);
  color: #241c05;
  font-size: 0.82rem;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.12s, filter 0.12s;
}
.ba-shop:hover { transform: translateY(-1px); filter: brightness(1.07); }
.ba-disclose { flex: 1 0 100%; font-size: 0.66rem; color: var(--ink-faint); text-align: right; }

.layout-pick {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  color: var(--ink-dim);
  margin-top: 8px;
}
.layout-pick select {
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 9px;
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  cursor: pointer;
}
.layout-pick select:focus { outline: none; border-color: var(--gold); box-shadow: var(--focus); }

/* ---------- Home / landing ---------- */
.home[hidden] { display: none !important; }
.home { max-width: 1040px; margin: 0 auto; padding: var(--s-6) var(--s-4) var(--s-8); }

.hero { text-align: center; padding: var(--s-6) 0 var(--s-7); }
.hero h2 {
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -0.035em;
  max-width: 18ch;
  margin: 0 auto var(--s-4);
}
.hero p {
  color: var(--ink-dim);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  max-width: 40ch;
  margin: 0 auto;
}

/* your collection */
.hc[hidden] { display: none !important; }
.hc {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-5);
  margin-bottom: var(--s-7);
  box-shadow: var(--e-1);
}
.hc-head { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between; margin-bottom: 18px; }
.hc-head h3 { font-size: 1.05rem; }
.hc-stats { display: flex; gap: 22px; flex-wrap: wrap; }
.hc-stat span {
  display: block;
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
}
.hc-stat strong { font-size: 1.25rem; }
.hc-stat .gold { color: var(--gold-ink); }

.hc-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.hc-col h4 {
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
  margin-bottom: 9px;
}
.hc-top, .hc-sets { list-style: none; display: flex; flex-direction: column; gap: 6px; }

.hc-top li {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 6px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s;
}
.hc-top li:hover { background: var(--surface-3); }
.hc-top img { width: 30px; border-radius: 3px; display: block; grid-row: span 2; }
.hc-top .t-name { font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hc-top .t-sub { grid-column: 2; font-size: 0.66rem; color: var(--ink-dim); }
.hc-top .t-slab {
  font-style: normal;
  background: #17384d;
  color: #9ad5ff;
  font-weight: 700;
  font-size: 0.6rem;
  padding: 1px 5px;
  border-radius: 4px;
  margin-left: 5px;
}
.hc-top .t-val { grid-row: span 2; font-size: 0.86rem; font-weight: 700; color: var(--gold-ink); }

.hc-sets li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px 10px;
  padding: 7px 6px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s;
}
.hc-sets li:hover { background: var(--surface-3); }
.hc-sets .s-name { font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hc-sets .s-count { font-size: 0.72rem; color: var(--ink-dim); }
.hc-sets .s-bar { grid-column: 1; height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; align-self: center; }
.hc-sets .s-bar i { display: block; height: 100%; background: var(--gold); }
.hc-sets .s-pct { font-size: 0.72rem; color: var(--gold-ink); font-weight: 700; }

/* features */
.features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
  margin-bottom: var(--s-6);
}
.feature {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-5);
}
.f-icon { display: block; color: var(--gold-ink); margin-bottom: var(--s-3); }
.f-icon .ic { width: 22px; height: 22px; }
.feature h3 {
  font-size: var(--fs-sm);
  font-weight: 600;
  margin-bottom: var(--s-2);
}
.feature p {
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--ink-dim);
}

/* games */
.games-title {
  text-align: center;
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-dim);
  margin: var(--s-7) 0 var(--s-4);
}
.games { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-4); }
.game-tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-6) var(--s-5);
  text-align: center;
  color: var(--ink);
  font: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-1);
  cursor: pointer;
  box-shadow: var(--e-1);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.game-tile:hover { transform: translateY(-3px); box-shadow: var(--e-2); }
.game-tile .g-name { font-size: 1.05rem; font-weight: 700; }
/* Official ONE PIECE CARD GAME logo — Bandai's white version (561x145), whose
   artwork fills the whole canvas, so it needs no cropping or recolouring. The
   old file bundled the set title and filled only its top-left 193x49 corner,
   which meant displaying it here upscaled it ~1.2x and made it look soft. */
.game-tile .g-logo {
  display: block;
  width: 100%;
  max-width: 240px;
  margin-bottom: 12px;
}
.game-tile .g-logo img {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0.94;
}
.game-tile .g-meta { font-size: 0.8rem; color: var(--ink-dim); }
.game-tile .g-go {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.8rem;
  color: var(--gold-ink);
  font-weight: 600;
  margin-top: 8px;
}
.game-tile .g-go .ic { width: 14px; height: 14px; }
.game-tile.soon { cursor: default; opacity: 0.5; }
.game-tile.soon:hover { transform: none; border-color: var(--line); }

@media (max-width: 720px) {
  .features, .games, .hc-cols { grid-template-columns: 1fr; }
}

/* ---------- Graded copies (card page) ---------- */
.cm-graded {
  border-top: 1px solid var(--line);
  padding-top: 14px;
  margin-bottom: 16px;
}
.cg-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.cg-head h4 {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
}
.cg-add {
  background: none;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  font: inherit;
  font-size: 0.74rem;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 7px;
  cursor: pointer;
}
.cg-add:hover { border-color: var(--gold); color: var(--gold-ink); }
.cg-add[hidden] { display: none !important; }

.cg-list { list-style: none; display: flex; flex-direction: column; gap: 5px; }
.cg-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 10px;
  font-size: 0.8rem;
}
.cg-list li.cg-empty {
  border-style: dashed;
  color: var(--ink-dim);
  font-size: 0.76rem;
  justify-content: center;
}
.cg-slab { flex: 1; }
.cg-slab b { color: var(--gold-ink); letter-spacing: 0.4px; }
.cg-val { font-weight: 700; }
.cg-val.none { font-weight: 400; color: var(--ink-faint); font-size: 0.72rem; }
.cg-del {
  background: none;
  border: 0;
  color: var(--ink-dim);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.cg-del:hover { color: var(--accent-soft); }

/* graded markers in the binder + checklist */
.card-slot.is-graded .owned-check { background: #9ad5ff; color: #062032; }
.cl-row.graded .cl-box { background: #9ad5ff; border-color: #9ad5ff; color: #062032; }

/* ---------- Showcase ---------- */
.showcase[hidden] { display: none !important; }
.showcase { max-width: 1100px; margin: 0 auto; padding: 8px 16px 60px; }
.sb-intro { margin-bottom: var(--s-5); }
.sb-stats {
  display: flex;
  justify-content: center;
  gap: var(--s-6);
  padding: var(--s-4) var(--s-5);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--e-1);
  width: max-content;
  max-width: 100%;
  margin: 0 auto;
}
.sb-note,
.sb-empty {
  text-align: center;
  color: var(--ink-dim);
  font-size: var(--fs-xs);
  margin-top: var(--s-3);
}
.sb-empty { color: var(--ink-dim); font-size: var(--fs-sm); }
.sb-intro em { display: block; font-style: normal; font-size: 0.74rem; color: var(--ink-faint); margin-top: 4px; }

.sb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 18px; }
.sc-item {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-3) var(--s-3) var(--s-4);
  box-shadow: var(--e-1);
  cursor: pointer;
  font: inherit;
  color: var(--ink);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 3px;
  transition: transform 0.12s, border-color 0.12s;
}
.sc-item:hover { transform: translateY(-3px); border-color: var(--gold); }
.sc-item.is-slab:hover { border-color: #9ad5ff; }

/* a bare card, as it would sit in the binder */
.raw-art {
  display: block;
  border-radius: 6px;
  overflow: hidden;
  background: var(--slot-bg);
  aspect-ratio: 600/838;
  margin-bottom: 10px;
}
.raw-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* graded cards sit in a plastic case with a grading label on top */
.slab {
  display: block;
  /* Fixed, like every other slab colour: this is a plastic case, not type.
     It was var(--ink), which is near-black in light mode — PSA and CGC slabs
     (the two that don't set their own case colour) rendered as black bricks. */
  background: #e9ecf2;
  border-radius: 9px;
  padding: 8px 8px 12px;
  margin-bottom: 10px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.8), 0 4px 14px rgba(0,0,0,0.45);
}
.slab-label {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
  border-radius: 3px;
  padding: 5px 8px;
  margin-bottom: 7px;
}
.slab-label u {
  text-decoration: none;
  font-size: 0.52rem;
  font-weight: 900;
  letter-spacing: 1px;
}
.slab-label b {
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  line-height: 1.1;
  text-align: center;
}
.slab-label i {
  font-style: normal;
  font-size: 1.1rem;
  font-weight: 900;
  line-height: 1;
}

/* The small company name (`u`) is 8.3px, so it needs AA against its own plate:
   the gold plate's #6b5316 sat at 3.16:1 and CGC's #9ecbff at 3.53:1. Darkened
   / lightened just enough to clear it while staying the real label colour.
   Each company's slab, following their real label colours.
   PSA: red-bordered white. Beckett: silver / gold (Pristine & Gem Mint) /
   black (Black Label). CGC: blue, gold for Pristine. SGC: black "tuxedo".
   TAG, ACE, AGS, ARS get their own distinct treatments. */
.slab-psa .slab-label { background: #fff; border: 2px solid #d0242c; color: #141821; }
.slab-psa .slab-label u { color: #d0242c; }

.slab-bgs-silver { background: linear-gradient(160deg, #dfe3ea, #dfe3ea 55%, #dfe3ea); }
.slab-bgs-silver .slab-label { background: linear-gradient(180deg, #dfe3ea, #dfe3ea); border: 1px solid #a8adba; color: #141821; }
.slab-bgs-silver .slab-label u { color: #555e77; }

.slab-bgs-gold { background: linear-gradient(160deg, #f6ecd2, #d9bd7f 55%, #f2e6c8); }
.slab-bgs-gold .slab-label { background: linear-gradient(180deg, #f3e3b8, #c9a659); border: 1px solid #a8863c; color: #241c05; }
.slab-bgs-gold .slab-label u { color: #503d0c; }

.slab-bgs-black { background: linear-gradient(160deg, #2b3140, #141821 55%, #2a2f3a); }
.slab-bgs-black .slab-label { background: #0e1116; border: 1px solid #3b4254; color: #fff; }
.slab-bgs-black .slab-label u { color: #c9a659; }

.slab-cgc .slab-label { background: linear-gradient(180deg, #1a63b8, #0d417e); border: 1px solid #0a2f5c; color: #fff; }
.slab-cgc .slab-label u { color: #cfe7ff; }

.slab-cgc-gold { background: linear-gradient(160deg, #f6ecd2, #d9bd7f 55%, #f2e6c8); }
.slab-cgc-gold .slab-label { background: linear-gradient(180deg, #f3e3b8, #c9a659); border: 1px solid #a8863c; color: #241c05; }
.slab-cgc-gold .slab-label u { color: #503d0c; }

.slab-sgc { background: linear-gradient(160deg, #2a2f3a, #0e1116 55%, #2a2f3a); }
.slab-sgc .slab-label { background: #0e1116; border: 1px solid #2b3140; color: #fff; }
.slab-sgc .slab-label u { color: #a8adba; }

.slab-tag { background: linear-gradient(160deg, #2a2f3a, #0e1116 55%, #20242c); }
.slab-tag .slab-label { background: #0e1116; border: 1px solid #2f6f6a; color: #eaf7f6; }
.slab-tag .slab-label u { color: #4fd1c5; }



.slab-arena-gold { background: linear-gradient(160deg, #f6ecd2, #d9bd7f 55%, #f2e6c8); }
.slab-arena-gold .slab-label { background: linear-gradient(180deg, #f3e3b8, #c9a659); border: 1px solid #a8863c; color: #241c05; }
.slab-arena-gold .slab-label u { color: #503d0c; }

.slab-arena-silver { background: linear-gradient(160deg, #dfe3ea, #dfe3ea 55%, #dfe3ea); }
.slab-arena-silver .slab-label { background: linear-gradient(180deg, #dfe3ea, #dfe3ea); border: 1px solid #a8adba; color: #141821; }
.slab-arena-silver .slab-label u { color: #555e77; }

.slab-arena-black { background: linear-gradient(160deg, #2a2f3a, #0e1116 55%, #20242c); }
.slab-arena-black .slab-label { background: #0e1116; border: 1px solid #3b4254; color: #fff; }
.slab-arena-black .slab-label u { color: #a8adba; }

.slab-art {
  display: block;
  border-radius: 3px;
  overflow: hidden;
  /* The mat behind the card photo, inside a light plastic case — fixed, like
     the case itself. var(--ink) is the theme's TEXT colour, so in light mode a
     card whose image hasn't loaded left a black hole in a white slab. */
  background: #cdd3de;
  aspect-ratio: 600/838;
}
.slab-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.sc-name { font-size: 0.88rem; font-weight: 700; line-height: 1.25; }
.sc-set {
  font-size: var(--fs-xs);
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.sc-meta { font-size: 0.7rem; color: var(--ink-dim); }
.sc-val {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--gold-ink);
  margin-top: 6px;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.sc-val i { font-style: normal; font-size: 0.68rem; font-weight: 500; color: var(--ink-dim); }

/* "view more" at the foot of the most-valuable list */
.hc-showcase {
  width: 100%;
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 11px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: none;
  color: var(--gold-ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.hc-showcase:hover {
  border-color: var(--line-strong);
  background: var(--surface-3);
}
.hs-icon, .hs-go { display: flex; }
.hs-icon .ic, .hs-go .ic { width: 15px; height: 15px; }

/* Navigation menu, top-right of every view. Replaced a lone Showcase pill:
   with Home, Sets and Showcase all worth reaching from anywhere, one control
   that lists them beats one shortcut that doesn't. */
.navmenu { position: absolute; right: var(--s-4); top: var(--s-5); }

.nav-toggle {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.14s, background 0.14s;
}
/* Red on hover/open reads as an error — the same reason the set tiles stopped
   turning red. Gold is this app's "active" colour. */
.nav-toggle:hover { border-color: var(--line-strong); background: var(--surface-3); }
.nav-toggle.open { border-color: var(--gold); background: var(--surface-3); }

/* the three lines; the middle one fades and the outer two cross when open */
.nt-bars { display: block; width: 18px; height: 12px; position: relative; }
.nt-bars i {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.18s ease, opacity 0.14s ease;
}
.nt-bars i:nth-child(1) { top: 0; }
.nt-bars i:nth-child(2) { top: 5px; }
.nt-bars i:nth-child(3) { top: 10px; }
.nav-toggle.open .nt-bars i:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle.open .nt-bars i:nth-child(2) { opacity: 0; }
.nav-toggle.open .nt-bars i:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* a quiet marker that there's something in the Showcase */
.nt-dot {
  position: absolute;
  top: -3px;
  right: -3px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--gold);
  border: 2px solid var(--bg);
}
.nt-dot[hidden] { display: none !important; }

.nav-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 208px;
  padding: var(--s-2);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--e-3);
  text-align: left;
  z-index: 60;
}
.nav-panel[hidden] { display: none !important; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 11px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 0.92rem;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.nav-item[hidden] { display: none !important; }
.nav-item:hover { background: var(--surface-3); }
.nav-item.on { color: var(--gold-ink); }
.ni-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  flex: 0 0 18px;
  color: var(--ink-faint);
}
.ni-icon .ic { width: 17px; height: 17px; }
.nav-item:hover .ni-icon,
.nav-item.on .ni-icon { color: var(--gold-ink); }
.ni-count {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink-dim);
  font-size: 0.74rem;
  font-weight: 700;
}
.nav-item.on .ni-count { color: var(--gold-ink); }
.nav-sep { height: 1px; margin: 5px 8px; background: var(--line); }

/* ---------- Add Graded Card sheet ---------- */
.gr-modal[hidden] { display: none !important; }
.gr-modal {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-5);
}
.gr-backdrop { position: absolute; inset: 0; background: rgba(4, 6, 11, 0.85); }
.gr-sheet {
  position: relative;
  width: min(560px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--surface-3);
  border-radius: 16px;
  box-shadow: 0 26px 80px rgba(0,0,0,0.75);
}
.gr-top {
  display: flex;
  align-items: center;
  padding: 16px 18px;
  border-bottom: 1px solid var(--surface-2);
  position: relative;
}
.gr-top h2 { flex: 1; text-align: center; font-size: 1.15rem; }
/* This sheet was modelled on a Collectr screenshot and kept their teal
   (#6fd7cf / #2f9e94) — the one screen in the app that wasn't gold. Adding a
   slab is a collection action, so it follows the same rule as the card page:
   gold is the primary action. */
.gr-close {
  position: absolute;
  left: 18px;
  background: none;
  border: 0;
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
  padding: 4px;
}
.gr-body { padding: 18px; display: flex; flex-direction: column; gap: 18px; }

.gr-card { display: flex; gap: 14px; align-items: flex-start; }
.gr-card img { width: 74px; border-radius: 6px; display: block; background: var(--slot-bg); }
.gr-card-text h3 { font-size: 1.02rem; line-height: 1.25; margin-bottom: 6px; }
.gr-card-text p {
  display: flex;
  gap: 10px;
  align-items: baseline;
  justify-content: space-between;
  font-size: 0.84rem;
  color: var(--ink-dim);
}
.gr-card-text b { font-size: 1.05rem; color: var(--ink); white-space: nowrap; }

/* grading company picker */
.gr-graders {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}
.gr-grader {
  flex: 0 0 auto;
  min-width: 74px;
  padding: 14px 10px;
  border-radius: 10px;
  border: 2px solid var(--surface-3);
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.6px;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.gr-grader:hover { border-color: var(--line-strong); }
.gr-grader.on {
  border-color: var(--gold);
  background: rgba(244, 201, 93, 0.16);
  color: var(--ink);
}

.gr-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.gr-field { position: relative; display: block; }
.gr-field > span {
  position: absolute;
  top: -7px;
  left: 12px;
  padding: 0 6px;
  background: var(--bg);
  font-size: 0.68rem;
  color: var(--ink-dim);
}
.gr-field select, .gr-field input {
  width: 100%;
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  padding: 15px 13px;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
}
.gr-field select:focus, .gr-field input:focus { outline: none; border-color: var(--gold); box-shadow: var(--focus); }

.gr-foot { padding: 4px 18px 20px; }
.gr-add {
  width: 100%;
  padding: 16px;
  border: 0;
  border-radius: 999px;
  background: var(--gold);
  color: #1a1408;
  font: inherit;
  font-size: 1rem;
  font-weight: 800;
  cursor: pointer;
  transition: filter 0.12s;
}
.gr-add:hover { filter: brightness(1.07); }

.cg-slab em { font-style: normal; color: var(--ink-dim); font-size: 0.72rem; }
.slab-val i { font-style: normal; color: var(--ink-dim); font-size: 0.72rem; margin-left: 4px; }

@media (max-width: 560px) {
  .gr-modal { padding: 0; align-items: flex-end; }
  .gr-sheet { border-radius: 16px 16px 0 0; max-height: 96vh; }
  .gr-fields { grid-template-columns: 1fr; }
}

/* ---------- Selects: drop the browser default look ---------- */
.gr-field select,
.cl-sort,
.layout-pick select {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%238b93a7' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  padding-right: 36px;
  text-overflow: ellipsis;
}
.gr-field select:hover, .cl-sort:hover, .layout-pick select:hover { border-color: var(--line-strong); }
/* the popup list itself can't be styled, but at least match the theme */
.gr-field select option,
.cl-sort option,
.layout-pick select option {
  background: var(--slot-bg);
  color: var(--ink);
}

/* graded sheet fields, tightened up */
.gr-field select, .gr-field input {
  background-color: var(--bg);
  font-weight: 600;
  letter-spacing: 0.2px;
  transition: border-color 0.12s, background 0.12s;
}
.gr-field input::placeholder { color: var(--line-strong); font-weight: 400; }
.gr-field select:focus, .gr-field input:focus { background-color: var(--bg); }
.gr-field input[type="number"] { -moz-appearance: textfield; }
.gr-field input[type="number"]::-webkit-outer-spin-button,
.gr-field input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* raw vs graded price on the sheet */
.gr-price-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  background: var(--bg);
  border: 1px solid var(--surface-3);
  border-radius: 10px;
  padding: 10px 13px;
}
.gr-price-row span { font-size: 0.72rem; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.8px; }
.gr-price-row b { font-size: 1.1rem; }
.gr-price-row.pending b { font-size: 0.78rem; color: var(--ink-faint); font-weight: 500; text-transform: none; letter-spacing: 0; }

/* showcase sort bar */
.sb-toolbar[hidden] { display: none !important; }
.sb-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin-bottom: var(--s-5);
}
.sb-toolbar .sb-search { flex: 1 1 240px; }
.sb-toolbar .cl-sort-wrap { flex: 0 0 auto; }
.sb-search { flex: 1 1 260px; min-width: 200px; }
.sb-none {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--ink-dim);
  font-size: 0.86rem;
  padding: 30px;
}
@media (max-width: 700px) {
  .sb-toolbar { justify-content: stretch; }
  .sb-toolbar .sb-search { flex: 1 1 100%; }
  /* The label sat beside the select and left it about 100px, so every value
     truncated — "All ga…", "Everyth…", "Value: hi…". You could not read what
     was filtered. Stacking gives the select the whole column. */
  .sb-toolbar .cl-sort-wrap {
    /* exactly two per row, using the full width — a 140px basis left each
       select about 85px, too narrow for "Value: high to low" */
    flex: 1 1 calc(50% - 6px);
    flex-direction: column;
    align-items: stretch;
    gap: 3px;
  }
  /* 36px of right padding for the dropdown arrow left 103px of text room, and
     "Value: high to low" needs 110px. */
  .sb-toolbar .cl-sort { width: 100%; font-size: 0.78rem; padding-right: 28px; background-position: right 8px center; }
}

/* A tapped set tile, while its card data is still downloading.
   ⚠️ This must NOT live on .t-cover::after — that pseudo-element IS the scrim
   behind the set wordmark, so overriding its background stripped the
   wordmark's dark backing for as long as the load took. The tile's own
   ::after is free, and sweeping the whole tile reads better anyway. */
.set-tile { position: relative; }
.set-tile.is-loading { cursor: progress; }
.set-tile.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  background: linear-gradient(100deg, transparent 20%, rgba(209, 171, 82, 0.22) 50%, transparent 80%);
  background-size: 220% 100%;
  animation: tile-load 1s linear infinite;
}
@keyframes tile-load { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@media (prefers-reduced-motion: reduce) {
  .set-tile.is-loading::after { animation: none; background: rgba(209, 171, 82, 0.16); }
}

/* A quiet offer to install the app. Deliberately NOT a warning: a standing
   "back up or lose everything" banner makes the product look fragile, and the
   real answer to durability is sign-in sync, not nagging. */
.notice[hidden] { display: none !important; }
.notice {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-3) var(--s-4);
  max-width: 900px;
  margin: 0 auto var(--s-5);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.notice p { margin: 0; font-size: var(--fs-sm); color: var(--ink); line-height: 1.5; }
.nt-icon { display: flex; color: var(--ink-dim); }
.nt-icon .ic { width: 20px; height: 20px; }
.nt-actions { display: flex; gap: var(--s-2); align-items: center; }
.nt-go, .nt-dismiss {
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 700;
  padding: 10px var(--s-4);
  border-radius: var(--r-full);
  cursor: pointer;
  white-space: nowrap;
  min-height: 40px;
}
.nt-go { border: 0; background: var(--gold); color: #1a1408; }
.nt-go:hover { filter: brightness(1.06); }
.nt-dismiss { border: 1px solid var(--line-strong); background: none; color: var(--ink-dim); font-weight: 600; }
.nt-dismiss:hover { background: var(--surface-3); color: var(--ink); }
@media (max-width: 620px) {
  .notice { grid-template-columns: auto 1fr; }
  .nt-actions { grid-column: 1 / -1; }
  .nt-go, .nt-dismiss { flex: 1; }
}
/* a brief message for failures that would otherwise be silent */
.toast {
  position: fixed;
  /* left:50% alone shrink-to-fits into the remaining half of the viewport —
     the box came out 188px wide on a phone and wrapped to four lines. Pinning
     both edges and centring with auto margins lets it use the full width. */
  left: 16px;
  right: 16px;
  margin: 0 auto;
  width: fit-content;
  bottom: 24px;
  transform: translateY(12px);
  z-index: 60;
  max-width: min(420px, calc(100vw - 32px));
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  color: var(--ink);
  box-shadow: var(--e-3);
  font-size: var(--fs-sm);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
}
.toast.on { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .toast { transition: none; } }

/* ---------- Collection value chart ---------- */
.hc-chart[hidden] { display: none !important; }
.hc-chart { margin: 4px 0 20px; }
.hcc-head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 9px;
}
.hcc-change { font-size: 0.92rem; font-weight: 800; }
.hcc-change.up { color: var(--good); }
.hcc-change.down { color: var(--bad); }
.hcc-change em { font-style: normal; font-weight: 500; color: var(--ink-dim); font-size: 0.78rem; margin-left: 4px; }

.hcc-ranges { display: flex; flex-wrap: wrap; gap: 4px; }
.hcc-range {
  padding: 5px 11px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--slot-bg);
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.hcc-range:hover { border-color: var(--line-strong); color: var(--ink); }
.hcc-range.on { background: var(--surface-3); border-color: var(--gold); color: var(--gold-ink); }

.hcc-graph {
  position: relative;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 6px 8px;
}
.hcc-graph svg { display: block; width: 100%; height: 150px; }
.hcc-hi, .hcc-lo {
  position: absolute;
  right: 10px;
  font-size: 0.64rem;
  color: var(--ink);
  background: var(--surface-3);
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  padding: 1px 4px;
  border-radius: 3px;
}
.hcc-hi { top: 6px; }
.hcc-lo { bottom: 6px; }
.hcc-axis {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.66rem;
  color: var(--ink-faint);
  padding: 6px 2px 0;
}
.hcc-axis em { font-style: normal; text-align: center; flex: 1; }

@media (max-width: 620px) {
  .hcc-axis em { display: none; }
}

/* ---------- Your copies (date + price paid) ---------- */
.cm-copies[hidden] { display: none !important; }
.cm-copies { border-top: 1px solid var(--line); padding-top: 14px; margin-bottom: 16px; }
.cp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.cp-head h4 {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
}
.cp-add {
  background: none;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  font: inherit;
  font-size: 0.74rem;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 7px;
  cursor: pointer;
}
.cp-add:hover { border-color: var(--gold); color: var(--gold-ink); }

.cp-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.cp-list li {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
}
.cp-field { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.cp-field > span {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--ink-dim);
}
.cp-field input {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 7px 9px;
  color: var(--ink);
  font: inherit;
  font-size: 0.8rem;
}
.cp-field input:focus { outline: none; border-color: var(--gold); }
.cp-field input::placeholder { color: var(--line-strong); }
.cp-field input[type="number"] { -moz-appearance: textfield; }
.cp-field input[type="number"]::-webkit-outer-spin-button,
.cp-field input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cp-del {
  background: none;
  border: 0;
  color: var(--ink-dim);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px 8px;
}
.cp-del:hover { color: var(--accent-soft); }
.cp-note { font-size: 0.68rem; color: var(--ink-faint); line-height: 1.5; margin-top: 8px; }

/* a slab row: summary on top, its date/price fields underneath */
.cg-item { flex-direction: column; align-items: stretch; gap: 8px; }
.cg-top { display: flex; align-items: center; gap: 10px; }
.cg-fields { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
@media (max-width: 620px) { .cg-fields { grid-template-columns: 1fr 1fr; } }

/* ---------- Profit & loss ---------- */
.hc-pl {
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 18px;
}
.hc-pl.empty { display: flex; flex-direction: column; gap: 5px; }
.pl-title {
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
  font-weight: 700;
}
.hc-pl.empty p { font-size: 0.8rem; line-height: 1.55; color: var(--ink-dim); }
.pl-row { display: flex; flex-wrap: wrap; gap: 26px; align-items: baseline; }
.pl-stat span {
  display: block;
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--ink-dim);
}
.pl-stat strong { font-size: 1.15rem; }
.pl-stat.big strong { font-size: 1.35rem; }
.pl-stat.big.up strong { color: var(--good); }
.pl-stat.big.down strong { color: var(--bad); }
.pl-stat.big em { font-style: normal; font-size: 0.85rem; margin-left: 6px; opacity: 0.85; }
.pl-note { font-size: 0.68rem; color: var(--ink-faint); margin-top: 9px; }

/* ---------- Backup & restore ---------- */
.backup {
  margin-top: var(--s-7);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  align-items: center;
  justify-content: space-between;
}
.bk-text { flex: 1 1 320px; }
.bk-text h3 { font-size: 0.98rem; margin-bottom: 5px; }
.bk-text p { font-size: 0.8rem; line-height: 1.55; color: var(--ink-dim); }
.bk-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.bk-btn {
  padding: 10px 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-strong);
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.14s, background 0.14s;
}
.bk-btn:hover { border-color: var(--line-strong); background: var(--surface-3); }
.bk-btn.primary { background: var(--gold); border-color: var(--gold); color: #241c05; font-weight: 600; }
.bk-btn.primary:hover { filter: brightness(1.04); background: var(--gold); }
/* The Replace button only appears once a backup file is loaded, so it escaped
   the contrast sweep: #ffb3bc ink sat at ~1.5:1 on a light surface, and the
   hover painted a fixed dark red behind themed ink. Both follow the theme now. */
.bk-btn.danger { border-color: #6b2b33; color: var(--bad); }
.bk-btn.danger:hover { border-color: var(--bad); background: rgba(192, 36, 52, 0.12); }

.bk-confirm[hidden] { display: none !important; }
.bk-confirm {
  flex: 1 0 100%;
  border-top: 1px solid var(--line);
  padding-top: 15px;
  margin-top: 4px;
}
.bk-confirm p { font-size: 0.84rem; line-height: 1.55; color: var(--ink-dim); margin-bottom: 11px; }
.bk-confirm b { color: var(--ink); }
.bk-error { color: var(--bad) !important; }
.bk-choice { display: flex; flex-wrap: wrap; gap: 8px; }

/* English / Japanese tabs over the set grid. Modelled on Collectr's language
   switcher: a single rounded track with the active tab raised out of it. */
.lang-tabs {
  display: flex;
  gap: 4px;
  align-self: center;
  margin: 0 auto 22px;
  padding: 4px;
  background: var(--slot-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  width: max-content;
  max-width: 100%;
}
.lang-tabs[hidden] { display: none !important; }
.lang-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 20px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-weight: 700;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background 0.14s, color 0.14s;
}
.lang-tab:hover { color: var(--ink); }
.lang-tab.on {
  background: var(--bg-page);
  color: var(--ink);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}
.lang-tab .lt-count {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--ink-dim);
  background: var(--bg);
  border-radius: 999px;
  padding: 2px 8px;
}
.lang-tab.on .lt-count { color: var(--gold-ink); }


/* yuyu-tei is the shop the Japanese prices come from, so it doubles as the
   "where do I actually buy this" link on Japanese cards. */
.cm-link.yuyu { background: #1f6f4a; border-color: #2b8d61; }
.cm-link.yuyu:hover { background: #268257; }
.cm-link[hidden] { display: none !important; }

/* Japanese printings are listed under their English name; this marks them.
   Small enough to scan past, clear enough to tell two printings apart in the
   Showcase where both languages sit side by side. */
.jp-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--jp-ink);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  vertical-align: 1px;
}
/* the Japanese name, kept as a subtitle under the English one */
.cm-name-alt {
  margin: 2px 0 0;
  color: var(--ink-dim);
  font-size: 0.92rem;
}
.cm-name-alt[hidden] { display: none !important; }

/* Japanese prices come from a Japanese shop, converted from yen — a different
   number from what the card fetches in the US. Say so rather than implying a
   US market value we don't have yet. */
.cm-price-note {
  margin: 6px 0 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink-dim);
}

/* the marketplace name under a buy button's label */
.cm-link .cl-sub {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  opacity: 0.72;
  margin-top: 1px;
}

/* section heading inside the navigation menu */
.nav-label {
  margin: 6px 11px 3px;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* "Games" opens a submenu on hover or keyboard focus; clicking it opens the
   Games page instead, which lists the same choices — so a touch device, where
   there is no hover, never loses access to anything. */
.nav-sub { position: relative; }
.ni-more { margin-left: auto; display: inline-flex; color: var(--ink-faint); }
.ni-more .ic { width: 15px; height: 15px; }
.nav-item.on .ni-more { color: var(--gold-ink); }

.nav-subpanel {
  display: none;
  position: absolute;
  right: calc(100% + 6px);
  top: -6px;
  min-width: 230px;
  white-space: nowrap;
  padding: 6px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.5);
  z-index: 70;
}
.nav-sub:hover .nav-subpanel,
.nav-sub.open .nav-subpanel { display: block; }
/* a hover bridge, so the pointer can cross the gap without the panel closing */
.nav-sub:hover .nav-subpanel::before {
  content: "";
  position: absolute;
  right: -8px;
  top: 0;
  width: 8px;
  height: 100%;
}

/* the Games page reuses the home tile styling */
.gamespage { max-width: 1180px; margin: 0 auto; padding: 8px 16px 40px; }
.gamespage[hidden] { display: none !important; }

@media (max-width: 700px) {
  /* The last crumb always names the current page — and the <h1> directly
     beneath it says exactly the same thing. On a phone that cost a whole line
     and pushed the trail onto two, leaving a stranded "›" at the end of the
     first. Drop the current page and its separator; every ancestor stays
     clickable, so Home is still one tap away. */
  .crumbs > .crumb.here { display: none; }
  .crumbs > .crumb-sep:nth-last-child(2) { display: none; }
  /* "Home › Games › One Piece Card Game" needed 289px against 287px available
     — it wrapped by two pixels. Trimming the tap padding keeps it on one line
     while staying comfortably above the 44px touch target with the trail's
     own line height. */
  .crumb { font-size: 0.78rem; padding: 11px 6px; }

  /* Touch targets: the layout and sort menus came out at 35px and 39px, and a
     checklist row at 38px. 44px is the size a thumb actually hits. */
  select { min-height: 44px; }
  .cl-row { min-height: 44px; }

  /* Inside its own set the prefix is on every slot and there is no room for it
     next to the ⓘ button. Cross-set reprints keep theirs (no .num-pre). */
  .card-slot .num-pre { display: none; }

  /* no hover on a phone: the submenu drops below its parent instead */
  .nav-subpanel {
    position: static;
    min-width: 0;
    margin: 4px 0 2px 12px;
    border-radius: 8px;
    box-shadow: none;
    white-space: normal;
  }
}

/* On Home the topbar title IS the wordmark; every other view sets text there. */
.topbar h1:has(.title-logo) {
  max-width: min(380px, 94%);
  letter-spacing: 0;
}
.title-logo {
  display: block;
  /* Reserve the menu button's width plus a gap so the wordmark never runs
     underneath it on a phone. */
  width: min(360px, calc(100vw - 150px));
  height: auto;
  margin: 0 auto;
}
.title-logo-light { display: none; }
:root[data-theme="light"] .title-logo-dark { display: none; }
:root[data-theme="light"] .title-logo-light { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .title-logo-dark { display: none; }
  :root:not([data-theme="dark"]) .title-logo-light { display: block; }
}

/* six feature cards sit as 3x2; the note underneath answers "what's the catch" */
.features-note {
  text-align: center;
  font-size: var(--fs-xs);
  color: var(--ink-faint);
  margin: 0 0 var(--s-2);
}

/* Appearance picker in the nav menu — a segmented control, not a dropdown, so
   the current state is visible without opening anything. */
.theme-pick {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-1);
  margin: var(--s-1) var(--s-2) var(--s-1);
  padding: var(--s-1);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.theme-pick button {
  padding: var(--s-2) var(--s-1);
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: var(--fs-2xs);
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.theme-pick button:hover { color: var(--ink); }
.theme-pick button.on {
  background: var(--surface-3);
  color: var(--gold-ink);
}

/* Bandai's wordmark comes in white and black ink; show whichever the theme
   needs. Both are in the markup because CSS media queries can't read the
   data-theme attribute that an explicit choice sets. */
.game-tile .g-logo img.g-logo-light { display: none; }
:root[data-theme="light"] .game-tile .g-logo img.g-logo-dark { display: none; }
:root[data-theme="light"] .game-tile .g-logo img.g-logo-light { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .game-tile .g-logo img.g-logo-dark { display: none; }
  :root:not([data-theme="dark"]) .game-tile .g-logo img.g-logo-light { display: block; }
}

/* Drawn icons: one grid, one weight, inheriting colour from their context. */
.ic { display: block; flex: none; stroke: currentColor; }

/* the Variant field is hidden for printings that only come one way */
.gr-field[hidden] { display: none !important; }

/* Certification number: links straight to that slab's page on the grader's
   own site, where the grade and usually photos of the exact slab live. */
.cp-cert input { font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.cg-cert-link {
  display: inline-block;
  margin-top: var(--s-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--link);
  text-decoration: none;
}
.cg-cert-link:hover { text-decoration: underline; text-underline-offset: 2px; }
.gr-field span em {
  font-style: normal;
  font-weight: 400;
  color: var(--ink-faint);
  text-transform: none;
  letter-spacing: 0;
}

/* cert number on a Showcase slab */
.sc-cert {
  margin-top: var(--s-1);
  font-size: var(--fs-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}
.sc-cert a { color: var(--link); text-decoration: none; }
.sc-cert a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* Day-over-day movement, above the lifetime profit figures. Measures price
   only — cards bought today aren't counted as a gain. */
.pl-today {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  margin-bottom: var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
}
.pl-today[hidden] { display: none !important; }
.plt-label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.plt-val { font-size: var(--fs-md); font-weight: 700; }
.plt-val em { font-style: normal; font-size: var(--fs-sm); font-weight: 600; opacity: 0.85; }
.pl-today.up .plt-val { color: var(--good); }
.pl-today.down .plt-val { color: var(--bad); }
.pl-today.flat .plt-val { color: var(--ink-dim); font-size: var(--fs-sm); font-weight: 600; }
/* the movement line and the chart's change line sit inches apart and answer
   different questions — this one is price only, the chart's includes cards you
   added — so it says which it is */
.plt-note {
  font-size: var(--fs-2xs);
  color: var(--ink-dim);
  margin-left: auto;
}
@media (max-width: 560px) { .plt-note { display: none; } }

/* On a phone these wrapped as flex and orphaned their last stat onto a row of
   its own with a 22px gap above it — "Sets started" and "Profit" both looked
   detached from the group. A grid keeps them as one tidy block. */
@media (max-width: 560px) {
  /* .hc-stats is a flex item inside .hc-head; without this it shrank to a
     single 92px column and stacked the three stats vertically. */
  .hc-head { flex-wrap: wrap; }
  .hc-stats { flex: 1 1 100%; }

  .hc-stats,
  .pl-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
    gap: var(--s-3) var(--s-4);
    align-items: start;
  }
  /* Profit carries the biggest number and its percentage, which won't sit in a
     half-width column — give it the full row rather than let it wrap. */
  .pl-stat.big { grid-column: 1 / -1; }

  /* "MARKET VALUE" wrapped to two lines in an 89px column while its neighbours
     stayed on one, dropping its figure out of line with theirs. */
  .hc-stat span,
  .pl-stat span { font-size: 0.6rem; letter-spacing: 0.4px; }

  /* Seven range buttons wrapped 6 + 1, stranding "All" on a line of its own.
     An equal seven-column grid fits them across at ~44px each. */
  .hcc-ranges {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
  }
  .hcc-range { padding-left: 0; padding-right: 0; text-align: center; }
}
