/* ==========================================================================
   TITANS COLLECTIBLES

   Rebuilt when the site became a price guide. The stylesheet had reached
   209KB, most of which styled a card product that no longer exists, pack
   openings, tier ladders, a portrait studio, an animated opening sequence.
   What remains is the design system, the navigation, the legal pages, the
   marketplace and the guide.
   ========================================================================== */

@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrumentserif-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrumentserif-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-var.woff2") format("woff2");
  font-weight: 400 800; font-stretch: 62% 125%; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/plexmono-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/plexmono-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

:root {
  color-scheme: light;

  /* DAYLIGHT. The owner retired the night-mode look for an open sky, the
     token NAMES survive (ink is still the ground, bone still the text) so
     every rule in this sheet re-themes without being touched; only the
     VALUES swapped sides of the day. The animated sky itself is painted by
     body::before / body::after below. */
  --sky-zenith:  #7FACD8;
  --sky-mid:     #B0CFEA;
  --sky-horizon: #E4F0FA;
  --sky-glow:    #F7EAD6;

  --ink:    #FFFFFF;
  --ink-2:  #F3F8FC;
  --ink-3:  #E9F2F9;
  --line:   #C6D6E5;
  --line-2: #A7BFD4;

  /* Frosted glass, now white over blue rather than black over black. Alpha is
     still set for legibility against the brightest sky state. */
  --panel:      rgba(255, 255, 255, 0.9);
  --panel-line: rgba(130, 160, 195, 0.55);
  --panel-body: #2C3F55;

  --bone:   #16293E;
  --bone-2: #3D5168;
  --bone-3: #42556E;

  /* Gold darkened to antique brass: the old #C6A15B read at 2.4:1 on daylight,
     which is decoration, not text. "hi" is now the DARKER of the pair, because
     on a light ground emphasis means more ink, not more light. */
  --gold:    #7A5E1F;
  --gold-hi: #6B521C;

  /* Dark text for gold-filled chips and buttons, whatever the theme does. */
  --on-gold: #241D0E;

  --vis:    #A67716;
  --vis-hi: #7C5A10;
  --deal:    #2E7D64;
  --deal-hi: #1F5C49;

  --display: "Instrument Serif", Georgia, serif;
  --sans:    "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, Menlo, monospace;

  --t-display: clamp(2.6rem, 6.4vw, 5.75rem);
  --t-title:   clamp(2rem, 4.3vw, 3.6rem);
  --t-head:    clamp(1.45rem, 2.6vw, 2.15rem);
  --t-lede:    clamp(1.0625rem, 1.3vw, 1.25rem);
  --t-small:   0.875rem;
  --t-label:   0.6875rem;
  --t-micro:   0.625rem;

  --max:       1400px;
  --gutter:    clamp(1.25rem, 4.5vw, 4rem);
  --section-y: clamp(5rem, 10vw, 8.5rem);

  --ease:     cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --nav-h: 68px;
  --bar-h: 34px;
  /* Everything that has to clear the fixed header clears the whole header, not
     just the nav, the status bar sits above it. */
  --top-h: calc(var(--nav-h) + var(--bar-h));
}

*, *::before, *::after { box-sizing: border-box; }
/* The ground colour lives on <html> so <body> can be transparent and let the
   fixed sky show through behind every section. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--ink); }

/* ---- The sky --------------------------------------------------------------
   The whole site sits under one animated daytime sky, fixed to the viewport
   so every page and every scroll position shares the same weather.

   Two layers, both pure CSS, no script, no images, nothing to load:

     body::before  the air. A gradient taller than the viewport, drifting
                   slowly, with a warm glow low in the east corner.
     body::after   the clouds. Soft white radial blobs in three repeating
                   bands, each band a different size and speed, so the drift
                   never visibly loops.

   The animations move background-position only, compositor work, no layout,
   no paint storms, and stop entirely for anyone who asked for reduced
   motion, leaving a perfectly good still sky. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(40% 70% at 0% 40%, rgba(127,172,216,0.16), rgba(127,172,216,0) 70%),
    radial-gradient(40% 70% at 100% 65%, rgba(127,172,216,0.14), rgba(127,172,216,0) 70%),
    #ffffff;
}
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(closest-side at 30% 30%, rgba(127,172,216,0.5) 25%, rgba(127,172,216,0) 75%),
    radial-gradient(closest-side at 55% 68%, rgba(127,172,216,0.34) 20%, rgba(127,172,216,0) 72%),
    radial-gradient(closest-side at 70% 25%, rgba(127,172,216,0.46) 25%, rgba(127,172,216,0) 75%),
    radial-gradient(closest-side at 42% 70%, rgba(127,172,216,0.3) 20%, rgba(127,172,216,0) 72%);
  background-size: 240px 420px, 200px 520px, 230px 460px, 190px 560px;
  background-position: left 0, left 0, right 0, right 0;
  background-repeat: repeat-y;
  animation: clouds-drift 160s linear infinite;
}
@keyframes sky-breathe { from, to { opacity: 1; } }
@keyframes clouds-drift {
  from { background-position: left 0,      left 0,      right 0,      right 0; }
  /* Each column rises by its own tile height, so all four loop seamlessly at
     their own speeds. */
  to   { background-position: left -420px, left -520px, right -460px, right -560px; }
}
@media (prefers-reduced-motion: reduce) {
  body::before, body::after { animation: none; }
}
body {
  margin: 0;
  background: transparent;
  color: var(--bone);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* clip, not hidden: hidden turns the body into a scroll container, and a
     scroll container swallows position:sticky for every descendant, which is
     exactly how the marketplace filter bar silently stopped sticking. clip
     cuts overflow identically without creating a scroll container. */
  overflow-x: clip;
}

/* `[hidden]` is a browser default, and ANY author rule setting display beats
   it, so `.combo__panel { display: flex }` left every dropdown permanently
   open on screen while `el.hidden` read true in script. This makes the
   attribute mean what it says, everywhere, once. */
[hidden] {
  display: none !important;
}
img, svg { display: block; max-width: 100%; }
button, input, select { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, p, figure, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--gold); color: #fff; }

body::before {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(110% 62% at 22% -8%, rgba(232, 180, 92, 0.13), transparent 60%),
    radial-gradient(95% 58% at 84% 4%, rgba(111, 168, 148, 0.10), transparent 58%);
}

/* ---------- Primitives ---------- */
.wrap {
  position: relative; z-index: 1;
  width: 100%; max-width: var(--max);
  margin-inline: auto; padding-inline: var(--gutter);
}
.label {
  font-family: var(--mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--bone-2);
}
.label--gold { color: var(--gold); }
.micro {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--bone-3);
}
.display {
  font-family: var(--display); font-weight: 400;
  line-height: 0.92; letter-spacing: -0.032em; text-wrap: balance;
}
.display em { font-style: italic; color: var(--gold); }
.lede {
  font-size: var(--t-lede); line-height: 1.55;
  color: var(--bone-2); max-width: 52ch; letter-spacing: -0.008em;
}
.tabular { font-variant-numeric: tabular-nums; }
/* Available to a screen reader, absent from the page. Used where the visual
   hierarchy is obvious but the heading outline would otherwise skip a level. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

.btn {
  display: inline-flex; align-items: center; gap: 0.7em;
  padding: 0.9rem 1.5rem;
  font-family: var(--mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  border: 1px solid var(--line-2); background: transparent; color: var(--bone);
  cursor: pointer;
  transition: background 0.4s var(--ease), color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.btn:hover { border-color: var(--gold); color: var(--gold-hi); }
.btn--fill { background: var(--gold); border-color: var(--gold); color: var(--on-gold); }
.btn--fill:hover { background: var(--gold-hi); border-color: var(--gold-hi); color: var(--on-gold); }
.btn:disabled { cursor: not-allowed; border-color: var(--line); color: var(--bone-3); background: transparent; }
.btn--fill:disabled { background: var(--line); border-color: var(--line); }
.btn__arrow { transition: transform 0.4s var(--ease); }
.btn:hover:not(:disabled) .btn__arrow { transform: translateX(4px); }
/* A button that carries its own status line. Kept inside the button so the
   status travels with the control rather than floating near it. */
/* Reads as a control at a glance: a thick gold rule and a lit ground, so it is
   not mistaken for a line of text sitting next to the filled button. */
.btn--stacked {
  flex-direction: column; gap: 0.35em; line-height: 1.1;
  border: 2px solid var(--gold); color: var(--gold-hi);
  background: rgba(198, 161, 91, 0.12);
}
.btn--stacked:hover {
  border-color: var(--gold-hi); background: rgba(198, 161, 91, 0.22); color: #FFF6E0;
}
.btn__soon { font-size: 0.5625rem; letter-spacing: 0.18em; color: var(--gold); }
.btn--stacked:hover .btn__soon { color: var(--gold-hi); }

.tlink {
  display: inline-block;
  font-family: var(--mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; padding-bottom: 0.3em;
  background-image: linear-gradient(var(--gold), var(--gold));
  background-repeat: no-repeat; background-position: 0 100%; background-size: 0% 1px;
  transition: background-size 0.5s var(--ease-out), color 0.4s var(--ease);
}
.tlink:hover { color: var(--gold-hi); background-size: 100% 1px; }

/* ==========================================================================
   Navigation
   ========================================================================== */
/* ---------- Status bar ---------- */
/* Height is auto so the line can wrap on a phone, and is measured back into
   --bar-h by script, everything below offsets against it. */
.topbar {
  position: fixed; inset: 0 0 auto; z-index: 62;
  display: grid; place-items: center;
  padding-block: 0.55rem;
  background: #16120A;
  border-bottom: 1px solid rgba(198, 161, 91, 0.34);
}
.topbar__text {
  display: flex; align-items: center; gap: 0.6rem;
  padding-inline: var(--gutter); text-align: center; text-wrap: balance;
  font-family: var(--mono); font-size: var(--t-micro); font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-hi);
  line-height: 1.5;
}
.topbar__dot {
  flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--gold);
}

.nav {
  position: fixed; inset: var(--bar-h) 0 auto; z-index: 60; height: var(--nav-h);
  display: flex; align-items: center; border-bottom: 1px solid transparent;
  transition: background 0.5s var(--ease), border-color 0.5s var(--ease);
}
.nav.is-stuck { background: var(--ink); backdrop-filter: none; border-bottom-color: var(--line); }
.nav__inner {
  width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
}
/* The wordmark is the word, set in the display serif. No icon competing with it. */
.mark { display: flex; align-items: baseline; gap: 0.6rem; white-space: nowrap; }
.mark__name {
  font-family: var(--display); font-weight: 400;
  font-size: 1.9rem; letter-spacing: -0.02em; color: var(--bone);
}
.mark__sub {
  font-family: var(--mono); font-size: 0.6875rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--bone-2);
}
.nav__links { display: flex; align-items: center; gap: clamp(1.1rem, 2.2vw, 2.25rem); }
.nav__link {
  font-family: var(--mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--bone-2);
  transition: color 0.35s var(--ease);
}
.nav__link:hover { color: var(--bone); }
.nav__link[aria-current="page"] { color: var(--gold); }
/* A nav item that carries a status under its name. The label keeps the row's
   baseline; the status hangs below it without moving anything else. */
.nav__link--stacked { position: relative; display: inline-block; }
.nav__soon {
  position: absolute; left: 0; top: calc(100% + 0.32em); white-space: nowrap;
  font-size: 0.5625rem; letter-spacing: 0.14em; color: var(--gold);
}
.menu__soon {
  display: inline-block; vertical-align: middle; margin-left: 0.6em;
  font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold);
}
.nav__toggle {
  display: none; justify-self: end; border: 0; background: none; cursor: pointer; padding: 0.5rem 0;
  font-family: var(--mono); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--bone);
}

/* ==========================================================================
   Section rail
   Every section is named at all times. The one you are in is largest; hovering
   any of them grows it, so the list reads as a place you are standing in.
   ========================================================================== */
.sidenav {
  /* Sizing lives in tokens so narrower windows shrink the rail instead of losing it. */
  --rail-w: 150px;
  --rail-w-on: 190px;
  --rail-name: 0.625rem;
  --rail-name-on: 0.8125rem;
  --rail-pad: 1.5rem;   /* nine entries now, keeps the stack inside a short viewport */

  position: fixed; z-index: 45;
  left: clamp(0.75rem, 2.4vw, 2.5rem); top: 50%; transform: translateY(-50%);
  pointer-events: auto;
}
.sidenav[hidden] { display: none; }
/* A spine down the left, a numbered entry per section, and a rule that extends
   and brightens on the one you are in. Every name stays legible; the current
   section is simply larger. */
/* The spine sits at x=0 and each rule starts on it, so they meet as clean T
   junctions. Text is inset by its own padding and never touches either line. */
/* The rail floats over a sky that runs from near-black to near-white across the
   page, so grey-on-transparent was legible for about half of it. It carries its
   own dark plate now, and the names are gold: one colour that holds against
   every state the sky passes through. */
.sidenav__list {
  position: relative;
  padding: 0.5rem 0.75rem 0.5rem 0;
  background: #FBFDFF;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(198, 161, 91, 0.22);
  border-left: 0;
}
.sidenav__list::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px; background: linear-gradient(180deg, transparent, var(--gold) 18%, var(--gold) 82%, transparent);
}

.sidenav__link {
  display: block;
  width: var(--rail-w); padding: var(--rail-pad) 0 var(--rail-pad) 1.15rem;
  border-bottom: 1px solid rgba(198, 161, 91, 0.16);
  transition: width 0.5s var(--ease-out), border-color 0.4s var(--ease);
}
.sidenav__item:last-child .sidenav__link { border-bottom: 0; }
/* Names are never truncated, the rule is sized to hold the longest label at its
   largest size, so nothing ever resolves to an ellipsis. */
.sidenav__name {
  display: block;
  font-family: var(--mono); font-weight: 500; font-size: var(--rail-name);
  letter-spacing: 0.16em; text-transform: uppercase; color: #C9AE79;
  white-space: nowrap; overflow: visible; line-height: 1;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
  transition: font-size 0.4s var(--ease-out), color 0.35s var(--ease);
}

.sidenav__item.is-active .sidenav__link { width: var(--rail-w-on); border-bottom-color: var(--gold); }
.sidenav__item.is-active .sidenav__name { font-size: var(--rail-name-on); color: #FFF0CC; }

.sidenav__link:hover { width: var(--rail-w-on); border-bottom-color: var(--gold); }
.sidenav__link:hover .sidenav__name { font-size: var(--rail-name-on); color: #FFF6E0; }
.menu {
  position: fixed; inset: 0; z-index: 55; background: var(--ink-2);
  display: flex; flex-direction: column; justify-content: center; gap: 0.3rem;
  padding: var(--top-h) var(--gutter) var(--gutter);
  clip-path: inset(0 0 100% 0); visibility: hidden;
  transition: clip-path 0.7s var(--ease-out);
}
.menu.is-open { clip-path: inset(0 0 0 0); visibility: visible; }
.menu__link { font-family: var(--display); font-size: clamp(2rem, 8vw, 3.25rem); line-height: 1.2; letter-spacing: -0.03em; }
.menu__link:hover { color: var(--gold); }

/* ==========================================================================
   Views
   ========================================================================== */
.view { position: relative; z-index: 1; display: block; }
.view[hidden] { display: none; }
.view.is-entering { animation: viewIn 0.65s var(--ease-out) both; }
@keyframes viewIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

.band { padding-block: var(--section-y); }
.band + .band { border-top: 1px solid var(--line); }

/* ==========================================================================

   Legal pages
   Documents, not marketing: one column, generous measure, and no decoration
   competing with the text. The one visual device is the placeholder, every
   value only the company can supply is marked, so an unfinished document
   cannot be mistaken for a finished one at a glance.
   ========================================================================== */
/* Clears the fixed banner and nav, the same way every other full page does. */
.legal { padding-block: calc(var(--top-h) + clamp(2rem, 4vw, 3.25rem)) clamp(3rem, 7vw, 6rem); }
.legal__wrap { max-width: 78ch; }
.legal__back { display: inline-block; margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.legal__meta {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--bone-3); margin-top: 0.9rem;
}
.legal__lede { margin-top: 1rem; max-width: 58ch; }

/* The draft warning. Deliberately the loudest thing on the page, these
   documents are not finished and must not read as though they are. */
.legal__flag {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  padding: clamp(0.9rem, 2vw, 1.25rem) clamp(1rem, 2.4vw, 1.6rem);
  background: rgba(198, 161, 91, 0.09);
  border: 1px solid rgba(198, 161, 91, 0.42);
  border-left: 3px solid var(--gold);
  color: #E7DCC6;
}
.legal__flag p { font-size: var(--t-small); line-height: 1.6; }
.legal__flagTitle {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold-hi); margin-bottom: 0.4rem;
}

.legal__sec { margin-top: clamp(2rem, 4.5vw, 3.25rem); }
.legal__sec h2 {
  font-family: var(--display); font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  color: var(--bone-hi); margin-bottom: 0.7rem; line-height: 1.2;
}
.legal__sec p, .legal__list li {
  color: var(--bone); font-size: var(--t-body); line-height: 1.7;
}
.legal__sec p + p { margin-top: 0.85rem; }
.legal__list { margin-top: 0.85rem; display: flex; flex-direction: column; gap: 0.55rem; }
.legal__list li { position: relative; padding-left: 1.1rem; }
.legal__list li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 4px; height: 4px; background: var(--gold);
}
.legal__note { margin-top: 1rem; color: var(--bone-2); font-size: var(--t-small); }

/* The lawful-basis table. Wide content gets its own scroller so the page body
   never moves sideways on a phone. */
.legal__table {
  width: 100%; margin-top: 1.1rem; border-collapse: collapse;
  font-size: var(--t-small); display: block; overflow-x: auto;
}
.legal__table th, .legal__table td {
  text-align: left; vertical-align: top; padding: 0.7rem 1rem 0.7rem 0;
  border-bottom: 1px solid var(--line); color: var(--bone);
  min-width: 14ch;
}
.legal__table th {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bone-3); border-bottom-color: var(--gold);
}

/* Contact addresses, one card per subject. */
.legal__cards {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(0.9rem, 2vw, 1.4rem);
}
.legal__card {
  padding: clamp(0.9rem, 2vw, 1.3rem);
  background: var(--panel); border: 1px solid var(--panel-line);
  border-left: 2px solid var(--gold);
  display: flex; flex-direction: column; gap: 0.45rem;
}
.legal__addr { font-family: var(--mono); font-size: var(--t-small); word-break: break-all; }
.legal__cardBody { color: var(--bone-2); font-size: var(--t-small); line-height: 1.6; }

/* Anything only the company can fill in. Marked rather than blank, so the gap
   is visible in a screenshot and in a print-out, not just in the source. */
/* A filter that looks like a filter.
   The chips elsewhere are underlined words in a row, which reads as a heading
   followed by links, you cannot tell it is a control until you click one. In
   the shop they are pills inside a labelled, bordered group: the group says
   what you are choosing, and the filled pill says what is chosen. */
.filter--group {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.45rem;
  padding: 0.55rem 0.75rem 0.6rem;
  border: 1px solid var(--panel-line);
  background: rgba(255, 255, 255, 0.02);
}
.filter--group .filter__legend { color: var(--bone-2); }
.filter__chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.filter--group .chip {
  padding: 0.32rem 0.7rem; border: 1px solid var(--line); border-bottom-width: 1px;
  border-radius: 999px; color: var(--bone-2);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease),
              background-color 0.25s var(--ease);
}
.filter--group .chip:hover { color: var(--bone-hi); border-color: var(--bone-3); }
.filter--group .chip[aria-pressed="true"] {
  color: var(--on-gold); background: var(--gold); border-color: var(--gold);
}
/* On the mine ground the group needs a warmer edge than the neutral panel line. */
#view-packs .filter--group {
  border-color: rgba(198, 161, 91, 0.3); background: rgba(20, 13, 6, 0.5);
}
#view-packs .filter--group .chip { border-color: rgba(198, 161, 91, 0.34); color: #CBB89B; }
#view-packs .filter--group .chip:hover { color: #FFF3DE; border-color: rgba(232, 193, 115, 0.7); }
#view-packs .filter--group .chip[aria-pressed="true"] {
  color: #201404; background: var(--gold); border-color: var(--gold);
}

/* The board runs four of these side by side, so once they are bordered the row
   needs its own spacing, the old gap was sized for text separated by air. */
.filters:has(.filter--group) { gap: 0.75rem; align-items: stretch; }
/* Sort is one of the four now, not a trailing control. The auto margin shoved it
   onto a line of its own and right-aligned it there, which read as a stray box
   rather than the last filter in the set. */
.filter--group.filter--sort { margin-left: 0; justify-content: space-between; }
.filter--group .select { width: 100%; padding-block: 0.3rem; }

/* Cool edges on the field, warm ones down the mine. The chip colours have to be
   re-stated at this specificity because the view-level rules that set the page's
   type colour are id-scoped and would otherwise win. */
#view-market .filter--group {
  border-color: rgba(138, 158, 226, 0.3); background: rgba(10, 14, 34, 0.5);
}
#view-market .filter--group .chip {
  border-color: rgba(138, 158, 226, 0.34); color: #C2CBEA;
}
#view-market .filter--group .chip:hover {
  color: #FFFFFF; border-color: rgba(180, 198, 255, 0.7); background: rgba(140, 164, 255, 0.12);
}
#view-market .filter--group .chip[aria-pressed="true"] {
  color: #0B1020; background: var(--gold); border-color: var(--gold);
}
#view-market .filter--group .filter__legend { color: #AEB9DC; }

/* Wraps. These were nowrap so a placeholder like [company number] stayed on one
   line, but a long one in a narrow column then pushed the whole document
   sideways on a phone, 153px of horizontal scroll on the privacy notice. A
   placeholder breaking across two lines costs nothing; a page that scrolls
   sideways costs the reader everything. */
.ph {
  color: #F0C97A; background: rgba(198, 161, 91, 0.14);
  border-bottom: 1px dashed rgba(240, 201, 122, 0.6);
  padding: 0 0.25em; font-family: var(--mono); font-size: 0.94em;
  overflow-wrap: anywhere;
}
.foot__entity { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }

/* ==========================================================================
   Responsive, for the components declared above
   These have to sit after their own base rules. A media query adds no
   specificity, so a plain rule written later in the file wins over an earlier
   `@media` block regardless of the viewport, which is how the opportunity
   section stayed two columns on a phone.
   ========================================================================== */
@media (max-width: 1080px) {
  .shop__notes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ring svg { max-height: min(46vh, 380px); }
}
/* The two sign-up forms are the point of this section, so on a short window the
   ring gives way to them rather than the other way round. Declared here so it
   sits after the width-based cap above. */
/* The opportunity section carries a diagram and two forms, so it starts giving
   way earlier than the rest of the page. */
/* 860, not 790. Between those two heights nothing compacted and The
   Opportunity was a dozen pixels over, a gap in the ladder rather than a
   section that was too tall. */
@media (max-height: 860px) {
  .oppLede { font-size: clamp(1rem, min(2vw, 2.7vh), 1.7rem); }
  .boom { padding: clamp(0.85rem, 1.9vw, 1.3rem); gap: 0.55rem; }
  .sign { padding-top: 0.7rem; gap: 0.45rem; }
  .sign__note { min-height: 0; }
  /* Collections is the tightest section, and on a 720-tall window it was two
     pixels over, which is enough to fail the fit check and switch snapping off
     for the whole page. It starts compacting here rather than at 680. */
  #sets .head { margin-bottom: clamp(0.5rem, 1.6vh, 1.4rem); }
  #sets .next { margin-top: clamp(0.6rem, 1.5vh, 1.5rem); padding-top: clamp(0.55rem, 1.3vh, 1rem); }
  #sets .setcard { padding: clamp(0.7rem, 1.5vh, 1.4rem) clamp(0.85rem, 1.6vh, 1.4rem); }
}
@media (max-height: 680px) {
  .ring svg { max-height: min(37vh, 236px); }
  .boom { padding: 0.75rem 0.9rem; gap: 0.45rem; }
  .boom__body { line-height: 1.45; }
  /* The Opportunity is measured with snapping already applied, because turning
     snapping on is what adds the header clearance that makes it overflow, measuring without it reports a fit that stops being true a frame later. */
  #opportunity .head { margin-bottom: 0.6rem; }
  #opportunity .opp { gap: clamp(0.75rem, 2vw, 1.5rem); }
  .oppLede { font-size: clamp(0.95rem, min(1.9vw, 2.5vh), 1.5rem); }
  .oppLede--sub { margin-top: 0.5rem; padding-top: 0.5rem; }
  .rules { padding-block: 0.6rem 0.7rem; margin-bottom: 0.6rem; }
  .boom__title { font-size: clamp(0.9rem, min(1.5vw, 2.1vh), 1.2rem); }
  .sign__row .form__field { padding: 0.5rem 0.7rem; }
  .sign__note { min-height: 0; }
  .sign__v { margin-top: 0.15rem; }
  /* Collections is the tightest section on a short window. Everything here is a
     size reduction, not a removal, the tiles still say what they said. */
  #sets .head { margin-bottom: 0.5rem; }
  #sets .next { margin-top: 0.6rem; padding-top: 0.55rem; }
  #sets .next__item { padding: 0.35rem 0.6rem; gap: 0.45rem; }
  #sets .next__badge { width: 1.4rem; height: 1.4rem; }
  #sets .setcard { padding: 0.7rem 0.85rem; }
}
/* The floor. Below this the three tallest sections, Card Types, Collections
   and The Opportunity, were each a handful of pixels over, and a single
   section overflowing anywhere switches snapping off for the whole page, so
   the cost of missing by two pixels is the same as missing by two hundred. */
@media (max-height: 660px) {
  #types .type__float { height: clamp(2.6rem, 7.4vh, 3.6rem); }
  #types .type { gap: 0.3rem; }
  #sets .setcard .logo { max-height: 3.1rem; }
  #sets .setcard__unlock { gap: 0.3rem; }
  #sets .setcard__face { width: 2rem; height: 2.6rem; }
  #sets .setcard { padding: 0.55rem 0.7rem; gap: 0.35rem; }
  #sets .next__item { padding: 0.28rem 0.5rem; }
  #sets .next { margin-top: 0.45rem; padding-top: 0.45rem; }
  #sets .head { margin-bottom: 0.35rem; }
  .boom { padding: 0.7rem 0.85rem; gap: 0.4rem; }
  .ring svg { max-height: min(35vh, 214px); }
  /* The two sign-up forms are most of the Opportunity column's height. Every
     line of copy stays; the space around it is what gives way. */
  .sign { padding-top: 0.5rem; gap: 0.3rem; }
  .sign__row .form__field { padding: 0.38rem 0.6rem; }
  .sign__note { line-height: 1.35; }
  #opportunity .head { margin-bottom: 0.45rem; }
  #opportunity .opp { gap: 0.7rem; }
}
/* The rig and the chart stay side by side as long as there are two columns
   worth of room. Stacking them at 1080 doubled the section's height and pushed
   it off a screen on a narrow laptop, where two columns still fit fine. */
@media (max-width: 900px) {
  .opp { grid-template-columns: minmax(0, 1fr); gap: clamp(1rem, 3vw, 2rem); }
  .shop__head { grid-template-columns: minmax(0, 1fr); }
  .shop__trust { flex-direction: row; flex-wrap: wrap; gap: 0.5rem 1.5rem; }
  .filter--sort { margin-left: 0; }
  .shop__count { margin-left: 0; }
  /* The board folds to two columns, so the terms stack under the name rather
     than staying right-aligned against an edge that is no longer there. */
  .listing__terms { text-align: left; align-items: flex-start; }
}
@media (max-width: 700px) {
  .shop { grid-template-columns: minmax(0, 1fr); }
  .shop__notes { grid-template-columns: minmax(0, 1fr); }
  .prodcard__stage { min-height: 220px; }
  .bidbox__row { flex-direction: column; gap: 0.75rem; }
  .bidbox__clock { text-align: left; }
  .shop__bar { gap: 0.75rem 1.25rem; }
}
/* Text inside an SVG scales with the drawing, so on a phone it has to be set
   larger in viewBox units to survive being shrunk to fit. */
@media (max-width: 560px) {
  .rg__label { font-size: 15px; letter-spacing: 0.06em; }
  .rg__halfName { font-size: 22px; }
  .rg__halfNote { font-size: 13px; }
  .rg__sealText { font-size: 12px; }
  .ring svg { max-height: none; }
}

/* ==========================================================================
   Opener, once only
   After the intro has run, every animation belonging to it is switched off and
   pinned to its finished state. Clicking a section can then only ever scroll.
   ========================================================================== */
.intro-done .opener             { display: none !important; }
/* Belt and braces: even if the class were re-applied, the home view cannot replay. */
.intro-done #view-home.is-entering { animation: none !important; opacity: 1; transform: none; }
.intro-done .reveal-line > span { animation: none !important; transform: none; }
.intro-done .fade-up            { animation: none !important; opacity: 1; transform: none; }
.intro-done .spread__deal       { animation: none !important; opacity: 1; transform: none; filter: none; }
.intro-done .bolt               { animation: none !important; opacity: 0; }
.intro-done .spread__slot::after { animation: none !important; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal-line > span, .fade-up, .obs { opacity: 1; transform: none; }
  .tc__tilt { transform: none !important; }
  /* Nothing may sit behind a delay waiting for an animation that will not play. */
  .spread__deal, .bolt, .spread__slot::after { animation-delay: 0s !important; }
  .bolt, .spread__slot::after, .opener { display: none; }
  .spread__deal { opacity: 1; filter: none; }
  .trail::after { transition: none; }
  .stop__panel { animation: none; }
}

/* ==========================================================================
   Phones
   Three separate problems, all of which only exist on a touch device and none
   of which show up in a desktop window narrowed to 375px:

   1. iOS Safari zooms the whole page when you focus an input whose text is
      under 16px, and it does not zoom back out. Every field here was 11-13px.
   2. Fingers are not cursors. A 33x34 menu button is a miss waiting to happen;
      the platform guidance is 44px, and the nav toggle was the worst offender
      because it is the only way into the menu.
   3. Notched phones put the status bar and the home indicator over the page.
   ========================================================================== */

/* --- Safe areas ---------------------------------------------------------- */
/* The fixed banner paints up into the notch and pads its own text down out of
   it, so the colour goes edge to edge but nothing is ever hidden behind the
   sensor housing. --top-h has to grow by the same amount, because every snapped
   section and every page heading offsets against it. */
:root {
  --top-h: calc(var(--nav-h) + var(--bar-h) + env(safe-area-inset-top, 0px));
}
.topbar { padding-top: calc(0.55rem + env(safe-area-inset-top, 0px)); }
/* `top` only, the base rule's `inset` shorthand already pins left and right,
   and adding `inset-block-start: auto` here (its logical alias) cancelled the
   line above it and dropped the nav off the page entirely. */
.nav { top: calc(var(--bar-h) + env(safe-area-inset-top, 0px)); }
.wrap, .nav__inner, .topbar__text {
  padding-inline: max(var(--gutter), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
}
.foot { padding-bottom: calc(2.25rem + env(safe-area-inset-bottom, 0px)); }

/* --- Touch devices ------------------------------------------------------- */
@media (pointer: coarse) {
  /* 16px is the threshold, not a preference: below it iOS zooms on focus. */
  input, select, textarea { font-size: 16px; }
  .search__field, .select, .form__field, .verify__field { font-size: 16px; }

  /* Hit areas. Where a control cannot physically be 44px, an inline text link
     inside a paragraph, it is left alone rather than given padding that would
     break the line it sits in. */
  .nav__toggle { min-width: 44px; min-height: 44px; padding: 0.5rem 0.25rem; }
  .menu__link { min-height: 44px; display: flex; align-items: center; }
  .btn, .cartbtn, .chip, .search__clear { min-height: 44px; }
  .chip { padding-block: 0.5rem; }
  .filter--group .chip { padding: 0.55rem 0.85rem; }
  .foot__cols .tlink, .legal__back,
  .setcard__foot .tlink { min-height: 44px; display: inline-flex; align-items: center; }
  /* An inline serial inside a sentence cannot be 44px tall without opening up
     the line it sits in. It gets the hit area anyway, via padding cancelled by
     an equal negative margin, so the text around it does not move. */
  .verify__sample {
    padding-block: 0.85rem; margin-block: -0.85rem;
    padding-inline: 0.3rem; margin-inline: -0.3rem;
  }
  .rung, .type, .next__item { touch-action: manipulation; }

  /* The blue flash Safari and Chrome paint over a tapped element fights every
     colour on the site. The controls have their own pressed states. */
  a, button, input, select, .chip { -webkit-tap-highlight-color: rgba(198, 161, 91, 0.18); }

  /* The card tilt follows a pointer. On a touchscreen there is no pointer to
     follow, so the transform just sticks wherever the last tap landed. */
  .tc__tilt { transform: none !important; }
}

/* --- Layout at phone widths ---------------------------------------------- */
@media (max-width: 560px) {
  /* The banner is two lines on a phone. Centre the dot with the first line
     rather than the middle of the block. */
  .topbar__text { align-items: flex-start; }
  .topbar__dot { margin-top: 0.42em; }

  /* One product per row, and the 3D objects get room to be seen. */
  .shop { grid-template-columns: minmax(0, 1fr); }
  .legal__cards { grid-template-columns: minmax(0, 1fr); }

  /* Filter groups go full width so their chips wrap inside a predictable box
     instead of each group being a different ragged width. */
  .filter--group { width: 100%; }
  .filters:has(.filter--group) { gap: 0.6rem; }

  /* The footer's four columns stack; two-up wastes the width on labels. */
  .foot__cols { gap: 0.6rem; }
}


/* ==========================================================================
   The marketplace
   Statically generated pages, sharing every token, font and control with the
   hand-written site. They are a different kind of page, a grid of other
   people's listings rather than our own product, but they have to read as the
   same company, so nothing here invents a new visual language.
   ========================================================================== */
:root {
  --spark-up: #6FA894;
  --spark-down: #C97F6A;
}

/* The generated pages have a static header rather than the fixed one the
   single-page site uses, so content starts below it rather than under it. */
.nav--static { position: sticky; top: 0; background: var(--ink);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line); }
body.mkt { background: var(--ink); }
.mktpage, .mktitem { padding-block: clamp(2rem, 5vw, 3.5rem) clamp(3rem, 7vw, 5rem); }

/* ---- Index head ---------------------------------------------------------- */
.mkt__head { max-width: 62ch; }
.mkt__lede { margin-top: 1rem; color: var(--bone); }
.mkt__disclaim {
  margin-top: 1rem; font-size: var(--t-small); color: var(--bone-2);
}

/* ---- Price tiers, as the headline control -------------------------------
   "Under $100" is a feature, not a dropdown entry. The cheap end is where most
   collectors start and it is what makes the index feel alive on a slow day, so
   it leads. */
/* Tier tiles retired, price ranges are a dropdown filter with counts now. */

.tierchip[aria-pressed="true"] .tierchip__label,
.tierchip[aria-pressed="true"] .tierchip__n { color: var(--on-gold); }
.tierchip__label { font-family: var(--mono); font-size: var(--t-label); letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--bone); }
.tierchip__n { font-family: var(--display); font-size: 1.5rem; color: var(--gold-hi); }

.mkt__tools { margin-top: clamp(1.5rem, 3vw, 2rem); }
.mkt__source { margin-top: 1.25rem; color: var(--bone-2); }

/* ---- The grid ------------------------------------------------------------ */
.mkt__grid {
  margin-top: 1rem;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: clamp(0.9rem, 2vw, 1.4rem);
}
.mcard { border: 1px solid var(--panel-line); background: var(--panel); display: flex; }
.mcard[hidden] { display: none; }
.mcard__link { display: flex; flex-direction: column; width: 100%; }
.mcard:hover { border-color: rgba(198, 161, 91, 0.5); }

/* Hotlinked from the source, never rehosted, no storage cost, no bandwidth
   cost, and no question about who owns the photograph. */
.mcard__shot { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--ink-2); }
.mcard__shot img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease); }
.mcard:hover .mcard__shot img { transform: scale(1.04); }
.mcard__noimg { display: block; width: 100%; height: 100%;
  background: repeating-linear-gradient(135deg, var(--ink-2) 0 10px, var(--ink-3) 10px 20px); }
.mcard__tier {
  position: absolute; left: 0; bottom: 0;
  padding: 0.3rem 0.6rem; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.1em; text-transform: uppercase;
  background: rgba(255, 255, 255, 0.94); color: var(--bone);
  border-top-right-radius: 8px;
}
.tier--entry { border-top: 2px solid #6FA894; }
.tier--mid { border-top: 2px solid #7FA0C4; }
.tier--high { border-top: 2px solid #C6A15B; }
.tier--grail { border-top: 2px solid #C97F6A; }

.mcard__body { padding: 0.85rem 0.95rem 1rem; display: flex; flex-direction: column; gap: 0.45rem; flex: 1; }
.mcard__title { font-size: var(--t-small); line-height: 1.4; color: var(--bone-hi); }
.mcard__reason { font-size: var(--t-micro); line-height: 1.5; color: var(--bone-2); flex: 1; }
.mcard__foot { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem;
  padding-top: 0.5rem; border-top: 1px solid var(--line); }
.mcard__price { font-family: var(--display); font-size: 1.15rem; color: var(--gold-hi); }
.mcard__source { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--bone-3); }
.mkt__empty { margin-top: 2rem; color: var(--bone-2); }

/* ---- An item ------------------------------------------------------------- */
.mktitem__back { display: inline-block; margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.mktitem__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem); align-items: start; }
/* A plain block, because the gallery inside it now owns its own layout. This
   was a three-column grid for the old flat strip of four images, which made
   the whole gallery a single third-width cell and rendered every photograph at
   a third of its intended size. */
.mktitem__media { display: block; }
.mktitem__img { width: 100%; border: 1px solid var(--panel-line); background: var(--ink-2); }
.mktitem__noimg { aspect-ratio: 4 / 3; display: grid; place-items: center;
  border: 1px dashed var(--line); color: var(--bone-3); font-family: var(--mono);
  font-size: var(--t-micro); letter-spacing: 0.12em; text-transform: uppercase; }

.mktitem__title { font-size: var(--t-title); margin-top: 0.6rem; line-height: 1.15; }
.mktitem__reason { margin-top: 0.9rem; color: var(--bone); font-size: var(--t-body); line-height: 1.6; }
.mktitem__note { margin-top: 0.85rem; color: var(--bone-2); font-size: var(--t-small); line-height: 1.65;
  border-left: 2px solid var(--gold); padding-left: 0.9rem; }

.mktitem__pricebox { margin-top: 1.5rem; padding: 1rem 1.15rem; background: var(--panel);
  border: 1px solid var(--panel-line); display: flex; flex-direction: column; gap: 0.35rem; align-items: flex-start; }
.mktitem__price { font-family: var(--display); font-size: 2.25rem; color: var(--gold-hi); line-height: 1; }
.mktitem__tier { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--bone-2); padding-top: 0.3rem; }
.mktitem__go { margin-top: 1.15rem; }
.mktitem__disclaim { margin-top: 0.75rem; font-size: var(--t-micro); color: var(--bone-3); line-height: 1.6; }

/* ---- The archive state ----------------------------------------------------
   The most misleading thing on the site if it is done carelessly. An inferred
   price is never rendered as a sale, the badge and the wording both carry the
   distinction, not just one of them. */
.arch { margin-top: 1.5rem; padding: 1rem 1.15rem; background: var(--panel);
  border: 1px solid var(--panel-line); border-left: 2px solid var(--bone-3); }
.arch__line { color: var(--bone); font-size: var(--t-body); line-height: 1.6; }
.arch__line strong { color: var(--gold-hi); font-family: var(--display); font-size: 1.2em; }
.arch__explain { margin-top: 0.6rem; font-size: var(--t-micro); color: var(--bone-3); line-height: 1.6; }
.arch__badge { display: inline-block; margin-left: 0.4rem; padding: 0.15rem 0.5rem;
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.1em; text-transform: uppercase;
  border: 1px solid var(--line); color: var(--bone-2); }
.arch__badge--confirmed { border-color: #6FA894; color: #8FBFAE; }
.arch__badge--inferred { border-color: #9A8046; color: #C6A15B; }

/* ---- Price history -------------------------------------------------------- */
.mktitem__history { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.spark { width: 100%; height: auto; margin-top: 0.75rem; display: block; }
.spark__line { fill: none; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.spark__dot { fill: var(--bone-2); }
.spark__gone { fill: none; stroke: var(--bone-3); stroke-width: 1.2; }
.spark__legend { margin-top: 0.5rem; display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: var(--t-micro); color: var(--bone-3); }
.spark__thin, .spark__none { margin-top: 0.5rem; font-size: var(--t-micro); color: var(--bone-3); line-height: 1.6; }

.mktitem__about { margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.mktitem__blurb { margin-top: 0.5rem; color: var(--bone-2); font-size: var(--t-small); line-height: 1.65; }

@media (max-width: 860px) {
  .mktitem__grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .mkt__tiers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mkt__grid { grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); }
}

/* ---- When the source's photograph has gone ---------------------------------
   Hotlinking costs nothing and keeps the copyright question simple, but it
   means we do not control how long a picture lasts. A listing ends, the source
   drops the file, and the archive page, which stays up forever, would show a
   broken-image icon. It shows the same woven placeholder an image-less listing
   gets instead, and says so where there is room to. */
.mcard__shot img.is-broken,
.mktitem__img.is-broken {
  display: block; min-height: 8rem;
  background: repeating-linear-gradient(135deg, var(--ink-2) 0 10px, var(--ink-3) 10px 20px);
  border: 1px solid var(--line);
  /* An <img> with no src is still a replaced element, and the browser draws its
     own small broken-picture glyph in the corner on top of the background above, so the card ends up showing a placeholder AND an error icon. `content`
     replaces what a replaced element renders, which suppresses the glyph and
     leaves the weave clean. */
  content: "";
}
.mktitem__media.has-broken-image::after {
  content: "The source no longer serves this photograph.";
  display: block;
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--bone-3); text-align: center;
  padding-top: 0.4rem;
}

/* ---- Company, person and tier pages ----------------------------------------
   The editorial sits above the grid on every one of these, because the writing
   is the part a grid cannot supply and the reason the page ranks at all. */
.ent { max-width: 68ch; }
.ent__founded { margin-top: 0.5rem; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--bone-3); }
.ent__blurb { margin-top: 1.1rem; color: var(--bone); font-size: var(--t-body); line-height: 1.7; }
.ent__stats { margin-top: 1rem; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold); }
.ent__people { margin-top: 0.75rem; font-size: var(--t-small); color: var(--bone-2); line-height: 1.8; }
.ent__section { margin-top: clamp(2rem, 5vw, 3.25rem); }
.ent__h2 { font-family: var(--display); font-size: clamp(1.35rem, 2.6vw, 1.9rem); color: var(--bone-hi); }
.ent__sub { margin-top: 0.4rem; color: var(--bone-2); font-size: var(--t-small); line-height: 1.6; max-width: 62ch; }
.ent__section .mkt__grid { margin-top: 1.25rem; }

/* ---- The results archive ---------------------------------------------------
   The most linkable page here, so the confidence distinction gets real design
   attention rather than a footnote: the key explains all three states before
   the table starts, and every row carries both a badge and words. */
.results__key {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0.9rem;
}
.results__keyItem { padding: 0.9rem 1rem; background: var(--panel); border: 1px solid var(--panel-line); }
.results__keyItem p { margin-top: 0.5rem; font-size: var(--t-micro); color: var(--bone-2); line-height: 1.6; }

.results { margin-top: 1.25rem; border-top: 1px solid var(--line); }
.results__head, .results__row {
  display: grid; grid-template-columns: minmax(0, 2.4fr) minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1.3fr);
  gap: 1rem; padding: 0.85rem 0.25rem; align-items: baseline;
  border-bottom: 1px solid var(--line);
}
.results__head { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--bone-3); }
.results__row:hover { background: rgba(198, 161, 91, 0.06); }
.results__title { color: var(--bone-hi); font-size: var(--t-small); line-height: 1.4; }
.results__price { font-family: var(--display); font-size: 1.1rem; color: var(--gold-hi); }
.results__when { font-family: var(--mono); font-size: var(--t-micro); color: var(--bone-2); }
.results__note { display: block; margin-top: 0.3rem; font-size: var(--t-micro); color: var(--bone-3); }

/* Titans' own cards on a shared surface. A site-wide banner would be wrong over
   a real listing someone can buy, so the card says it instead. */
.mcard--ours { border-color: rgba(198, 161, 91, 0.4); }
.mcard__ours {
  position: absolute; right: 0; bottom: 0;
  padding: 0.3rem 0.55rem; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.08em; text-transform: uppercase;
  background: var(--gold); color: var(--on-gold);
}

@media (max-width: 720px) {
  .results__head { display: none; }
  .results__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 0.35rem; }
  .results__title { grid-column: 1 / -1; }
  .results__how { grid-column: 1 / -1; }
}

/* ==========================================================================
   Marketplace, second pass: the sticky filter bar, grouped cards, the sold
   strip, and the item page's related-listings modules.

   The old chip rows grew linearly with the roster, at 104 companies they were
   most of the viewport. One bar of dropdowns stays one bar at any roster size,
   and the active choices surface as removable tags underneath, since a closed
   dropdown hides its own selection.
   ========================================================================== */
.mbar {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--ink) 92%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-block: 1px solid var(--line);
  padding: 0.65rem 0;
  margin-bottom: 1.75rem;
}
.mbar__inner {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
}
.mbar__search {
  flex: 1 1 11rem; min-width: 9rem;
  background: rgba(240, 247, 252, 0.9);
  border: 1px solid var(--line); color: var(--bone);
  font: inherit; font-size: 0.8rem; letter-spacing: 0.04em;
  padding: 0.55rem 1rem; border-radius: 999px;
}
.mbar__search:focus-visible { outline: none; border-color: var(--gold); }
.mbar__select {
  appearance: none; -webkit-appearance: none;
  background: rgba(240, 247, 252, 0.9)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%23C6A15B'/%3E%3C/svg%3E")
    no-repeat right 0.7rem center;
  border: 1px solid var(--line); color: var(--bone);
  font: inherit; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.55rem 1.9rem 0.55rem 1rem; border-radius: 999px;
  cursor: pointer; max-width: 13rem;
}
.mbar__select:hover, .mbar__select:focus-visible { outline: none; border-color: var(--gold); }
.mbar__selects { display: contents; }
.mbar__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; padding-top: 0.55rem; }
.mtag {
  font: inherit; font-size: 0.7rem; letter-spacing: 0.05em;
  color: var(--gold); background: rgba(198, 161, 91, 0.1);
  border: 1px solid rgba(198, 161, 91, 0.4); border-radius: 999px;
  padding: 0.3rem 0.7rem; cursor: pointer;
}
.mtag:hover { background: rgba(198, 161, 91, 0.2); }
.mtag--count {
  color: var(--bone-2); background: transparent;
  border-color: var(--panel-line); cursor: default;
}
.mtag--count:hover { background: transparent; }
.mtag:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* The daily refresh, made visible. */
.mcard__new {
  position: absolute; top: 0.6rem; right: 0.6rem;
  font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--on-gold); background: var(--gold);
  padding: 0.22rem 0.5rem; border-radius: 2px;
}

/* Recently sold, on the way into the grid. Horizontal scroll on purpose, a
   strip, not a section that pushes the live market below the fold. */
.soldstrip { margin-bottom: 2rem; }
.soldstrip__head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.7rem; }
.soldstrip__row {
  display: flex; gap: 0.75rem; overflow-x: auto;
  padding-bottom: 0.5rem;
  scrollbar-width: thin;
}
.soldcard {
  flex: 0 0 14rem; text-decoration: none;
  border: 1px solid var(--line); border-radius: 3px;
  padding: 0.8rem 0.9rem; background: rgba(255, 255, 255, 0.02);
}
.soldcard:hover { border-color: var(--gold); }
.soldcard__title {
  color: var(--bone); font-size: 0.8rem; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  margin: 0 0 0.45rem;
}
.soldcard__price { color: var(--gold); font-size: 1rem; margin: 0 0 0.35rem; }
.soldcard__meta { display: flex; gap: 0.5rem; align-items: center; margin: 0; font-size: 0.68rem; color: var(--bone-3); }

/* Related listings on an item page: compact rows, not another grid. */
.mktitem__module { margin-top: 2rem; }
.minilist { display: flex; flex-direction: column; margin-top: 0.6rem; border-top: 1px solid var(--line); }
.minirow {
  display: grid; grid-template-columns: 2.6rem 1fr auto auto;
  gap: 0.7rem; align-items: center;
  padding: 0.55rem 0; border-bottom: 1px solid var(--line);
  text-decoration: none;
}
.minirow:hover .minirow__title { color: var(--gold); }
.minirow__img {
  width: 2.6rem; height: 2.6rem; object-fit: cover; border-radius: 2px;
  border: 1px solid var(--line); background: var(--ink-2);
}
.minirow__img--none, .minirow__img.is-broken {
  background: repeating-linear-gradient(135deg, var(--ink-2) 0 6px, var(--ink-3) 6px 12px);
  content: "";
}
.minirow__title {
  color: var(--bone); font-size: 0.8rem; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.minirow__price { color: var(--gold); font-size: 0.82rem; white-space: nowrap; }
.mktitem__modulenote { margin-top: 0.5rem; }

@media (max-width: 40rem) {
  /* On a phone the wrapped bar was four rows and half the viewport when stuck.
     Search keeps its own full-width row; the five selects share one
     horizontally scrollable row beneath it, two rows total, always. */
  .mbar__inner { gap: 0.4rem; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 0.15rem; scrollbar-width: none; }
  .mbar__inner::-webkit-scrollbar { display: none; }
  .mbar__search { flex: 0 0 100%; }
  .mbar { padding-top: 0.5rem; padding-bottom: 0.5rem; }
  .mbar__inner { flex-wrap: wrap; }
  .mbar__selects { display: flex; gap: 0.4rem; overflow-x: auto; flex: 0 0 100%; scrollbar-width: none; }
  .mbar__selects::-webkit-scrollbar { display: none; }
  .mbar__select { font-size: 0.68rem; padding: 0.5rem 1.7rem 0.5rem 0.6rem; flex: 0 0 auto; max-width: none; }
  .soldcard { flex-basis: 11.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .soldstrip__row { scroll-behavior: auto; }
}

/* ==========================================================================
   The searchable filter dropdown.

   Replaces the native <select>, whose option list the operating system draws:
   the site's `color: inherit` put near-white text on Windows' white popup and
   the choices were genuinely unreadable. This panel is ours, so its contrast
   is ours to guarantee, and it can hold a search box, which forty-four
   companies need and two hundred and fifty will need badly.
   ========================================================================== */
.combo { position: relative; flex: 0 0 auto; }

.combo__btn {
  display: inline-flex; align-items: center; gap: 0.45rem;
  background: rgba(240, 247, 252, 0.9);
  border: 1px solid var(--line); color: var(--bone);
  font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.55rem 0.75rem; border-radius: 999px; cursor: pointer;
  white-space: nowrap;
}
.combo__btn:hover { border-color: var(--line-2); }
.combo__btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.combo__label { color: var(--bone-3); }
.combo__value { color: var(--bone); max-width: 9rem; overflow: hidden; text-overflow: ellipsis; }
.combo__caret { color: var(--gold); flex: none; }
.combo.is-open .combo__btn { border-color: var(--gold); }
.combo.is-active .combo__btn { border-color: var(--gold); background: rgba(198, 161, 91, 0.1); }
.combo.is-active .combo__label { color: var(--gold); }

.combo__panel {
  position: absolute; z-index: 60; top: calc(100% + 0.35rem); left: 0;
  min-width: 100%; width: max-content; max-width: min(20rem, 86vw);
  background: var(--ink-2);
  border: 1px solid var(--line-2);
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(23, 48, 77, 0.22);
  padding: 0.5rem;
  display: flex; flex-direction: column; gap: 0.35rem;
}
.combo__search {
  background: rgba(240, 247, 252, 0.95);
  border: 1px solid var(--line-2);
  color: var(--bone); font-size: 0.78rem; letter-spacing: 0.02em;
  padding: 0.45rem 0.6rem; border-radius: 2px; text-transform: none;
}
.combo__search::placeholder { color: var(--bone-3); }
.combo__search:focus-visible { outline: none; border-color: var(--gold); }

.combo__list {
  list-style: none; margin: 0; padding: 0;
  max-height: 15rem; overflow-y: auto;
  scrollbar-width: thin;
}
.combo__opt {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 0.45rem 0.55rem; border-radius: 2px; cursor: pointer;
  font-size: 0.82rem; color: var(--bone); line-height: 1.3;
}
.combo__opt:hover { background: rgba(198, 161, 91, 0.14); }
.combo__opt:focus-visible { outline: none; background: rgba(198, 161, 91, 0.2); }
.combo__opt[aria-selected="true"] { color: var(--gold); }
.combo__opt[aria-selected="true"]::after { content: "✓"; font-size: 0.7rem; }
.combo__n { color: var(--bone-3); font-size: 0.72rem; }
.combo__opt[aria-selected="true"] .combo__n { color: inherit; }
/* A combination with nothing behind it. Visible on purpose, knowing Amazon
   has no $25,000+ material is useful; being unable to tell is not. */
.combo__opt.is-empty { opacity: 0.34; cursor: default; }
.combo__opt.is-empty:hover { background: none; }
.combo__none { color: var(--bone-3); font-size: 0.78rem; padding: 0.5rem 0.55rem; margin: 0; }

@media (max-width: 40rem) {
  .combo__btn { font-size: 0.68rem; padding: 0.5rem 0.6rem; }
  .combo__value { max-width: 6.5rem; }
  /* Anchored to the viewport rather than the button so a panel opened from the
     right-hand end cannot hang off the screen. min-width has to be reset too, the base rule's `min-width: 100%` refers to the button and wins over
     left/right, which is what pushed the panel back off the edge. */
  .combo__panel {
    position: fixed; left: 0.75rem; right: 0.75rem;
    width: auto; min-width: 0; max-width: none;
  }
}

/* ==========================================================================
   Item-page gallery and lightbox.

   A listing carries up to twenty-five photographs and the page showed four,
   flat and unclickable. On a collectible the extra frames often ARE the
   evidence, the certificate of authenticity, the reverse of a signed photo,
   the serial plate, so all of them get a strip, and any of them can be
   opened and zoomed.
   ========================================================================== */
.gallery { display: flex; flex-direction: column; gap: 0.6rem; }

/* A FIXED frame. Without one the box took each photograph's own aspect ratio,
   so clicking from a wide cover shot to a tall portrait grew the box by
   hundreds of pixels and shoved the whole page down, the layout lurched on
   every thumbnail click. eBay sellers shoot at every ratio there is, so the
   frame has to be the constant and the picture has to fit inside it. */
.gallery__main {
  position: relative; display: block; width: 100%; padding: 0;
  aspect-ratio: 4 / 3;
  background: var(--ink-2); border: 1px solid var(--line);
  border-radius: 3px; overflow: hidden; cursor: zoom-in;
}
.gallery__main:hover { border-color: var(--gold); }
.gallery__main:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* contain, not cover: a signature in the corner of a photograph is the whole
   point of the listing, and cover would crop it off. */
.gallery__mainimg {
  width: 100%; height: 100%; display: block;
  object-fit: contain;
}
.gallery__hint {
  position: absolute; right: 0.6rem; bottom: 0.6rem;
  font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--bone); background: rgba(255, 255, 255, 0.92); border-radius: 6px;
  border: 1px solid var(--line-2); border-radius: 2px;
  padding: 0.25rem 0.5rem; opacity: 0; transition: opacity 0.15s ease;
}
.gallery__main:hover .gallery__hint,
.gallery__main:focus-visible .gallery__hint { opacity: 1; }

.gallery__thumbs {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(3.75rem, 1fr));
  gap: 0.4rem;
}
.gallery__thumb {
  padding: 0; aspect-ratio: 1; overflow: hidden; cursor: pointer;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: 2px;
}
.gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery__thumb:hover { border-color: var(--line-2); }
.gallery__thumb.is-current { border-color: var(--gold); }
.gallery__thumb:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

/* ---- Lightbox ---- */
body.lbox-open { overflow: hidden; }
.lbox {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6, 7, 10, 0.94);
  display: grid;
  grid-template-columns: 3.5rem 1fr 3.5rem;
  grid-template-areas: "prev stage next";
  align-items: center;
}
.lbox__stage {
  grid-area: stage; display: flex; align-items: center; justify-content: center;
  height: 100vh; padding: 3rem 0.5rem;
  /* The stage is the constant, not the picture, paging between a portrait and
     a landscape shot must not move the arrows or the counter. */
  min-height: 0;
}
.lbox__img {
  width: 100%; height: 100%; object-fit: contain;
  cursor: zoom-in; transition: transform 0.18s ease;
}
.lbox__img.is-zoomed { transform: scale(2.4); cursor: zoom-out; }
.lbox__nav, .lbox__close {
  background: none; border: 0; color: var(--bone);
  cursor: pointer; line-height: 1;
}
.lbox__nav { font-size: 2.6rem; padding: 1rem 0.5rem; opacity: 0.7; }
.lbox__prev { grid-area: prev; }
.lbox__next { grid-area: next; }
.lbox__nav:hover { opacity: 1; color: var(--gold); }
.lbox__close {
  position: absolute; top: 0.75rem; right: 1rem;
  font-size: 2.2rem; opacity: 0.75; z-index: 1;
}
.lbox__close:hover { opacity: 1; color: var(--gold); }
.lbox__nav:focus-visible, .lbox__close:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; opacity: 1; }
.lbox__counter {
  position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%);
  margin: 0; font-size: 0.75rem; letter-spacing: 0.1em; color: var(--bone-2);
}

@media (max-width: 40rem) {
  .lbox { grid-template-columns: 2.5rem 1fr 2.5rem; }
  .lbox__nav { font-size: 2rem; }
  .gallery__thumbs { grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr)); }
}
@media (prefers-reduced-motion: reduce) {
  .lbox__img, .gallery__hint { transition: none; }
}

/* ==========================================================================
   The Price Guide.

   A three-step page: who, what kind, how narrow, then the answer. The steps
   are numbered because they genuinely are a sequence; the estimate means
   nothing until a person is chosen, and the page says so rather than showing
   an average across everybody.
   ========================================================================== */
.guide { padding-block: clamp(2rem, 5vw, 3.5rem) 5rem; }
.guide__head { max-width: 46rem; margin-bottom: clamp(2rem, 5vw, 3rem); }
.guide__title { margin: 0.5rem 0 0; }
.guide__lede { margin-top: 1rem; }

.guide__step { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.guide__stephead { display: flex; align-items: baseline; gap: 0.7rem; margin-bottom: 0.9rem; flex-wrap: wrap; }
.guide__stepn {
  font-family: var(--mono); font-size: 0.7rem; color: var(--on-gold);
  background: var(--gold); width: 1.4rem; height: 1.4rem; border-radius: 50%;
  display: grid; place-items: center; flex: none; align-self: center;
}
.guide__steptitle { font-family: var(--display); font-size: clamp(1.3rem, 2.4vw, 1.7rem); margin: 0; font-weight: 400; }
.guide__hint { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bone-3); }

.guide__search {
  width: 100%; max-width: 26rem; background: rgba(255,255,255,0.55);
  border: 1px solid var(--line); color: var(--bone); font: inherit; font-size: 0.9rem;
  padding: 0.65rem 0.9rem; border-radius: 2px; margin-bottom: 1.1rem;
}
.guide__search:focus-visible { outline: none; border-color: var(--gold); }
.guide__search::placeholder { color: var(--bone-3); }

.guide__people { display: flex; flex-direction: column; gap: 1.25rem; }
.guide__sectorname {
  font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bone-3); margin: 0 0 0.5rem;
}
.guide__chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.pchip, .tchip {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: rgba(255,255,255,0.5); border: 1px solid var(--line);
  color: var(--bone); font: inherit; font-size: 0.82rem;
  padding: 0.45rem 0.75rem; border-radius: 2px; cursor: pointer;
}
.pchip:hover, .tchip:hover:not(:disabled) { border-color: var(--line-2); }
.pchip:focus-visible, .tchip:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.pchip__n, .tchip__n { font-size: 0.7rem; color: var(--bone-3); }
.pchip[aria-pressed="true"], .tchip[aria-pressed="true"] {
  background: var(--gold); border-color: var(--gold); color: var(--on-gold); font-weight: 600;
}
.pchip[aria-pressed="true"] .pchip__n, .tchip[aria-pressed="true"] .tchip__n { color: var(--on-gold); opacity: 0.7; }
.tchip.is-empty:not([aria-pressed="true"]) { opacity: 0.35; cursor: default; }
.guide__nomatch, .guide__empty { color: var(--bone-3); font-size: 0.9rem; }

.guide__filters { display: flex; flex-wrap: wrap; gap: 0.9rem; align-items: flex-end; }
.gfilter { display: flex; flex-direction: column; gap: 0.35rem; }
.gfilter__label {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--bone-3);
}
.gfilter__money { display: inline-flex; align-items: center; gap: 0.3rem;
  background: rgba(255,255,255,0.55); border: 1px solid var(--line);
  padding: 0.5rem 0.7rem; border-radius: 2px; color: var(--bone-3); }
.gfilter__input { background: none; border: 0; color: var(--bone); font: inherit; width: 5.5rem; }
.gfilter__input:focus-visible { outline: none; }
.gfilter__money:focus-within { border-color: var(--gold); }
.gfilter__select {
  background: rgba(255,255,255,0.55); border: 1px solid var(--line); color: var(--bone);
  font: inherit; font-size: 0.85rem; padding: 0.55rem 0.7rem; border-radius: 2px; cursor: pointer;
}
.gfilter__select:focus-visible { outline: none; border-color: var(--gold); }
.gfilter__reset {
  background: none; border: 0; color: var(--gold); font: inherit; font-size: 0.8rem;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px; padding: 0.55rem 0;
}

/* The answer. */
.guide__results { border-top: 1px solid var(--line); padding-top: 2rem; margin-top: 2rem; }
.estimate {
  border: 1px solid var(--gold); border-radius: 3px;
  background: rgba(198,161,91,0.06); padding: 1.4rem 1.5rem; margin-bottom: 2rem;
}
.estimate__figure {
  font-family: var(--display); font-size: clamp(2.4rem, 6vw, 3.6rem);
  color: var(--gold); line-height: 1; margin: 0.5rem 0 0.4rem;
}
.estimate__detail { margin: 0; color: var(--bone-2); }
.estimate__caveat {
  margin: 0.8rem 0 0; padding-top: 0.8rem; border-top: 1px solid rgba(198,161,91,0.25);
  color: var(--bone-2); font-size: 0.88rem;
}

.guide__panel { margin-bottom: 2.25rem; }
.guide__panelhead { display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; margin-bottom: 0.75rem; flex-wrap: wrap; }
.guide__paneltitle { font-family: var(--display); font-size: 1.35rem; margin: 0; font-weight: 400; }
.guide__sorts { display: flex; gap: 0.3rem; }
.sortbtn {
  background: none; border: 1px solid var(--line); color: var(--bone-3);
  font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.35rem 0.6rem; border-radius: 2px; cursor: pointer;
}
.sortbtn.is-on { color: var(--gold); border-color: var(--gold); }
.guide__more { margin-top: 0.9rem; }
.guide__disclaim { color: var(--bone-3); font-size: 0.82rem; margin-top: 1.5rem; }
.guide__prompt { color: var(--bone-3); border-top: 1px solid var(--line); padding-top: 2rem; margin-top: 2rem; }

.complist { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.comp {
  display: grid; grid-template-columns: 3rem 1fr auto auto; gap: 0.85rem;
  align-items: center; padding: 0.65rem 0; border-bottom: 1px solid var(--line);
  text-decoration: none;
}
.comp:hover .comp__title { color: var(--gold); }
.comp__img { width: 3rem; height: 3rem; object-fit: cover; border: 1px solid var(--line);
  border-radius: 2px; background: var(--ink-2); }
.comp__img--none, .comp__img.is-broken {
  background: repeating-linear-gradient(135deg, var(--ink-2) 0 6px, var(--ink-3) 6px 12px);
  content: "";
}
.comp__title {
  color: var(--bone); font-size: 0.85rem; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.comp__meta { display: flex; flex-direction: column; align-items: flex-end; gap: 0.15rem; }
.comp__price { color: var(--gold); font-size: 0.95rem; white-space: nowrap; }
.comp__date, .comp__src { color: var(--bone-3); font-size: 0.7rem; white-space: nowrap; }

.guide__method { border-top: 1px solid var(--line); margin-top: 3.5rem; padding-top: 2rem; }
.guide__methodtitle { font-family: var(--display); font-size: 1.4rem; font-weight: 400; margin: 0 0 1.2rem; }
.guide__methodgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1.5rem;
}
.guide__methodgrid p:not(.label) { color: var(--bone-2); font-size: 0.88rem; margin: 0.4rem 0 0; }

@media (max-width: 40rem) {
  .comp { grid-template-columns: 2.5rem 1fr auto; }
  .comp__src, .comp .arch__badge { display: none; }
  .guide__filters { gap: 0.6rem; }
  .gfilter__input { width: 4.5rem; }
  .estimate { padding: 1.1rem 1.1rem; }
}

/* ==========================================================================
   Recovered from the pre-guide stylesheet.
   Rules that lived in card-site sections but are used by pages that outlived
   them: the footer grid, the page title, and a screen-reader utility.
   ========================================================================== */
.coll__title { font-size: var(--t-title); margin-top: 1rem; }

.foot { position: relative; z-index: 1; border-top: 1px solid var(--line); padding-block: clamp(3rem, 5vw, 4.5rem) 2.25rem; }
.foot__grid { display: grid; grid-template-columns: minmax(0, 5fr) repeat(2, minmax(0, 2fr)); gap: clamp(2rem, 4vw, 3rem); align-items: start; }
.foot__cols { display: flex; flex-direction: column; gap: 0.8rem; align-items: flex-start; }
.foot__bar { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem; margin-top: clamp(2.5rem, 5vw, 4rem); padding-top: 1.25rem; border-top: 1px solid var(--line); }

/* Announced by a screen reader, invisible to the eye. The filter tags need it, a bare multiplication sign announces as nothing useful. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 60rem) { .foot__grid { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   Price Guide, phase two: quick lookup, chart, deals, trends, outliers.
   ========================================================================== */
.quick {
  border: 1px solid var(--gold); border-radius: 3px;
  background: rgba(198, 161, 91, 0.06);
  padding: 1.15rem 1.25rem; margin-bottom: clamp(2rem, 5vw, 3rem);
}
.quick__title { font-family: var(--display); font-size: 1.35rem; font-weight: 400; margin: 0 0 0.7rem; }
.quick__form { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.quick__input {
  flex: 1 1 18rem; min-width: 0; background: rgba(255,255,255,0.6);
  border: 1px solid var(--line-2); color: var(--bone); font: inherit; font-size: 0.95rem;
  padding: 0.7rem 0.9rem; border-radius: 2px;
}
.quick__input:focus-visible { outline: none; border-color: var(--gold); }
.quick__input::placeholder { color: var(--bone-3); }
.quick__go { flex: 0 0 auto; }
.quick__read { margin: 0.8rem 0 0; color: var(--bone-2); font-size: 0.9rem; }
.quick__hint { color: var(--bone-3); }
.quick__clear {
  background: none; border: 0; color: var(--gold); font: inherit; font-size: 0.85rem;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px; padding: 0;
}

.estimate__basis {
  margin: 0.5rem 0 0; color: var(--bone-3); font-size: 0.82rem;
  font-family: var(--mono); letter-spacing: 0.03em;
}

/* Price over time. */
.chart { width: 100%; height: auto; display: block; }
.chart__axis { stroke: var(--line-2); stroke-width: 1; }
.chart__dot { fill: var(--gold); opacity: 0.75; }
.chart__line { fill: none; stroke: var(--bone-2); stroke-width: 1.6; stroke-linejoin: round; }
.chart__legend {
  display: flex; justify-content: space-between; gap: 1rem;
  color: var(--bone-3); font-size: 0.72rem; font-family: var(--mono); margin-top: 0.3rem;
}
.chart__note { color: var(--bone-3); font-size: 0.82rem; margin: 0.6rem 0 0; }

/* Deals. */
.deal { border-left: 2px solid var(--deal); padding-left: 0.7rem; }
.deal__pct {
  color: var(--deal-hi); font-size: 0.8rem; white-space: nowrap;
  font-family: var(--mono); letter-spacing: 0.04em;
}

/* An outlier stays visible and says why it was set aside. A flag with no
   stated reason is a site asserting that a real sale did not happen. */
.comp--outlier { opacity: 0.55; }
.comp--outlier .comp__price { color: var(--bone-2); text-decoration: line-through; }
.arch__badge--outlier { color: var(--vis); border-color: currentColor; }
.comp__why {
  grid-column: 1 / -1; margin: 0 0 0.55rem; padding-left: 3.85rem;
  color: var(--bone-3); font-size: 0.75rem; border-bottom: 1px solid var(--line);
}

/* Trending. */
.trends { border-top: 1px solid var(--line); margin-top: 3rem; padding-top: 2rem; }
.trendlist { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0.5rem; margin-top: 0.9rem; }
.trend {
  display: grid; gap: 0.15rem; text-align: left; cursor: pointer;
  background: rgba(255,255,255,0.5); border: 1px solid var(--line);
  border-radius: 2px; padding: 0.7rem 0.85rem; color: var(--bone); font: inherit;
}
.trend:hover { border-color: var(--gold); }
.trend__name { font-size: 0.88rem; }
.trend__pct { font-size: 1.15rem; font-family: var(--display); }
.trend__pct.is-up { color: var(--deal-hi); }
.trend__pct.is-down { color: var(--vis); }
.trend__detail { color: var(--bone-3); font-size: 0.72rem; }

@media (max-width: 40rem) {
  .quick__go { width: 100%; }
  .comp__why { padding-left: 0; }
  .deal__pct { font-size: 0.72rem; }
}

/* ==========================================================================
   Price Guide front page: hero collage and the unified lookup.

   The page used to open with a form. It opens with the market now, a wall of
   what is actually being traded, because "what is it worth" is a question
   people arrive at after seeing something, not before.
   ========================================================================== */
.hero {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center;
  padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(1.75rem, 4vw, 3rem);
}
.hero__title { margin: 0.5rem 0 0; }
.hero__lede { margin: 1rem 0 0; max-width: 34rem; }
.hero__stats {
  display: flex; flex-wrap: wrap; gap: 0.4rem 1.5rem; margin-top: 1.4rem;
  font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bone-3);
}
.hero__stats strong { color: var(--gold); font-size: 1.05rem; font-family: var(--display); font-weight: 400; }

/* Deliberately uneven: a strict grid of identical squares reads as a template,
   and these are photographs of very different things. */
.hero__collage {
  display: grid; grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: clamp(52px, 7vw, 84px); gap: 6px;
}
.tile {
  position: relative; overflow: hidden; border-radius: 2px;
  border: 1px solid var(--line); background: var(--ink-2);
  display: block;
}
.tile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.4s ease; }
.tile:hover img { transform: scale(1.06); }
.tile:hover { border-color: var(--gold); }
.tile__price {
  position: absolute; left: 0; bottom: 0;
  background: rgba(255, 255, 255, 0.92);
  color: var(--bone); font-size: 0.62rem; padding: 0.15rem 0.35rem;
  border-top-right-radius: 2px;
}
/* A few tiles carry more weight so the wall has a rhythm. */
.tile:nth-child(1)  { grid-column: span 2; grid-row: span 2; }
.tile:nth-child(8)  { grid-column: span 2; grid-row: span 2; }
.tile:nth-child(13) { grid-column: span 2; grid-row: span 2; }

/* ---- The lookup --------------------------------------------------------- */
.lookup { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.lookup__title {
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bone-3); margin: 0 0 0.6rem; font-weight: 400;
}
.lookup__field { position: relative; }
.lookup__input {
  width: 100%; background: rgba(255,255,255,0.6);
  border: 1px solid var(--line-2); color: var(--bone);
  font: inherit; font-size: clamp(1rem, 2.2vw, 1.25rem);
  padding: 0.95rem 2.6rem 0.95rem 1.1rem; border-radius: 3px;
}
.lookup__input:focus-visible { outline: none; border-color: var(--gold); }
.lookup__input::placeholder { color: var(--bone-3); }
.lookup__clear {
  position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%);
  background: none; border: 0; color: var(--bone-3); font-size: 1.5rem;
  line-height: 1; cursor: pointer; padding: 0.2rem 0.5rem;
}
.lookup__clear:hover { color: var(--gold); }

.lookup__suggest {
  position: absolute; z-index: 50; top: calc(100% + 4px); left: 0; right: 0;
  list-style: none; margin: 0; padding: 0.3rem;
  background: var(--ink-2); border: 1px solid var(--line-2); border-radius: 3px;
  box-shadow: 0 18px 44px rgba(23, 48, 77, 0.2); max-height: 22rem; overflow-y: auto;
}
.sugg {
  display: grid; grid-template-columns: 1fr auto auto; gap: 0.9rem;
  align-items: baseline; padding: 0.6rem 0.7rem; border-radius: 2px; cursor: pointer;
}
.sugg:hover, .sugg.is-active { background: rgba(198, 161, 91, 0.16); }
.sugg__name { color: var(--bone); font-size: 0.95rem; }
.sugg__kind {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--bone-3);
}
.sugg__n { color: var(--gold); font-size: 0.8rem; min-width: 2ch; text-align: right; }
.sugg--text .sugg__name { color: var(--bone-2); font-style: italic; }
.lookup__read { margin: 0.7rem 0 0; color: var(--bone-2); font-size: 0.92rem; }

/* ---- Filters as a bar --------------------------------------------------- */
.guide__step--bar { border: 0; padding-top: 0; }
.guide__steptitle--sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.typebar { display: flex; flex-wrap: wrap; gap: 0.5rem 0.9rem; align-items: center; margin-bottom: 1rem; }
.typebar__label {
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--bone-3);
}
.typebar__chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

@media (max-width: 60rem) {
  .hero { grid-template-columns: minmax(0, 1fr); }
  .hero__collage { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 68px; }
  .tile:nth-child(n+13) { display: none; }
}
@media (max-width: 40rem) {
  .hero__collage { grid-template-columns: repeat(3, 1fr); grid-auto-rows: 62px; }
  .tile:nth-child(n+10) { display: none; }
  .sugg { grid-template-columns: 1fr auto; }
  .sugg__kind { display: none; }
}

/* The wordmark and two nav links no longer fit side by side on a narrow phone
   once the links carry letter-spacing, they pushed 23px past the viewport.
   Tightening the pair rather than hiding either: both are the whole site. */
@media (max-width: 26rem) {
  .nav__inner { gap: 0.5rem; }
  .nav__links { gap: 0.9rem; }
  .nav__link { letter-spacing: 0.08em; font-size: 0.66rem; }
  .mark__name { font-size: 1.45rem; }
  .mark__sub { display: none; }
}

/* ==========================================================================
   The marketplace hero: the name inside the market.

   Two bands of listing photographs, one above the wordmark and one below, so
   the first thing on the page is what is actually being traded with the name
   sitting in the middle of it. The bands are masked at their edges and dimmed
   so they read as ground rather than as content competing with the title.
   ========================================================================== */
.mhero {
  position: relative;
  padding: clamp(1rem, 3vw, 2rem) 0 clamp(1.5rem, 4vw, 2.5rem);
  text-align: center;
  overflow: hidden;
}
.mhero__wall {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 5px;
  /* Full strength. Dimming was a night-theme device, dimmed photos glow on
     black and dissolve on sky. Daylight treatment is card physics instead:
     white frames and a shadow, below. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.mhero__wall--top { margin-bottom: clamp(1.25rem, 3vw, 2rem); }
.mhero__wall--bottom { margin-top: clamp(1.25rem, 3vw, 2rem); }

.mtile {
  display: block; aspect-ratio: 1; overflow: hidden; border-radius: 3px;
  border: 1px solid var(--line); background: #fff;
  box-shadow: 0 5px 16px rgba(23, 48, 77, 0.14);
}
.mtile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.5s var(--ease); }
.mtile:hover { border-color: var(--gold); }
.mtile:hover img { transform: scale(1.08); }

.mhero__centre { position: relative; z-index: 2; max-width: 44rem; margin: 0 auto; }
.mhero__title { margin: 0.5rem 0 0; }
.mhero__lede { margin: 1rem auto 0; max-width: 38rem; }
.mhero__stats {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 0.4rem 1.75rem;
  margin: 1.35rem 0 0;
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--bone-3);
}
.mhero__stats strong { color: var(--gold); font-family: var(--display); font-size: 1.1rem; font-weight: 400; }
.mhero .mkt__disclaim { position: relative; z-index: 2; margin-top: 1.5rem; }

@media (max-width: 60rem) {
  .mhero__wall { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .mtile:nth-child(n+9) { display: none; }
}
@media (max-width: 40rem) {
  .mhero__wall { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px; }
  .mtile:nth-child(n+6) { display: none; }
  /* One band is enough on a phone; two eat the whole first screen. */
  .mhero__wall--bottom { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .mtile img { transition: none; }
  .mtile:hover img { transform: none; }
}

/* The wordmark inside the hero. Same type as the header mark so it reads as
   the logo rather than a heading that happens to say the name. */
.mhero__mark {
  display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
  margin: 0 0 0.9rem;
}
.mhero__mark .mark__name { font-size: clamp(2.1rem, 5vw, 3rem); line-height: 1; }
.mhero__mark .mark__sub { font-size: 0.7rem; }

/* Price in the corner of a collage tile. The wall is a market, and a market
   without prices is a mood board. */
.mtile { position: relative; }
.mtile__price {
  position: absolute; left: 0; bottom: 0;
  background: rgba(255, 255, 255, 0.92);
  color: var(--bone); font-family: var(--mono);
  font-size: 0.58rem; letter-spacing: 0.02em;
  padding: 0.12rem 0.3rem; border-top-right-radius: 2px;
}
@media (max-width: 40rem) { .mtile__price { font-size: 0.52rem; } }

/* ---- People we track ------------------------------------------------------
   A four-thousand-name roster has to read as a reference list, not as a wall.
   Three things do that work: a fixed multi-column grid so the eye scans down
   rather than across, a letter rule that stays visible while scrolling, and a
   clear difference between a name we hold something for and one we do not, most of the list is the latter, and it must not look like an error. */
.roster { margin-top: clamp(2.5rem, 6vw, 4rem); }

.roster__field { position: relative; margin: 1rem 0 0.75rem; max-width: 30rem; }
.roster__input {
  width: 100%; background: rgba(255,255,255,0.6);
  border: 1px solid var(--line-2); color: var(--bone);
  font: inherit; font-size: 1rem;
  padding: 0.7rem 2.4rem 0.7rem 0.9rem; border-radius: 3px;
}
.roster__input:focus-visible { outline: none; border-color: var(--gold); }
.roster__input::placeholder { color: var(--bone-3); }
.roster__clear {
  position: absolute; right: 0.4rem; top: 50%; transform: translateY(-50%);
  background: none; border: 0; color: var(--bone-3); font-size: 1.4rem;
  line-height: 1; cursor: pointer; padding: 0.2rem 0.5rem;
}
.roster__clear:hover { color: var(--gold); }

.roster__status {
  font-family: var(--mono); font-size: var(--t-micro);
  color: var(--bone-3); margin: 0 0 1rem;
}

.roster__az {
  display: flex; flex-wrap: wrap; gap: 0.15rem;
  padding-bottom: 0.9rem; margin-bottom: 0.9rem;
  border-bottom: 1px solid var(--line);
}
.rost__az {
  font-family: var(--mono); font-size: 0.72rem; color: var(--bone-3);
  text-decoration: none; padding: 0.25rem 0.45rem; border-radius: 2px;
}
.rost__az:hover { color: var(--gold); background: rgba(255,255,255,0.6); }

.roster__list {
  columns: 4; column-gap: 1.75rem;
}
@media (max-width: 1100px) { .roster__list { columns: 3; } }
@media (max-width: 780px)  { .roster__list { columns: 2; } }
@media (max-width: 520px)  { .roster__list { columns: 1; } }

/* break-inside on every child: without it a name splits across a column
   boundary and renders as two half-rows. */
.rost__letter, .rost__i, .rost__more, .rost__empty {
  break-inside: avoid; -webkit-column-break-inside: avoid;
}

.rost__letter {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em;
  color: var(--gold); margin: 1.1rem 0 0.4rem; font-weight: 400;
  border-bottom: 1px solid var(--line); padding-bottom: 0.25rem;
}
.rost__letter:first-child { margin-top: 0; }

.rost__i {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 0.6rem; padding: 0.24rem 0; color: var(--bone-2);
  text-decoration: none; font-size: 0.9rem;
}
.rost__i:hover { color: var(--gold); }
.rost__i:focus-visible { outline: 1px solid var(--gold); outline-offset: 2px; }

/* A name we actually hold something for earns the brighter ink. The rest are
   legible but recede, they are the answer to "do you track them", not
   something to click. */
.rost__i.is-held .rost__name { color: var(--bone); }
.rost__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rost__n { font-family: var(--mono); font-size: 0.68rem; color: var(--gold); white-space: nowrap; }
.rost__none { font-family: var(--mono); font-size: 0.64rem; color: var(--bone-3); opacity: 0.55; }

.rost__more {
  display: flex; justify-content: space-between; align-items: baseline;
  width: 100%; margin-top: 1rem; padding: 0.6rem 0.8rem;
  background: rgba(255,255,255,0.55); border: 1px solid var(--line-2);
  border-radius: 3px; color: var(--bone-2); font: inherit; font-size: 0.85rem;
  cursor: pointer;
}
.rost__more:hover { border-color: var(--gold); color: var(--gold); }
.rost__moren { font-family: var(--mono); font-size: 0.68rem; color: var(--bone-3); }

.rost__empty { color: var(--bone-3); font-size: 0.9rem; margin: 0; }

/* ---- Database page remodel ------------------------------------------------
   One search, a thin wayfinding bar, filters that appear only with results,
   and an empty state that is a door rather than a sign. */





/* Suggestions: a tracked name reads as what it is. */
.sugg__kind { white-space: nowrap; }

/* The roster's inline field is a FILTER of the list below it, not a second
   search, scoped visually inside the module so the two cannot be confused.
   The page-level search is the one that answers questions. */
.roster__field { max-width: 22rem; }
.roster__input { font-size: 0.9rem; padding: 0.55rem 2.2rem 0.55rem 0.8rem; }

/* On a phone the nav must stay one row, sticky chrome two rows deep is a
   tax on every scroll. One scrollable row, no visible scrollbar. */
@media (max-width: 640px) {
  .pagenav { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .pagenav::-webkit-scrollbar { display: none; }
}

#record, #g-roster, #method { scroll-margin-top: 1rem; }

/* The people line: the page's opening statement, sized as a statement rather
   than a banner. The count is the link, clicking it lands on the roster. */
.peopleline {
  font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bone-3);
  margin: 0 0 1.1rem;
}
.peopleline__link { color: var(--gold); text-decoration: none; }
.peopleline__link:hover, .peopleline__link:focus-visible { text-decoration: underline; outline: none; }
.peopleline__link strong { font-weight: 400; }

/* ==========================================================================
   Email capture.

   One set of rules for four placements: a block on the homepage, a slim strip
   in every footer, an inline row on the waitlist and on person pages. The
   variant class only changes the arrangement, the field, the button and the
   focus ring are the same object everywhere, so the offer is recognisable
   wherever it appears.
   ========================================================================== */

/* The honeypot. Hidden from sight AND from the accessibility tree AND from
   tab order, because a field a screen-reader user can reach is a field they
   will fill in, and filling it in silently discards their subscription.
   `display:none` alone is what spam bots look for, so it is moved out of the
   viewport instead. */
.sub__trap {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; margin: 0;
}

.sub { margin: 0; }
.sub__label {
  display: block; margin-bottom: 0.4rem;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--bone-3);
}
.sub__row { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.sub__input {
  flex: 1 1 14rem; min-width: 0; font: inherit; font-size: 1rem;
  color: var(--bone); background: #fff;
  border: 1px solid var(--panel-line); border-radius: 999px;
  padding: 0.75rem 1.15rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.sub__input::placeholder { color: var(--bone-3); opacity: 0.7; }
.sub__input:focus {
  outline: none; border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(122, 94, 31, 0.14);
}
.sub__btn {
  flex: none; font: inherit; font-size: 0.95rem; font-weight: 500;
  color: #fff; background: var(--gold);
  border: 1px solid var(--gold); border-radius: 999px;
  padding: 0.75rem 1.5rem; cursor: pointer;
  transition: background 0.15s, transform 0.15s;
}
.sub__btn:hover { background: var(--gold-hi); transform: translateY(-1px); }
.sub__btn:focus-visible { outline: 2px solid var(--bone); outline-offset: 2px; }
.sub__note { margin: 0.55rem 0 0; font-size: var(--t-micro); color: var(--bone-3); }

/* ---- The homepage block -------------------------------------------------- */
.subblock {
  margin-top: clamp(3rem, 7vw, 5.5rem);
  padding: clamp(2rem, 4.5vw, 3.25rem) 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.subblock__inner {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center;
}
@media (max-width: 780px) { .subblock__inner { grid-template-columns: 1fr; } }
.subblock__eyebrow {
  margin: 0 0 0.4rem; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold);
}
.subblock__title {
  margin: 0; font-family: var(--display); font-weight: 400;
  font-size: clamp(1.6rem, 3.2vw, 2.4rem); line-height: 1.1; color: var(--bone);
}
.subblock__lede {
  margin: 0.7rem 0 0; max-width: 44ch; line-height: 1.55; color: var(--panel-body);
}

/* ---- The waitlist -------------------------------------------------------- */
.waitblock { padding: clamp(1.6rem, 3.5vw, 2.4rem) 0 clamp(2.5rem, 5vw, 4rem); }
.waitblock__inner {
  display: flex; flex-wrap: wrap; gap: 1rem 2rem;
  align-items: center; justify-content: space-between;
}
.waitblock__title {
  margin: 0; font-size: 1.05rem; font-weight: 500; color: var(--bone);
}
.waitblock__lede { margin: 0.15rem 0 0; font-size: var(--t-small); color: var(--bone-3); }
/* Inline variants put the label on the field rather than above it: at this
   size a stacked label is louder than the thing it labels. */
.sub--inline .sub__label, .sub--slim .sub__label {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}
.sub--inline .sub__row { flex-wrap: nowrap; }
@media (max-width: 560px) { .sub--inline .sub__row { flex-wrap: wrap; } }

/* ---- The footer strip ---------------------------------------------------- */
/* ---- The signup strip ------------------------------------------------------
   It used to sit at the very bottom of the footer, under four columns of
   links, set at small-print size in the same grey as the legal line, with a
   sentence about the newsletter where the ask should have been. Everything
   about it said "footnote". Nothing about it said "type your address here".

   Three changes, in order of how much they do: it moved above the columns so
   it is read before the links rather than after them; the sentence became a
   heading that asks for the thing; and the block sits on its own ground with
   a gold rule so it reads as one object rather than as the last row of the
   footer. */
.footsub {
  display: flex; flex-wrap: wrap; gap: 1rem 2.5rem;
  align-items: center; justify-content: space-between;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
  padding: clamp(1.25rem, 2.5vw, 1.75rem) clamp(1.25rem, 2.5vw, 2rem);
  background: linear-gradient(180deg, rgba(255, 252, 245, 0.95), rgba(255, 255, 255, 0.55));
  border: 1px solid var(--panel-line);
  border-top: 2px solid var(--gold);
  border-radius: 4px;
}
.footsub__say { min-width: 0; }
.footsub__eyebrow {
  margin: 0; font-family: var(--mono); font-size: 0.62rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--gold);
}
.footsub__ask {
  margin: 0.35rem 0 0; font-family: var(--display); font-weight: 400;
  font-size: clamp(1.25rem, 2.4vw, 1.7rem); line-height: 1.1; color: var(--bone);
}
.footsub__pitch {
  margin: 0.35rem 0 0; max-width: 52ch;
  font-size: 0.9rem; line-height: 1.5; color: var(--panel-body);
}

/* The field is the point of the block, so it is not the smallest thing in it.
   A 0.9rem input beside a 0.875rem button read as a pair of controls somebody
   had run out of room for. */
.footsub .sub { flex: 0 1 26rem; }
.footsub .sub__input {
  flex: 1 1 13rem; padding: 0.8rem 1.1rem; font-size: 1rem;
  background: #fff; border-color: var(--line-2);
}
.footsub .sub__input:focus {
  border-color: var(--gold); box-shadow: 0 0 0 3px rgba(122, 94, 31, 0.14);
}
.footsub .sub__btn {
  padding: 0.8rem 1.5rem; font-size: 0.8rem;
  box-shadow: 0 3px 12px rgba(122, 94, 31, 0.22);
}

@media (max-width: 44rem) {
  .footsub { display: block; }
  .footsub .sub { margin-top: 1rem; }
}

/* ---- The person-page prompt ---------------------------------------------- */
.subperson {
  display: flex; flex-wrap: wrap; gap: 0.9rem 1.75rem;
  align-items: center; justify-content: space-between;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: clamp(1.1rem, 2.2vw, 1.5rem) clamp(1.2rem, 2.5vw, 1.75rem);
  background: var(--ink-2); border: 1px solid var(--line); border-radius: 1.25rem;
}
.subperson__say { margin: 0; font-size: 1rem; color: var(--bone); max-width: 40ch; }

/* ---- The success page ---------------------------------------------------- */
.thanks { padding: clamp(3rem, 8vw, 6rem) 0 clamp(4rem, 10vw, 7rem); max-width: 40rem; }
.thanks__title {
  margin: 0; font-family: var(--display); font-weight: 400;
  font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1.05; color: var(--bone);
}
.thanks__lede {
  margin: 1rem 0 0; font-size: var(--t-lede); line-height: 1.55; color: var(--panel-body);
}
.thanks__back { margin: 2rem 0 0; display: flex; flex-wrap: wrap; gap: 1.5rem; }

/* The line under the hero headline. The headline states what Titans is about;
   this says what the site does, which is the question the headline raises. */
.mhero__sub {
  margin: clamp(0.9rem, 2vw, 1.4rem) auto 0; max-width: 46ch;
  font-size: clamp(1rem, 1.5vw, 1.15rem); line-height: 1.55;
  color: var(--panel-body); text-wrap: pretty;
}
.mhero__sub strong { font-weight: 500; color: var(--bone); }

/* ---- Hero highlights ------------------------------------------------------
   Five claims where a paragraph used to be, on the owner's brief. Bubbles
   rather than a stat bar, and the difference is not decorative: a stat bar is
   read as one horizontal unit and skimmed as a block, whereas discrete pills
   are read one at a time, which is the point when each carries a different
   claim rather than five facets of the same one.

   Each is a link, so the figure and the page proving it are one click apart.
   The figure leads in the display serif because that is the type this site
   uses for anything it is asserting; the label sits under it in the mono
   caps used for every other label on the site, which keeps the bubble from
   reading as a button. */
.hilite {
  list-style: none; margin: clamp(1.35rem, 2.6vw, 2rem) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(0.5rem, 1.2vw, 0.75rem);
}
.hilite__i { display: flex; }
.hilite__a {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.15rem;
  padding: 0.6rem 1.05rem 0.65rem;
  border: 1px solid var(--panel-line); border-radius: 999px;
  background: rgba(255, 255, 255, 0.78);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  text-decoration: none; color: inherit;
  box-shadow: 0 2px 10px rgba(23, 48, 77, 0.07);
  transition: transform 0.25s var(--ease), border-color 0.25s var(--ease),
              box-shadow 0.25s var(--ease), background 0.25s var(--ease);
}
.hilite__fig {
  font-family: var(--display); font-size: clamp(1.15rem, 2vw, 1.45rem);
  line-height: 1; color: var(--bone);
}
.hilite__lab {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bone-3); text-align: center;
  white-space: nowrap;
}
.hilite__a:hover,
.hilite__a:focus-visible {
  transform: translateY(-2px);
  border-color: var(--gold);
  background: #fff;
  box-shadow: 0 6px 18px rgba(23, 48, 77, 0.13);
}
.hilite__a:hover .hilite__fig,
.hilite__a:focus-visible .hilite__fig { color: var(--gold); }

/* Narrow screens: the labels are the part that has to give. Wrapping them
   turns five pills into five paragraphs, so they shrink and stay on one line
   until there is genuinely no room, at which point the pills stack two-up. */
@media (max-width: 40rem) {
  .hilite { gap: 0.4rem; }
  .hilite__a { padding: 0.5rem 0.8rem 0.55rem; }
  .hilite__lab { font-size: 0.53rem; letter-spacing: 0.06em; }
}

@media (prefers-reduced-motion: reduce) {
  .hilite__a { transition: none; }
  .hilite__a:hover, .hilite__a:focus-visible { transform: none; }
}

/* A hotlinked photograph arrives when it arrives. Until then the tile was a
   white square on a white page, which reads as a broken image rather than a
   loading one; a faint tint says "something is coming here". */
.mtile { background: var(--ink-3); }

/* ==========================================================================
   Two ways in, the marketplace's invitation to sell

   Placed after the grid rather than above it. A banner at the top of a page
   asks for something before giving anything; by the bottom the reader has seen
   what the index actually is, and "I have one of these" is the thought they
   are most likely to be having.

   Two buttons rather than one, because the two audiences want opposite things:
   a private seller with a single object needs a form that asks about the
   object, and an auction house with four hundred lots needs one that asks
   about the catalogue. Sending both down the same route would waste
   everybody's time, so the split happens here, in the open, where each reader
   can see which one is theirs.
   ========================================================================== */
.sellcta {
  margin: clamp(3.5rem, 8vw, 6rem) 0 0;
  padding: clamp(2rem, 4.5vw, 3.25rem) 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0));
}
.sellcta__inner {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center;
}
.sellcta__t {
  margin: 0.5rem 0 0; font-family: var(--display); font-weight: 400;
  font-size: clamp(1.6rem, 3.2vw, 2.35rem); line-height: 1.08;
  color: var(--bone); text-wrap: balance; max-width: 24ch;
}
.sellcta__l {
  margin: 0.85rem 0 0; font-size: 1rem; line-height: 1.6;
  color: var(--panel-body); max-width: 46ch;
}

.sellcta__acts { display: grid; gap: 0.75rem; }

/* A card, not a pill: each carries a title and the line that says who it is
   for, and that second line is the part that does the sorting. */
.sellcta__btn {
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 1rem 1.25rem;
  text-decoration: none;
  background: var(--gold); border: 1px solid var(--gold); border-radius: 4px;
  box-shadow: 0 4px 14px rgba(122, 94, 31, 0.2);
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease), background 0.22s var(--ease);
}
.sellcta__btnt {
  font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.12em;
  text-transform: uppercase; font-weight: 500; color: var(--on-gold);
}
.sellcta__btns { font-size: 0.85rem; line-height: 1.4; color: rgba(36, 29, 14, 0.78); }
.sellcta__btn:hover {
  background: var(--gold-hi); transform: translateY(-2px);
  box-shadow: 0 7px 20px rgba(122, 94, 31, 0.26);
}

/* The dealer route is the quieter of the two. Fewer people need it, and the
   ones who do are looking for it rather than being sold it. */
.sellcta__btn--alt {
  background: rgba(255, 255, 255, 0.8); border-color: var(--line-2);
  box-shadow: 0 2px 10px rgba(23, 48, 77, 0.08);
}
.sellcta__btn--alt .sellcta__btnt { color: var(--bone); }
.sellcta__btn--alt .sellcta__btns { color: var(--bone-3); }
.sellcta__btn--alt:hover {
  background: #fff; border-color: var(--gold);
  box-shadow: 0 6px 18px rgba(23, 48, 77, 0.13);
}
.sellcta__btn--alt:hover .sellcta__btnt { color: var(--gold); }

@media (max-width: 52rem) {
  .sellcta__inner { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .sellcta__btn { transition: none; }
  .sellcta__btn:hover { transform: none; }
}

/* The nav's one outbound ask. Marked rather than shouted: a filled button in a
   text nav pulls the eye off the three links a visitor actually arrived for. */
.nav__link--act { color: var(--gold); }
.nav__link--act::after { background: var(--gold); }

/* The extra paragraph on the thank-you page, shown only for the submissions
   that need more than a line. Somebody who has just uploaded photographs of an
   object they own and named a price needs to know what happens next, when, and
   what a "no" looks like, or they will spend the week refreshing the
   marketplace looking for their item. */
.thanks__extra {
  margin: 1rem 0 0; font-size: 0.95rem; line-height: 1.6;
  color: var(--bone-3); max-width: 58ch;
  padding-left: 1rem; border-left: 2px solid var(--gold);
}

/* ==========================================================================
   Direct from collectors, items whose owner is the seller

   These look deliberately unlike the indexed cards around them, and the
   difference is information rather than decoration. An indexed card is a
   pointer at somebody else's listing and ends in a click-out. One of these is
   an object being offered here and nowhere else, with no checkout behind it,
   which means the reader's next step is a conversation rather than a purchase.
   A card that looked identical to the eBay ones would be promising a
   transaction that does not exist.

   So: a gold-edged flag on the photograph naming who is selling, warmer
   ground, and a price labelled with what kind of price it is.
   ========================================================================== */
.sdirect {
  margin: clamp(2rem, 5vw, 3.25rem) 0 clamp(1.5rem, 3vw, 2.25rem);
  padding: clamp(1.25rem, 3vw, 2rem);
  background: linear-gradient(180deg, rgba(255, 252, 245, 0.9), rgba(255, 255, 255, 0.5));
  border: 1px solid var(--panel-line);
  border-top: 2px solid var(--gold);
  border-radius: 4px;
}
.sdirect__head {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: 0.75rem 2rem;
}
.sdirect__t {
  margin: 0; font-family: var(--display); font-weight: 400;
  font-size: clamp(1.3rem, 2.6vw, 1.85rem); line-height: 1.1; color: var(--bone);
}
.sdirect__l {
  margin: 0.4rem 0 0; font-size: 0.92rem; line-height: 1.55;
  color: var(--panel-body); max-width: 62ch;
}
.sdirect__row {
  margin-top: clamp(1rem, 2.5vw, 1.5rem);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: clamp(0.75rem, 1.8vw, 1.1rem);
}

.scard {
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
  background: #fff; border: 1px solid var(--line); border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 3px 12px rgba(23, 48, 77, 0.08);
  transition: transform 0.22s var(--ease), border-color 0.22s var(--ease), box-shadow 0.22s var(--ease);
}
.scard:hover {
  transform: translateY(-2px); border-color: var(--gold);
  box-shadow: 0 7px 20px rgba(23, 48, 77, 0.14);
}
.scard__shot { position: relative; display: block; aspect-ratio: 4 / 3; background: var(--ink-3); }
.scard__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.scard__none { display: block; width: 100%; height: 100%; background: var(--ink-3); }
.scard__flag {
  position: absolute; left: 0; bottom: 0;
  font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-gold); background: var(--gold);
  padding: 0.2rem 0.45rem; border-top-right-radius: 2px;
}
.scard__body { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.75rem 0.85rem 0.85rem; }
.scard__t { font-size: 0.92rem; line-height: 1.35; color: var(--bone); }
.scard__foot { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
.scard__foot b { font-size: 1.05rem; color: var(--bone); }
.scard__kind {
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--bone-3);
}
.scard__ends { font-size: 0.72rem; color: var(--bone-3); }


/* ==========================================================================
   The head of the listings

   Two things on one line: where the listings come from, and the fact that you
   can add to them. The second used to live only at the foot of the page, past
   eighteen hundred cards, which is a long way to scroll to find out a route
   exists at all.

   It is also the scroll target for the hero's "Current live listings" bubble.
   That bubble linked to /marketplace/, which IS this page, so clicking it did
   nothing: the browser resolved the href, decided it was already there, and
   stayed put. An in-page anchor scrolls instead. scroll-margin-top clears the
   fixed header and the sticky filter bar, without which the line the reader
   was sent to arrives hidden behind both.
   ========================================================================== */
.mkt__lead {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 0.75rem 1.5rem;
  margin-bottom: 1rem;
  scroll-margin-top: calc(var(--top-h) + 3.75rem);
}
.mkt__lead .mkt__source { margin: 0; }

/* Two routes in, at different weights. Listing one object is the thing most
   readers could do today, so it is the filled gold box. Linking a whole
   marketplace is rarer and starts a conversation, so it sits beside it in
   outline. An outlined pill for both would have made them look like a pair of
   filters. */
.mkt__acts { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.mkt__list {
  display: flex; align-items: baseline; gap: 0.55rem; flex-wrap: wrap;
  text-decoration: none;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--gold); border-radius: 4px;
  background: var(--gold);
  transition: background 0.2s var(--ease), box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
  box-shadow: 0 3px 12px rgba(122, 94, 31, 0.2);
}
.mkt__listt {
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em;
  text-transform: uppercase; font-weight: 500; color: #fff;
}
/* Not pure white. At 0.8rem against this gold, full white vibrates; pulling it
   back a little keeps it legible without turning it grey. */
.mkt__lists { font-size: 0.8rem; color: rgba(255, 255, 255, 0.85); }
.mkt__list:hover {
  background: var(--gold-hi); transform: translateY(-1px);
  box-shadow: 0 5px 16px rgba(122, 94, 31, 0.28);
}

.mkt__list--alt {
  background: rgba(255, 255, 255, 0.75);
  box-shadow: 0 2px 8px rgba(23, 48, 77, 0.06);
}
.mkt__list--alt .mkt__listt { color: var(--gold); }
.mkt__list--alt .mkt__lists { color: var(--bone-3); }
.mkt__list--alt:hover { background: #fff; box-shadow: 0 5px 16px rgba(23, 48, 77, 0.12); }
.mkt__list--alt:hover .mkt__listt { color: var(--gold-hi); }

@media (max-width: 60rem) {
  /* The sourcing line and the buttons stop competing for one row. */
  .mkt__lead { align-items: flex-start; }
}
@media (max-width: 34rem) {
  .mkt__lead { gap: 0.5rem; }
  .mkt__acts { width: 100%; }
  .mkt__list { flex: 1 1 100%; }
  .mkt__lists { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .mkt__list { transition: none; }
  .mkt__list:hover { transform: none; }
}

/* ==========================================================================
   The pager

   Three things, and their order is the order they are wanted in: where you
   are, how to move, and how much to see at once. The count sits first because
   it is the one a reader looks at without meaning to.

   The page buttons are drawn by the script, because how many there are depends
   on the filter. The count and the size selector are in the HTML so the shape
   does not jump into place after load.
   ========================================================================== */
.pager {
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding-top: clamp(1.25rem, 3vw, 1.75rem);
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 1rem 1.5rem;
}
.pager__count { margin: 0; font-size: 0.9rem; color: var(--bone-3); }
.pager__count b { color: var(--bone); font-weight: 600; }

.pager__pages { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; }

.pager__b {
  font: inherit; font-family: var(--mono); font-size: 0.8rem;
  min-width: 2.35rem; padding: 0.5rem 0.6rem;
  color: var(--bone); background: rgba(255, 255, 255, 0.65);
  border: 1px solid var(--line-2); border-radius: 3px;
  cursor: pointer;
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease), color 0.18s var(--ease);
}
.pager__b:hover:not(:disabled) { border-color: var(--gold); color: var(--gold); background: #fff; }
.pager__b:disabled { opacity: 0.35; cursor: default; }

/* The current page is filled rather than outlined. An outline that differs
   only in colour is not enough to find at a glance in a row of nine. */
.pager__b.is-current {
  background: var(--gold); border-color: var(--gold); color: var(--on-gold);
  font-weight: 600;
}
.pager__b.is-current:hover { color: var(--on-gold); background: var(--gold); }

.pager__gap { padding: 0 0.15rem; color: var(--line-2); font-family: var(--mono); }

.pager__per { margin: 0; display: flex; align-items: center; gap: 0.5rem; }
.pager__perl {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bone-3);
}
/* The select borrows the form stylesheet's shape, which the marketplace page
   does not load, so the few rules it needs are restated here rather than
   pulling in the whole of database.css for one dropdown. */
.pager__perwrap { position: relative; display: block; }
.pager__persel {
  appearance: none; -webkit-appearance: none;
  font: inherit; font-size: 0.85rem; color: var(--bone);
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid var(--line-2); border-radius: 3px;
  padding: 0.45rem 2rem 0.45rem 0.7rem;
  cursor: pointer;
}
.pager__persel:hover { border-color: var(--gold); }
.pager__perwrap .qf__caret {
  position: absolute; right: 0.7rem; top: 50%; transform: translateY(-50%);
  color: var(--bone-3); pointer-events: none;
}

@media (max-width: 44rem) {
  .pager { justify-content: center; text-align: center; }
  .pager__pages { order: -1; width: 100%; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .pager__b { transition: none; }
}

/* ==========================================================================
   BACK BAR

   Filled in by the script at the foot of every page, and only when the reader
   actually came from somewhere on this site. Sits above the page's own
   breadcrumbs, which point at the parent rather than at where you were.

   `hidden` does the hiding, so a reader with JavaScript off sees nothing
   rather than an empty bar reserving space for a link that never arrives.
   ========================================================================== */
.backbar[hidden] { display: none; }

.backbar {
  /* Same box as .wrap, so the link lines up with the page title beneath it
     rather than floating at its own margin. */
  width: 100%; max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-top: clamp(0.9rem, 2vw, 1.4rem);
}

.backbar__link {
  display: inline-block;
  font-size: var(--t-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold);
  text-decoration: none;
  /* A generous target: this is the control a reader reaches for most, and on
     a phone it is competing with the thumb that just tapped a table row. */
  padding: 0.35rem 0;
}
.backbar__link:hover,
.backbar__link:focus-visible { text-decoration: underline; }

/* ==========================================================================
   PRICE RANGE

   Two number boxes instead of a searchable list of bands. The floor line is
   part of the control, not a footnote: type 20 into the min box and nothing
   comes back, which looks like a broken filter unless the page has already
   said we do not list under $75.
   ========================================================================== */
.combo--price .combo__panel { min-width: 17rem; }

.prange {
  display: flex; align-items: flex-end; gap: 0.5rem;
  padding: 0.75rem 0.75rem 0.25rem;
}
.prange__field { display: flex; flex-direction: column; gap: 0.3rem; flex: 1 1 0; min-width: 0; }
.prange__cap {
  font-family: var(--mono); font-size: var(--t-label);
  letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.6;
}
.prange__wrap { position: relative; display: block; }
.prange__dollar {
  position: absolute; left: 0.6rem; top: 50%; transform: translateY(-50%);
  opacity: 0.5; pointer-events: none; font-size: 0.95em;
}
.prange__in {
  width: 100%; font: inherit; font-size: 0.95rem;
  padding: 0.5rem 0.5rem 0.5rem 1.5rem;
  border: 1px solid rgba(128, 128, 128, 0.35); border-radius: 6px;
  background: transparent; color: inherit;
}
.prange__in:focus-visible { outline: none; border-color: var(--gold); }
/* The spinners are 20px of chrome on a box that wants to be typed into. */
.prange__in::-webkit-outer-spin-button,
.prange__in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.prange__in { -moz-appearance: textfield; appearance: textfield; }
.prange__to { padding-bottom: 0.6rem; opacity: 0.5; font-size: 0.9rem; }

.prange__floor {
  margin: 0; padding: 0 0.75rem 0.6rem;
  font-size: var(--t-small); opacity: 0.6;
}
.prange__presets { border-top: 1px solid rgba(128, 128, 128, 0.22); padding-top: 0.25rem; }

/* ==========================================================================
   MOBILE LEGIBILITY

   Owner, 2026-08-29: "text is crammed, stuff is in weird places". Measured on
   a 375px viewport before changing anything, which is how the real cause
   turned up: the type scale is desktop-first and nothing overrode it. The
   Database page rendered 177 elements at 10px and 176 at 11px; the home page
   had listing prices at 8.3px, deliberately shrunk by a rule written when the
   tiles were decoration rather than something anyone reads.

   The three small tokens are the whole problem, so they are raised here
   rather than chased through the two hundred rules that use them. Nothing on
   a phone should render below about 12px, and the label size does most of
   the work because the mono uppercase labels are everywhere.

   Kept to a single breakpoint. A second one would mean two sizes to reason
   about for every element and there is no evidence yet that 480 and 640 want
   different answers.
   ========================================================================== */
@media (max-width: 40rem) {
  :root {
    --t-small: 0.9375rem;   /* 15px, was 14 */
    --t-label: 0.8125rem;   /* 13px, was 11 */
    --t-micro: 0.75rem;     /* 12px, was 10 */
    /* The lede stops shrinking: clamp's lower bound was tuned for a desktop
       minimum and reads as body copy on a phone, where it is the first thing
       anyone reads. */
    --t-lede: 1.0625rem;
  }

  /* A price is the second thing a visitor looks at on a tile, after the
     photograph. 0.52rem was 8.3px, which is smaller than a legal footnote. */
  /* Sized to the tile rather than shrunk to fit it: at 0.75rem the badge was
     wider than its own thumbnail and "$100,000" lost its last digit, which is
     worse than small type. The padding goes instead of the type. */
  /* Four tiles a row, not twelve. At twelve each tile was 64px wide, which is
     too small to read a photograph and too narrow for its own price label:
     "$2,499.99" lost its last digits whatever size the type was. Fewer and
     larger is the fix, and the wall is a display of what is for sale rather
     than an inventory, so showing eight of them says the same thing. */
  /* Four tiles, not five. The existing rule already cut the band to one row
     of five and hid the rest, which was the right instinct; at five each tile
     was 64px, too small to read a photograph and too narrow for its own price
     label, so "$2,499.99" lost its last digits at any type size. One row is
     still one row, with four tiles you can actually see. */
  .mhero__wall { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .mtile:nth-child(n+5) { display: none; }
  .mtile__price { font-size: 0.75rem; padding: 0.15rem 0.3rem; right: 0;
                  max-width: 100%; box-sizing: border-box; }

  /* THE NAV. Four links in a mono uppercase row with 0.16em tracking, at
     11px, on a 375px screen. Raising the type alone would overflow it, so
     the row wraps and the tracking comes in. */
  /* The bar has a fixed height, so a wrapped nav spilled through its own
     bottom border and sat on top of the page beneath. Letting it grow is the
     fix; the height variable becomes a minimum rather than a promise. */
  .nav { height: auto; min-height: 0; padding-block: 0.35rem; }
  .nav__inner { flex-wrap: wrap; gap: 0.15rem 0; }
  /* Measured, not guessed: at 13px with 0.08em tracking and a 0.9rem gap the
     four links needed 361px against 335px available, so they wrapped to two
     rows and the bar took 120px, about a sixth of the screen. Tightening the
     gap and the tracking recovers roughly 32px, which is enough, and leaves
     the type at a readable 13px rather than shrinking it back. */
  .nav__links { flex-wrap: wrap; gap: 0 0.65rem; width: 100%; }
  /* Tracking comes in so four links need less width, and the padding buys a
     real tap target out of 13px of text: 17px tall before, per the guidance
     Apple and Google both give. Tight enough that two rows of nav do not eat
     a sixth of the screen. */
  /* font-size stated explicitly: an earlier mobile rule pins this to 0.66rem
     (10.56px) and raising the token alone left it untouched, because that
     rule sets the property directly. */
  .nav__link { font-size: var(--t-label); letter-spacing: 0.04em; padding: 0.42rem 0; }

  /* The roster is the Database page, and these two lines are its whole grid:
     157 "1 sold" counts at 10.9px and 143 category words at 10.2px, both
     hardcoded rather than tokenised, which is why raising the tokens missed
     300 elements on the one page that has the most of them. */
  .rost__n { font-size: 0.8125rem; }
  .rost__none { font-size: 0.78rem; opacity: 0.7; }

  /* The last few, each pinned by its own rule rather than by a token.
     hilite__lab was the worst on the page at 8px: it captions the three
     figures under the wordmark, which are the first numbers anyone reads. */
  .hilite__lab { font-size: 0.75rem; }
  .combo__btn, .combo__label, .combo__value { font-size: 0.8125rem; }
  .soldcard__meta { font-size: 0.8125rem; }
  .footsub__eyebrow { font-size: 0.75rem; }

  /* The sold-archive filters are handled in that page's own inline styles,
     which win on document order anyway. Nothing for them here. */
}
