/* ==========================================================================
   BUILDMYTRUCK — "Onyx & Gold" design system
   Luxury automotive black with a champagne-gold signature accent. Restraint
   over neon: hairline golds, soft depth, uppercase display type, serif
   ledes. (Owner direction 2026-07-09: gold/black, not green.)
   NOTE: the accent variable keeps the historical name --volt so every
   component reference keeps working; its VALUE is gold now.
   ========================================================================== */

/* Hidden means hidden, everywhere.
   Any rule that sets `display` outranks the browser's own [hidden] default, so
   a component with `display: flex` stays on the screen after JavaScript sets
   el.hidden = true. This has been discovered and patched one component at a
   time — the size chart, the cart summary, the added-to-list panel, the quote
   panel — and each patch left the next component to find it again. The stance
   menu on the wheel page was the one nobody had found: it is meant to appear
   only when it is the last thing left to decide, and it has been on screen the
   whole time (owner, 2026-09-17). One rule, at the top, for all of them. */
[hidden] { display: none !important; }

/* Vendored Barlow Condensed — the condensed-bold automotive display type every
   real parts store uses (research 2026-07-09: zero serif, all-caps condensed). */
@font-face { font-family: "Oswald"; font-weight: 500; font-style: normal;
  font-display: swap; src: url("/static/fonts/oswald-500.woff2") format("woff2"); }
@font-face { font-family: "Oswald"; font-weight: 600; font-style: normal;
  font-display: swap; src: url("/static/fonts/oswald-600.woff2") format("woff2"); }
@font-face { font-family: "Oswald"; font-weight: 700; font-style: normal;
  font-display: swap; src: url("/static/fonts/oswald-700.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 400; font-style: normal;
  font-display: swap; src: url("/static/fonts/manrope-400.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 500; font-style: normal;
  font-display: swap; src: url("/static/fonts/manrope-500.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 700; font-style: normal;
  font-display: swap; src: url("/static/fonts/manrope-700.woff2") format("woff2"); }
@font-face { font-family: "Barlow Condensed"; font-weight: 500; font-style: normal;
  font-display: swap; src: url("/static/fonts/barlow-condensed-500.woff2") format("woff2"); }
@font-face { font-family: "Barlow Condensed"; font-weight: 600; font-style: normal;
  font-display: swap; src: url("/static/fonts/barlow-condensed-600.woff2") format("woff2"); }
@font-face { font-family: "Barlow Condensed"; font-weight: 700; font-style: normal;
  font-display: swap; src: url("/static/fonts/barlow-condensed-700.woff2") format("woff2"); }

:root {
  --ink-0: #08090b;            /* page background — asphalt at night */
  --ink-1: #0e1013;            /* raised panel */
  --ink-2: #15181d;            /* card */
  --ink-3: #1e2229;            /* card hover / input */
  --line: #262b33;             /* hairlines */
  --line-bright: #3a414c;
  --text-0: #f2f4f6;           /* headlines */
  --text-1: #b8bec7;           /* body */
  /* muted. Was #7d848f: 4.23:1 on a raised panel (--ink-3), under the WCAG AA
     4.5:1 minimum, so every gray status badge and hint failed. #8f96a0 is 5.35:1
     on --ink-3 and 6.7:1 on the page, and still clearly dimmer than --text-1. */
  --text-2: #8f96a0;
  /* champagne-gold ramp (5 stops) */
  --gold-100: #f3e4c3;
  --gold-300: #e3c489;
  --gold-500: #c9a15b;
  --gold-600: #a9843f;
  --gold-700: #7d5f2c;
  --volt: #c9a15b;             /* THE accent — champagne gold */
  --volt-dim: #a9843f;
  --volt-glow: rgba(212, 175, 55, 0.20);
  /* polished-metal gold: specular highs + deep lows, like machined brass */
  --gold-metal: linear-gradient(168deg,
      #f8efd6 0%, #f3e4c3 16%, #e3c489 34%, #c9a15b 50%,
      #7d5f2c 60%, #a9843f 74%, #e3c489 90%, #f3e4c3 100%);
  --gold-metal-x: linear-gradient(100deg,
      #a9843f 0%, #e3c489 28%, #f8efd6 50%, #c9a15b 70%, #7d5f2c 100%);
  --chrome: #cfd6de;
  --danger: #ff5d5d;
  --radius: 10px;
  --radius-lg: 16px;
  --shadow-card: 0 10px 30px rgba(0, 0, 0, 0.55);
  --font-display: "Oswald", "Barlow Condensed", "Arial Narrow", system-ui, sans-serif;
  --font-body: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* The header is sticky, so an anchor used to land with the top of the card
     under it: 217px of a deal's card — its name, its phone, its badge — hidden
     on a phone, which is how the wrong customer gets called (desk walk
     2026-09-17). */
  scroll-padding-top: 150px;
}
/* full-bleed sections size themselves with vw, which includes the scrollbar;
   clip the few-px overhang instead of growing a horizontal scrollbar */
body { overflow-x: clip; }

body {
  margin: 0;
  background:
    radial-gradient(1200px 500px at 75% -10%, rgba(212, 175, 55, 0.05), transparent 60%),
    linear-gradient(180deg, #0a0c0f 0%, var(--ink-0) 30%);
  background-color: var(--ink-0);
  color: var(--text-1);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* ---------- gold text ----------
   Solid gold, not a gradient fill (style reference, approved 2026-09-15):
   gradient-filled text was one of the things that read as generated. The metal
   gradient stays where it earns its place, on the gold button. A price is the
   plainest fact on a page, so it is white. */
.kicker, .brand b, .gold { color: var(--gold-300); }
.stat b { color: var(--text-0); }
.card .price .from { color: var(--text-2); }

/* ---------- type ---------- */
/* Capitals for page titles, buttons and small labels, nowhere else, and sizes
   only from the roles in :root (style reference, approved 2026-09-15). */
h1, h2, h3, .display {
  font-family: var(--font-display);
  color: var(--text-0);
  letter-spacing: 0.01em;
  line-height: 1.08;
  margin: 0 0 0.5em;
}
h1, .display { text-transform: uppercase; letter-spacing: 0.015em; line-height: 1.02; }
h1 { font-size: var(--text-title); font-weight: 700; }
h2 { font-size: var(--text-section); font-weight: 600; }
h3 { font-size: var(--text-name); font-weight: 500; }
.kicker {
  color: var(--gold-300);
  font-family: var(--font-body);
  font-weight: 700;
  text-transform: uppercase;
  font-size: var(--text-label);
  letter-spacing: 0.14em;
  margin-bottom: 0.9rem;
}
.lede { color: var(--text-1); font-size: var(--text-lead); max-width: 46rem; }
a { color: var(--chrome); text-decoration: none; }
a:hover { color: var(--text-0); }

/* ---------- shell ---------- */
.wrap { max-width: 1280px; margin: 0 auto; padding: 0 24px; }

.site-nav {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
  padding: 14px 26px;
  background: rgba(8, 9, 11, 0.86);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.brand {
  font-family: var(--font-display);
  font-size: var(--text-lead); letter-spacing: 0.04em;
  color: var(--text-0); text-transform: uppercase;
  display: flex; align-items: center; gap: 10px;
}
.brand b { color: var(--volt); }
.brand .tick {
  width: 10px; height: 22px; background: var(--volt);
  transform: skewX(-18deg); border-radius: 2px;
  box-shadow: 0 0 14px var(--volt-glow);
}
.site-nav .links { display: flex; gap: 22px; margin-left: auto; align-items: center; }
.site-nav .links a {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: var(--text-small); letter-spacing: 0.14em; color: var(--text-1);
}
.site-nav .links a { white-space: nowrap; }
.site-nav .links a:hover { color: var(--volt); }
.site-nav .links a.cart-link { color: var(--chrome); }

/* ---------- buttons ---------- */
/* `.btn` alone. It also said `button.btn`, which outranks `.btn-ghost` and
   `.btn-sm`: every outline button written as a <button> lost its border (Add to
   build list, the cart's remove) and every small one rendered full size. No
   other stylesheet styles bare buttons, so nothing needed that extra weight. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.08em; font-size: var(--text-small);
  padding: 14px 26px; border-radius: var(--radius);
  border: 1px solid transparent; cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.2s ease, background 0.2s;
}
.btn-volt {
  background: var(--gold-metal-x);
  background-size: 220% 100%;
  background-position: 15% 0;
  color: #141005;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.5), inset 0 -1px 0 rgba(0, 0, 0, 0.25);
  transition: background-position 0.55s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-volt:hover { transform: translateY(-1px); background-position: 85% 0; box-shadow: 0 10px 26px rgba(0,0,0,0.5), 0 0 18px var(--volt-glow); color: #000; }
.btn-ghost {
  background: transparent; color: var(--text-0);
  border-color: var(--line-bright);
}
.btn-ghost:hover { border-color: var(--volt); color: var(--volt); }
.btn-block { width: 100%; }

/* ---------- cards / panels ---------- */
.panel {
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.card {
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color 0.2s ease;
  display: flex; flex-direction: column;
}
/* Under the pointer the border turns gold, and nothing lifts or zooms. */
.card:hover { border-color: var(--volt-dim); }
/* Every product on white, edge to edge -- wheels, tires, lift kits and parts
   alike. The parts shelf was the one the owner loved; the wheel shelf drew
   its wheels on a dark vignette and read as another store (2026-09-18: "it's
   a different experience when you're on wheels versus lift kits versus
   tires"). One card look, every shelf. */
.card .thumb {
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  background: #fff;
  border-bottom: 1px solid var(--line);
  padding: 7%;
}
/* `width: auto; height: auto` is load-bearing wherever an <img> carries HTML
   width/height attributes: the attributes are there to reserve the box before
   the photo lands, but with only max-* set they become the USED size and the
   wheel renders as a tall oval. Same reason .ba img needs height: auto. */
.card .thumb img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.card .body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.card .brand-line { color: var(--text-2); font-size: var(--text-label); font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em; }
.card .name { font-family: var(--font-display); color: var(--text-0); font-size: var(--text-name); font-weight: 500; letter-spacing: 0.01em; }
.card .meta { color: var(--text-2); font-size: var(--text-small); }
.card .price { margin-top: auto; padding-top: 10px; color: var(--text-0); font-weight: 700; font-size: var(--text-name); }
.card .price .from { color: var(--text-2); font-weight: 400; font-size: var(--text-small); margin-right: 6px; text-transform: uppercase; letter-spacing: 0.08em; }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-label); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 99px;
  /* A label, never a paragraph: in the tire size table "We confirm lead time"
     wrapped to three lines and turned the pill into an oval. The table scrolls. */
  white-space: nowrap;
  background: rgba(212, 175, 55, 0.12); color: var(--volt);
  border: 1px solid rgba(212, 175, 55, 0.35);
}
.badge.gray { background: var(--ink-3); color: var(--text-2); border-color: var(--line); }

/* ---------- hero ---------- */
.hero { padding: 84px 0 60px; }
.hero .stat-row { display: flex; gap: 40px; margin-top: 34px; flex-wrap: wrap; }
.stat { display: flex; flex-direction: column; gap: 2px; }
.stat b { font-size: var(--text-section); line-height: 1; }
.hero .stat b { display: block; font-family: var(--font-display); font-size: var(--text-section); color: var(--text-0); }
.hero .stat span { color: var(--text-2); font-size: var(--text-small); text-transform: uppercase; letter-spacing: 0.14em; }
.showcase {
  position: relative; border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--line-bright); box-shadow: var(--shadow-card);
}
.showcase img { display: block; width: 100%; }
.showcase .tag {
  position: absolute; top: 14px; left: 14px;
}
.ba { position: relative; overflow: hidden; border-radius: var(--radius-lg);
  /* dragging the divider must never select text or lift the image ("wonky
     highlight", owner 2026-07-09) */
  user-select: none; -webkit-user-select: none; touch-action: pan-y; cursor: ew-resize; }
.ba img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
.ba img { width: 100%; height: auto; display: block; }
.ba picture { display: block; }
.ba .after { position: absolute; inset: 0; clip-path: inset(0 0 0 50%); }
.ba .handle {
  position: absolute; top: 0; bottom: 0; left: 50%; width: 2px;
  background: var(--gold-metal); box-shadow: 0 0 14px var(--volt-glow), inset 0 1px 0 rgba(255,255,255,.5); cursor: ew-resize;
}
.ba .handle::after {
  content: "◂ ▸"; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--gold-metal-x); color: #141005; font-size: var(--text-label); font-weight: 900;
  padding: 7px 9px; border-radius: 99px; white-space: nowrap;
}

/* ---------- sections ---------- */
/* Top and bottom only. Most sections are also .wrap, and a `padding` shorthand
   here (it comes later, same weight) zeroed .wrap's side gutter: store, tires,
   cart and account text sat flush against the edge of a phone, and of a
   1280px laptop. */
.section { padding-block: clamp(72px, 8vw, 112px); }
.section-head { display: flex; align-items: end; justify-content: space-between; gap: 20px; margin-bottom: 40px; }
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.step { padding: 26px 24px; }
.step .num {
  font-family: var(--font-display); color: var(--volt); font-size: var(--text-section);
  text-shadow: 0 0 18px var(--volt-glow);
}
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(266px, 1fr)); gap: 22px; }

/* The tail of a truncated brand chapter, and the pager under a brand grid.
   Both exist so a browsing page stays a fixed, quick size instead of growing
   with the catalog. */
.card-more {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 24px; text-align: center; min-height: 200px;
  border-style: dashed; border-color: var(--line-bright); text-decoration: none;
}
.card-more:hover { border-style: solid; }
/* Under 24px tall on a phone. The padding IS the tap area; the negative margin
   keeps the layout where it was. (.linkish is fixed at its own rule further
   down — a second one here loses to it and silently does nothing.) */
.brand-divider-link { padding: 12px 0; margin: -12px 0; }
.card-more-n {
  font-family: var(--font-display); font-size: var(--text-section); line-height: 1;
  color: var(--volt);
}
.card-more-label { color: var(--text-1); font-size: var(--text-small); max-width: 15ch; }
.card-more-go {
  margin-top: 6px; color: var(--volt); font-size: var(--text-small);
  text-transform: uppercase; letter-spacing: 0.18em;
}
.more-row {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  margin: 32px 0 8px;
}
.more-count { color: var(--text-2); font-size: var(--text-small); }

/* ---------- shop filters ---------- */
.filter-bar {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding: 14px 16px; margin-bottom: 24px;
}
.filter-bar select, .filter-bar input[type="text"], .field input, .field select {
  background: var(--ink-3); color: var(--text-0);
  border: 1px solid var(--line-bright); border-radius: 8px;
  padding: 10px 12px; font: inherit;
}
.filter-bar label.toggle { display: inline-flex; gap: 8px; align-items: center; color: var(--text-1); font-size: var(--text-small); }

/* ---------- product page ---------- */
.product-grid { display: grid; grid-template-columns: 1.05fr 1fr; gap: 44px; align-items: start; padding-block: 44px; }
/* The name is written before the photograph so that a phone, which stacks this
   grid into one column, reads brand -> name -> photo -> price. On a laptop
   these three rules put it back at the top of the right-hand column, which is
   where it has always been drawn. */
.product-title { grid-column: 2; grid-row: 1; }
.product-media { grid-column: 1; grid-row: 1 / span 2; }
.product-buy   { grid-column: 2; grid-row: 2; }
.product-title .product-name { margin-top: 2px; }
/* A grid item's default min-width is AUTO, i.e. its content's minimum — so the
   size table (which is wide by nature and scrolls in its own box) pushed the
   whole column past the viewport, and the PAGE scrolled sideways on a phone:
   459px of content in a 390px window, measured on an iPhone viewport. The
   column may shrink; the table keeps scrolling inside its own container. */
.product-grid > * { min-width: 0; }
.product-stage {
  border-radius: var(--radius-lg); border: 1px solid var(--line);
  background:
    radial-gradient(65% 60% at 50% 42%, #262c35 0%, #131519 75%),
    repeating-linear-gradient(135deg, rgba(255,255,255,0.012) 0 2px, transparent 2px 6px);
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; padding: 8%;
}
.product-stage img { max-width: 100%; max-height: 100%; width: auto; height: auto;
  filter: drop-shadow(0 26px 40px rgba(0,0,0,0.65)); }
.spec-table { width: 100%; border-collapse: collapse; font-size: var(--text-small); }
.spec-table th, .spec-table td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--line); }
.spec-table th { color: var(--text-2); font-weight: 600; text-transform: uppercase; font-size: var(--text-label); letter-spacing: 0.14em; }

/* ---------- the price box ----------
   Price, picks, fit and the buttons in one panel, the way a store sells a
   wheel. A wheel is priced one at a time and bought four at a time, so both
   numbers are printed and both follow the pick — the multiplying is the
   store's job, not the customer's. */
.price-box {
  margin: 18px 0 6px; padding: 20px; border: 1px solid var(--line);
  border-radius: var(--radius-lg); background: var(--ink-1);
  display: flex; flex-direction: column; gap: 14px;
}
.price-lines { display: grid; gap: 4px; }
.price-money { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; }
.price-each, .price-set { margin: 0; }
.price-each {
  font-family: var(--font-display); font-size: var(--text-section);
  color: var(--text-0); line-height: 1.1;
}
.price-lines .from, .price-set span {
  font-family: var(--font-body); font-size: var(--text-label); font-weight: 700;
  color: var(--text-2); text-transform: uppercase; letter-spacing: 0.12em;
}
.price-each .per {
  font-family: var(--font-body); font-size: var(--text-small); color: var(--text-2);
  margin-left: 7px;
}
.price-set b {
  font-family: var(--font-display); font-size: var(--text-name); font-weight: 600;
  color: var(--text-0); margin-right: 7px;
}
/* The pick, read back. Plain while something is still open; marked once it
   resolves to one orderable wheel. */
.fit-line { margin: 0; color: var(--text-2); font-size: var(--text-small); }
.fit-line.is-set {
  color: var(--text-0); border-left: 2px solid var(--volt); padding-left: 12px;
}
.fit-line.is-set::before { content: "✓ "; color: var(--gold-300); }
.buy-row { display: flex; gap: 12px; flex-wrap: wrap; }
.buy-row .btn { flex: 1 1 auto; }
.buy-call { margin: 0; font-size: var(--text-small); color: var(--text-1); }
.buy-call a { color: var(--gold-300); font-weight: 700; }
.buy-terms { margin: 0; font-size: var(--text-small); color: var(--text-2); }

.product-head { max-width: 680px; }
/* The tire page has no photograph, so what an order includes takes the half a
   photo would have filled. It stacks under the price box on a narrow screen. */
.tire-product { padding-block: 10px 48px; }
.tire-top { display: grid; gap: 30px 44px; align-items: start; margin-top: 18px; }
.tire-aside .incl { grid-template-columns: 1fr; margin-top: 0; }
@media (min-width: 1000px) {
  .tire-top { grid-template-columns: minmax(0, 620px) minmax(0, 1fr); }
}

/* ---------- what a wheel order is, and is not ---------- */
.incl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 30px; margin-top: 28px; }
/* These were `h3`s, drawn at the name size. They are `h2`s now — a product's
   sections belong directly under its name for anyone reading by heading — and
   the size is stated here rather than inherited from the level. */
.incl-head {
  font-size: var(--text-name); font-weight: 500;
}
.incl-head {
  font-family: var(--font-body); font-size: var(--text-label); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--text-2); margin: 0 0 9px;
}
.incl-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px;
  font-size: var(--text-small); color: var(--text-1); }
.incl-list li { display: grid; grid-template-columns: 15px minmax(0, 1fr); gap: 8px; align-items: start; }
.incl-list li::before { font-weight: 700; }
.incl-list.yes li::before { content: "✓"; color: var(--gold-300); }
.incl-list.no li::before { content: "—"; color: var(--text-2); }
.incl-foot { margin-top: 14px; }
@media (max-width: 720px) { .incl { grid-template-columns: 1fr; } }

/* ---------- sizes and prices, one diameter at a time ---------- */
.sizes { margin-top: 30px; }
.sizes-head { display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 10px 16px; margin-bottom: 10px; }
.sizes-head h2 { margin: 0; font-size: var(--text-name); font-weight: 500; }
.product-grid > div > h2 { font-size: var(--text-name); font-weight: 500; }
.dia-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.dia-tab {
  font-family: var(--font-body); font-size: var(--text-label); font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2);
  background: transparent; border: 1px solid var(--line); border-radius: 999px;
  padding: 8px 14px; min-height: 34px; cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
.dia-tab:hover { color: var(--text-0); border-color: var(--line-bright); }
.dia-tab.on { color: var(--ink-0); background: var(--volt); border-color: var(--volt); }
.sizes .table-scroll { border: 1px solid var(--line); border-radius: var(--radius);
  max-height: 360px; overflow-y: auto; }
.spec-table tr[hidden] { display: none; }

/* On a phone the chart stops being a table and becomes a list: the size and
   the price on the first line, the rest under them. A five-column table on a
   360px screen puts the PRICE off the right-hand edge, behind a sideways
   scroll — the one number the customer came for. */
@media (max-width: 600px) {
  .sizes .table-scroll { overflow-x: visible; }
  /* beats .table-scroll .spec-table { min-width: 460px }, which is set later */
  .sizes .table-scroll .spec-table { min-width: 0; }
  .sizes .spec-table thead { position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .sizes .spec-table tr {
    display: grid; gap: 3px 10px; padding: 11px 12px; border-bottom: 1px solid var(--line);
  }
  /* ...and this must outrank that display, or a row the diameter tabs hid is
     drawn anyway: `display` is set by whichever rule wins, hidden or not. */
  .sizes .spec-table tr[hidden] { display: none; }
  .sizes .spec-table td { border: 0; padding: 0; color: var(--text-2); overflow-wrap: anywhere; }
  .sizes .spec-table td:first-child {
    font-family: var(--font-display); font-size: var(--text-name); color: var(--text-0);
  }

  /* wheels: size and price on top, the fit facts under them, then the row's
     own add button across the full width — the same shape as the tire chart */
  .wheel-sizes .spec-table tr { grid-template-columns: auto auto minmax(0, 1fr) auto; }
  .wheel-sizes .spec-table td:nth-child(1) { grid-area: 1 / 1 / 2 / 4; }
  .wheel-sizes .spec-table td:nth-child(5) { grid-area: 1 / 4 / 2 / 5;
    text-align: right; font-weight: 700; color: var(--text-0); }
  .wheel-sizes .spec-table td:nth-child(2) { grid-area: 2 / 1 / 3 / 2; }
  .wheel-sizes .spec-table td:nth-child(3) { grid-area: 2 / 2 / 3 / 3; }
  .wheel-sizes .spec-table td:nth-child(4) { grid-area: 2 / 3 / 3 / 5; }
  .wheel-sizes .spec-table td:nth-child(6) { grid-area: 3 / 1 / 4 / 5; margin-top: 8px; }
  .wheel-sizes .spec-table td:nth-child(6) .btn { width: 100%; }

  /* tires: size and price on top, then the wheel it mounts and the stock line,
     then the row's own add button across the full width */
  .tire-sizes .spec-table tr { grid-template-columns: minmax(0, 1fr) auto; }
  .tire-sizes .spec-table td:nth-child(1) { grid-area: 1 / 1 / 2 / 2; }
  .tire-sizes .spec-table td:nth-child(3) { grid-area: 1 / 2 / 2 / 3;
    text-align: right; font-weight: 700; color: var(--text-0); }
  .tire-sizes .spec-table td:nth-child(2) { grid-area: 2 / 1 / 3 / 2; }
  .tire-sizes .spec-table td:nth-child(4) { grid-area: 2 / 2 / 3 / 3; text-align: right; }
  .tire-sizes .spec-table td:nth-child(5) { grid-area: 3 / 1 / 4 / 3; margin-top: 8px; }
  .tire-sizes .spec-table td:nth-child(5) .btn { width: 100%; }
}

/* ---------- forms / status ---------- */
.field { display: grid; gap: 6px; margin-bottom: 14px; }
.field > span { font-size: var(--text-small); text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-2); }
.status-box {
  padding: 14px 16px; border-radius: var(--radius);
  background: var(--ink-3); border: 1px solid var(--line-bright); color: var(--text-1);
}
.hint { color: var(--text-2); font-size: var(--text-small); }

/* ---------- footer ---------- */
/* ---------- trust bar + footer ---------- */
.trust-bar { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--ink-1), var(--ink-0)); margin-top: 90px; }
.trust-row { display: flex; flex-wrap: wrap; gap: 26px; justify-content: center;
  padding: 20px 26px; color: var(--text-2); font-size: var(--text-small); text-align: center; }
.trust-row b { color: var(--text-1); font-weight: 700; }
.site-footer { color: var(--text-2); font-size: var(--text-small); padding-top: 46px; }
.foot-grid { display: grid; grid-template-columns: 1.5fr 0.8fr 0.8fr 0.9fr 0.7fr 1.3fr; gap: 26px; padding-bottom: 34px; }
.foot-brand p { max-width: 34ch; margin: 12px 0 0; line-height: 1.5; }
.foot-col h2 { font-family: var(--font-display); text-transform: uppercase; font-size: var(--text-label);
  letter-spacing: 0.16em; color: var(--text-1); margin: 0 0 14px; }
.foot-col a { display: block; color: var(--text-2); text-decoration: none; padding: 5px 0; }
.foot-col a:hover { color: var(--volt); }
/* Italic, not faded: opacity took this link to 2.56:1. */
.muted-link { font-style: italic; }
.foot-base { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
  border-top: 1px solid var(--line); padding-block: 20px 60px; color: var(--text-2); }
/* Not faded: at 70% opacity "no payment is taken online" was 3.05:1. */
.foot-note { }
/* The sign-up form needs 220px. Left in one of two phone columns it claimed
   that column outright and crushed the other to 46px: Build and Legal became
   a one-word-per-line stack pushed into the side gutter, on every page. It
   takes the full row on a phone, like the brand block. */
@media (max-width: 760px) { .foot-grid { grid-template-columns: 1fr 1fr; } .foot-brand, .foot-news { grid-column: 1 / -1; } }

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .product-grid { grid-template-columns: 1fr; }
  /* One column: the placements above would pin three blocks into two rows of a
     single column and stack them on top of each other. Source order takes
     over, which is the order this page is written in. */
  .product-title, .product-media, .product-buy { grid-column: auto; grid-row: auto; }
  .product-grid { gap: 22px; }
  .steps { grid-template-columns: 1fr; }
  .hero { padding: 44px 0 30px; }
  .site-nav { gap: 14px; padding: 12px 16px; }
  .site-nav .links { gap: 14px; }
}

/* ---------- legacy flow reskin ----------
   The build/calibrate/result pages still use style.css classes; theme.css loads
   after it, so retinting the old accent token here pulls the whole funnel onto
   the Midnight Garage palette without touching those templates. */
:root {
  --accent: var(--volt);
  --accent-fg: var(--ink-0);
}
/* phones: nav drops to two rows so the long link never clips */
@media (max-width: 600px) {
  /* One label size for every link, so the row wraps instead of shrinking the
     type: five links in capitals do not fit across 360px at 12px. */
  .site-nav { flex-wrap: wrap; row-gap: 6px; padding-inline: 16px; }
  .site-nav .links { width: 100%; flex-wrap: wrap; justify-content: space-between; gap: 8px 12px; }
  .site-nav .links a { letter-spacing: 0.04em; white-space: nowrap; }
  /* A thumb is about 44px wide; these links were 15px tall, which is a miss
     waiting to happen on the site's PRIMARY navigation. The padding grows the
     tap area without touching the type size, and the negative row-gap margin
     keeps the header the same height it was. */
  .site-nav .links a { padding: 17px 2px; margin: -17px 0; }
  .site-nav { row-gap: 0; }
}

/* ---------- product photo gallery ---------- */
.photo-strip { display: flex; gap: 10px; margin-top: 12px; }
.photo-pick {
  width: 74px; height: 74px; padding: 6px; cursor: pointer;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: 10px;
}
.photo-pick img { width: 100%; height: 100%; object-fit: contain; display: block; }
.photo-pick:hover { border-color: var(--line-bright); }
.photo-pick.on { border-color: var(--volt); box-shadow: 0 0 14px var(--volt-glow); }

/* ---------- render payoff (result page) ---------- */
.render-progress {
  display: flex; align-items: center; gap: 16px; padding: 22px;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 22px;
}
.render-progress strong { display: block; font-size: var(--text-body); color: var(--text-0); }
.render-progress .hint { margin: 4px 0 0; }
.spinner {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  border: 3px solid var(--line-bright); border-top-color: var(--volt);
  animation: bmt-spin 0.8s linear infinite;
}
@keyframes bmt-spin { to { transform: rotate(360deg); } }

/* The live render checklist. Every entry is a real pipeline stage, ticked only
   once that stage has actually returned — no fake creep toward 90%. */
.render-steps {
  list-style: none; margin: 0 0 22px; padding: 20px 22px;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: var(--radius);
}
.render-steps li {
  display: flex; align-items: center; gap: 12px;
  padding: 7px 0; font-size: var(--text-body); color: var(--text-2);
  transition: color 0.3s ease, opacity 0.3s ease;
}
.render-steps .step-mark {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 2px solid var(--line-bright); position: relative;
}
.render-steps .is-done { color: var(--text-1); }
.render-steps .is-done .step-mark { border-color: var(--volt); background: var(--volt); }
.render-steps .is-done .step-mark::after {
  content: ""; position: absolute; left: 4px; top: 1px;
  width: 3px; height: 7px; border: solid var(--ink-0);
  border-width: 0 2px 2px 0; transform: rotate(42deg);
}
.render-steps .is-active { color: var(--text-0); font-weight: 600; }
.render-steps .is-active .step-mark {
  border-color: var(--volt);
  animation: bmt-pulse 1.1s ease-in-out infinite;
}
@keyframes bmt-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(201, 161, 91, 0.55); }
  50%      { box-shadow: 0 0 0 6px rgba(201, 161, 91, 0); }
}
.render-steps .is-waiting { opacity: 0.45; }
@media (prefers-reduced-motion: reduce) {
  .render-steps .is-active .step-mark { animation: none; background: var(--volt); }
}

.beforeafter.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.beforeafter figure { margin: 0; }
.beforeafter img { width: 100%; border-radius: var(--radius); border: 1px solid var(--line); display: block; }

/* PARTS IN THIS BUILD — the render's bill of materials, each row openable.
   Sits outside the picture: the photo sells the look, this answers "what am I
   actually looking at, and where do I get it". */
.build-parts { margin: 20px 0 6px; padding: 18px 20px; background: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--radius); }
.build-parts h3 { margin: 0 0 14px; font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.12em; font-size: var(--text-small); color: var(--gold-100); }
.parts-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.part { border: 1px solid var(--line); border-radius: calc(var(--radius) - 4px);
  background: var(--ink-1); overflow: hidden; }
/* FLEX, not grid: a row has two or three children depending on whether the
   part has a product photo, and fixed grid columns put the "See the wheel →"
   call-to-action right up against the title on the rows without one. */
.part-link, .part-static { display: flex; align-items: center; gap: 14px;
  padding: 12px 14px; }
.part-link { text-decoration: none; color: inherit;
  transition: background .18s ease, border-color .18s ease; }
.part-link:hover { background: var(--ink-3, #1b1d22); }
.part-thumb { width: 64px; height: 64px; display: grid; place-items: center;
  background: var(--ink-2); border-radius: 8px; overflow: hidden; }
/* Only the wheel has a product photo; an empty box beside the tires read as
   an image that had failed to load. */
.part-thumb:empty { display: none; }
.part-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.part-body { display: grid; gap: 2px; min-width: 0; flex: 1; }
.part-kicker { font-size: var(--text-label); text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-2); }
.part-title { color: var(--text-0); font-size: var(--text-body); }
.part-spec { color: var(--gold-100); font-size: var(--text-small); font-weight: 600; }
.part-price { color: var(--text-2); font-size: var(--text-small); }
.part-cta { color: var(--gold-100); font-size: var(--text-small); font-weight: 600;
  white-space: nowrap; margin-left: auto; }
@media (max-width: 560px) {
  /* On a phone the row is too narrow to hold the name and the arrow side by
     side — sharing it broke "Moto Metal Siege" across three lines. Give the
     arrow its own line (flex-basis 100% is what actually forces the wrap;
     flex-wrap alone doesn't, because the body will happily shrink instead). */
  .part-link { flex-wrap: wrap; }
  .part-thumb { width: 52px; height: 52px; }
  .part-cta { flex-basis: 100%; margin: 4px 0 0 66px; }
}

/* The payoff, treated like one. The AFTER gets a gold frame and both images
   invite a closer look; the reveal eases in instead of popping (htmx swaps the
   fragment, so the animation runs exactly once, when the render lands). */
.beforeafter img[data-expand] { cursor: zoom-in; transition: transform 0.25s ease, box-shadow 0.25s ease; }
.beforeafter img[data-expand]:hover { transform: scale(1.015); box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.beforeafter .ba-after img { border-color: var(--volt); box-shadow: 0 0 24px var(--volt-glow); }
.beforeafter figcaption { margin-top: 8px; font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.12em; font-size: var(--text-label); color: var(--text-2); }
.beforeafter .ba-after figcaption { color: var(--gold-100); }
.beforeafter .expand-hint { text-transform: none; letter-spacing: 0.02em; opacity: 0.65; }
.artifacts .beforeafter figure { animation: ba-reveal 0.6s cubic-bezier(.16,1,.3,1) both; }
.artifacts .beforeafter figure:last-child { animation-delay: 0.12s; }
@keyframes ba-reveal { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (max-width: 700px) { .beforeafter.grid { grid-template-columns: 1fr; } }

/* Full-screen viewer for [data-expand] images. */
.lightbox { position: fixed; inset: 0; z-index: 300; display: none; align-items: center;
  justify-content: center; padding: 3vh 3vw; background: rgba(5,6,8,0.94);
  backdrop-filter: blur(6px); cursor: zoom-out; }
.lightbox.open { display: flex; animation: lb-in 0.18s ease-out; }
.lightbox img { max-width: 96vw; max-height: 94vh; border-radius: 10px;
  box-shadow: 0 20px 80px rgba(0,0,0,0.8); }
.lightbox-close { position: absolute; top: 14px; right: 18px; font-size: var(--text-section); line-height: 1;
  background: none; border: none; color: var(--text-1); cursor: pointer; }
.lightbox-close:hover { color: var(--text-0); }
@keyframes lb-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .artifacts .beforeafter figure { animation: none; }
  .lightbox.open { animation: none; }
}
.beforeafter figcaption {
  margin-top: 8px; text-transform: uppercase; letter-spacing: 0.1em;
  font-size: var(--text-label); color: var(--text-2);
}
.artifacts .summary { margin: 18px 0 0; color: var(--text-1); font-size: var(--text-body); }
.result-cta { display: flex; gap: 12px; flex-wrap: wrap; margin: 22px 0 4px; }
.render-details { margin-top: 28px; color: var(--text-2); font-size: var(--text-small); }
.render-details summary { cursor: pointer; color: var(--text-2); }
.render-details .all-stages { display: grid; grid-template-columns: repeat(auto-fill,minmax(150px,1fr)); gap: 10px; margin: 12px 0; }
.render-details .all-stages img { width: 100%; border-radius: 8px; border: 1px solid var(--line); }
.render-details .warn-list, .render-details .timing-list { margin: 8px 0; padding-left: 18px; }
@media (max-width: 640px) { .beforeafter.grid { grid-template-columns: 1fr; } }

/* phones: keep long wheel names from clipping the product title */
@media (max-width: 600px) {
  .product-grid h1 { font-size: var(--text-section) !important; overflow-wrap: anywhere; }
  /* A perfect square is 340px of a 390px screen, and the price sits under it.
     The photograph stays the hero and keeps its proportions; it just stops
     taking the whole screen to do it. */
  .product-stage { aspect-ratio: 4 / 3; padding: 5%; }
}

/* ---------- visual build picker ---------- */
.picker .lede { margin-bottom: 8px; }
.picker-ok { background: rgba(212,175,55,0.10); border: 1px solid var(--volt);
  color: var(--text-0); border-radius: 10px; padding: 11px 14px; margin: 14px 0 0; font-size: var(--text-small); }
.picker-error { color: var(--volt) !important; font-weight: 600; }
/* The wheel a customer is looking at cannot go on the truck they told us
   about. Loud enough to stop a wrong order, quiet enough not to shout at
   somebody buying for a second truck. */
.fit-warning {
  margin: 14px 0 0; padding: 11px 14px; border-radius: 10px;
  border: 1px solid var(--volt); border-left-width: 3px; background: rgba(212, 175, 55, 0.08);
  color: var(--text-1); font-size: var(--text-small);
}
.fit-warning b { color: var(--text-0); }
/* Not a warning: a fact about how this wheel is made. */
.fit-note {
  margin: 14px 0 0; padding: 11px 14px; border-radius: 10px;
  border: 1px solid var(--line); border-left: 2px solid var(--line-bright);
  background: var(--ink-1); color: var(--text-1); font-size: var(--text-small);
}
.fit-note b { color: var(--text-0); }

/* The reference a customer reads down the phone, and the clock time behind
   the plain "3 days ago". */
.deal-ref {
  font-family: var(--font-display); font-size: var(--text-label); letter-spacing: 0.08em;
  color: var(--text-2); border: 1px solid var(--line); border-radius: 4px; padding: 2px 6px;
}
/* Quieter than "3 days ago", still readable: dimmed with opacity it measured
   3.57:1, under the AA floor, on the one screen that is read in a hurry. */
.deal-stamp { color: var(--text-2); }

/* One next step, and the boxes that belong to it. Drawn as one object so a
   field can never look like it belongs to the button above it. */
.deal-do { margin: 0; display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.deal-do-fields {
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--ink-1);
}
/* The label, and the fact under it. On ONE line, in the label's own uppercase
   and letter-spacing, the two ran together and read as a single phrase --
   "AGREED TOTAL PARTS LIST $889.00". The fact gets its own line, in sentence
   case, so it reads as a note rather than as more of the label. Kept on one
   line it also laid the desk out 495px wide on a 360px phone. Only the money
   is unbreakable. */
.deal-do .field > span { display: grid; gap: 2px; }
.deal-do .field span em {
  font-style: normal; font-weight: 400; color: var(--text-2);
  text-transform: none; letter-spacing: 0; font-size: var(--text-small);
}
.deal-do .field span em b { font-weight: 600; color: var(--text-1); white-space: nowrap; }

/* What the parts come to, where they are being changed. */
.parts-sum { color: var(--text-1); font-size: var(--text-small); }
.parts-sum b { color: var(--text-0); font-variant-numeric: tabular-nums; }

/* What the desk just did, drawn on the deal it did it to. */
.desk-said {
  margin: 0 0 12px; padding: 10px 14px; border-radius: 10px;
  border: 1px solid var(--volt); border-left-width: 3px;
  background: rgba(212, 175, 55, 0.08); color: var(--text-0);
  font-size: var(--text-small);
}
/* Whose account this is: under the heading, at reading size, and able to break
   a long address rather than push the page sideways. */
.account-who {
  margin: -6px 0 18px; color: var(--text-2); font-size: var(--text-small);
  overflow-wrap: anywhere; min-width: 0;
}
.fit-warning a { color: var(--gold-300); font-weight: 700; white-space: nowrap; }

.fit-toggle {
  display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
  color: var(--text-2); font-size: var(--text-small); cursor: pointer;
}
.fit-toggle input { width: 18px; height: 18px; accent-color: var(--volt); }
.picker-note { background: var(--ink-1); border: 1px solid var(--line); border-left: 2px solid var(--volt);
  color: var(--text-1); border-radius: 10px; padding: 11px 14px; margin: 14px 0 0; font-size: var(--text-small); }
.picker-hint { color: var(--text-2); font-size: var(--text-small); margin: 10px 0 0; }
.build-step { margin-top: 28px; }
.build-step > h2 { display: flex; align-items: center; gap: 10px; font-size: var(--text-lead); margin: 0 0 12px; }
.step-n { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--volt); color: var(--ink-0); font-weight: 800; font-size: var(--text-small); }
.field-row { display: flex; gap: 14px; flex-wrap: wrap; }
.field-row label { flex: 1; min-width: 160px; display: grid; gap: 6px; color: var(--text-1); font-size: var(--text-small); }
.picker select { width: 100%; padding: 12px 14px; border-radius: 10px;
  background: var(--ink-3); border: 1px solid var(--line-bright); color: var(--text-0); font: inherit; }
.wheel-toolbar { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.wheel-toolbar select { max-width: 260px; }
.inline-check { display: flex; align-items: center; gap: 8px; color: var(--text-1); font-size: var(--text-small); }
.inline-check input { width: auto; }
.wheel-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px;
  max-height: 460px; overflow-y: auto; padding: 4px; }
.wheel-opt { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 12px;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; text-align: center; }
.wheel-opt:hover { border-color: var(--line-bright); }
.wheel-opt.on { border-color: var(--volt); box-shadow: 0 0 0 1px var(--volt), 0 0 22px var(--volt-glow); }
.wheel-opt-img { display: flex; align-items: center; justify-content: center; aspect-ratio: 1; }
.wheel-opt-img img { width: 100%; height: 100%; object-fit: contain; }
.wheel-opt-name { font-size: var(--text-small); color: var(--text-1); line-height: 1.2; }
.wheel-opt-badge { position: absolute; top: 8px; right: 10px; color: var(--volt); font-size: var(--text-small); }
.chip-row { display: flex; gap: 10px; flex-wrap: wrap; }
.chip { padding: 12px 20px; border-radius: 999px; background: var(--ink-3);
  border: 1px solid var(--line-bright); color: var(--text-1); font: inherit; font-weight: 600; cursor: pointer; }
.chip:hover { border-color: var(--text-2); }
.chip.on { background: var(--volt); border-color: var(--volt); color: var(--ink-0); box-shadow: 0 0 18px var(--volt-glow); }
/* How high the truck sits, on the shocks and suspension shelves. */
.height-ask { margin: 0 0 18px; }
.height-ask-head { margin: 0 0 10px; color: var(--text-1); font-size: var(--text-small); max-width: 60ch; }
.height-ask-head b { color: var(--text-0); font-size: var(--text-body); display: block; }
.height-ask .chip { display: inline-flex; align-items: center; gap: 8px; padding: 10px 16px;
  text-decoration: none; font-size: var(--text-small); }
.height-ask .chip-count { color: var(--text-2); font-weight: 500; }
.height-ask .chip.on .chip-count { color: var(--ink-0); }
/* The two build flows: a deliberate fork, not a buried dropdown. Same select
   language as the chips (gold ring when chosen) but card-sized, with an honest
   time expectation on each so nobody is surprised by the wait. */
.flow-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px; max-width: 620px; margin-bottom: 14px; }
.flow-card { display: grid; gap: 5px; text-align: left; padding: 16px 18px;
  background: var(--ink-3); border: 1px solid var(--line-bright); border-radius: var(--radius);
  color: var(--text-1); font: inherit; cursor: pointer; transition: border-color 0.15s ease, box-shadow 0.15s ease; }
.flow-card:hover { border-color: var(--text-2); }
.flow-card strong { font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.06em; font-size: var(--text-body); color: var(--text-0); }
.flow-card span { font-size: var(--text-small); color: var(--text-2); }
.flow-card em { font-style: normal; font-size: var(--text-label); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-2); margin-top: 4px; }
.flow-card.on { border-color: var(--volt); box-shadow: 0 0 18px var(--volt-glow); }
.flow-card.on strong { color: var(--volt); }
.flow-card.on em { color: var(--gold-100); }
#lift-height { margin: 4px 0 12px; }

.size-row { margin-top: 14px; }
/* one plain-English line under each control — hand-holding without the essay */
.term-hint { display: block; margin-top: 5px; font-size: var(--text-label); line-height: 1.45;
  color: var(--text-2); font-weight: 400; max-width: 260px; }
.my-setup { margin: 14px 0 0; padding: 10px 14px; display: inline-flex; gap: 8px;
  flex-wrap: wrap; align-items: baseline; background: var(--ink-3);
  border: 1px solid var(--line-bright); border-radius: 999px; font-size: var(--text-small);
  color: var(--text-1); }
.my-setup-label { font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.1em; font-size: var(--text-label); color: var(--gold-100); }
.my-setup strong { color: var(--text-0); }
.my-setup-fit { color: var(--text-2); }
.tire-select { display: grid; gap: 6px; margin-top: 16px; max-width: 300px; color: var(--text-1); font-size: var(--text-small); }
.cta-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-top: 30px; }
@media (max-width: 600px) {
  .wheel-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
}


/* ---------- the two doors (build-for-MY-truck vs just-shopping) ---------- */

/* ---------- brand tiles (shop-by-brand, owner call 2026-08-18) ----------
   Official logo art on onyx cards. One click filters to the brand; clicking
   the active tile clears it. Counts stay honest under the other filters. */
.brand-tiles {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px;
  margin: 0 0 18px;
}
@media (max-width: 900px) { .brand-tiles { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px) { .brand-tiles { grid-template-columns: repeat(2, 1fr); } }
.brand-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 20px 14px 16px; min-height: 108px;
  background: linear-gradient(180deg, var(--panel-2, #14151a), var(--panel, #101116));
  border: 1px solid var(--line-bright); border-radius: 12px;
  text-decoration: none; position: relative; overflow: hidden;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.brand-tile:hover {
  border-color: var(--volt); transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
.brand-tile.on {
  border-color: var(--volt);
  background: linear-gradient(180deg, rgba(212, 175, 55, 0.12), rgba(212, 175, 55, 0.04));
}
.brand-tile.on::after {
  content: "✕"; position: absolute; top: 8px; right: 10px;
  color: var(--volt); font-size: var(--text-label); opacity: 0.8;
}
.brand-tile img.brand-logo, .brand-tiles.tires .brand-tile > img {
  max-height: 30px; max-width: 82%; object-fit: contain;
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.5));
}
.brand-tile-name {
  font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--text-1); font-size: var(--text-small);
}
.brand-tile-count {
  font-size: var(--text-label); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-2);
}
.brand-tile.on .brand-tile-count { color: var(--volt); }

/* Tire shelf: text-forward cards (no product photography yet — typography
   carries them) + an honest in-stock badge. */
/* A tire's frame, with no photograph to put in it: the distributor's feed
   ships none. A drawn tread keeps the shelf's rhythm — a card missing its
   picture reads as broken. */
.tread-mark { width: 62%; height: auto;
  --tire: #101317; --cut: #191d23; --rim: #2b323b; }

/* ---------- the truck you picked, on every page ----------
   Picked on the shelf, kept in a cookie, and forgotten by every other page
   until now (store rebuild, step 7). */
.truck-strip { border-bottom: 1px solid var(--line); background: var(--ink-1); }
.truck-strip-row {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
  padding-block: 9px; font-size: var(--text-small); color: var(--text-2);
}
.truck-strip-label {
  font-size: var(--text-label); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.12em;
}
.truck-strip-truck { color: var(--text-0); }
.truck-strip-ask { color: var(--text-1); }
.truck-strip-fits { color: var(--text-2); }
.truck-strip-row a { color: var(--gold-300); font-weight: 700; }
/* The x beside the truck: shop without it (2026-09-19). */
.truck-strip-forget { display: inline-flex; margin: 0; align-self: center; flex: 0 0 auto; }
.truck-strip-x {
  display: inline-grid; place-items: center; width: 28px; height: 28px; margin: -6px 0 -6px -4px;
  border: 0; border-radius: 50%; background: transparent; color: var(--text-2);
  font: inherit; font-size: 1.25rem; line-height: 1; cursor: pointer;
}
.truck-strip-x:hover, .truck-strip-x:focus-visible { color: var(--text-0); background: var(--ink-3); }

/* ---------- the build list, as a cart ----------
   Parts on the left, the summary beside them: what it adds up to, when we
   call, one gold button and the number. It was a list with a form under it and
   no total anywhere (store rebuild, step 5). */
.cart-grid { display: grid; gap: 26px; align-items: start; margin-top: 26px; }
@media (min-width: 900px) {
  .cart-grid { grid-template-columns: minmax(0, 1fr) 360px; gap: 34px; }
  .cart-summary { position: sticky; top: 92px; }
}
.cart-items { display: grid; gap: 0; }
.cart-line {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto auto auto;
  align-items: center; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--line);
}
.cart-shot { width: 64px; height: 64px; object-fit: contain; }
.cart-what { display: grid; gap: 3px; min-width: 0; }
.cart-name { color: var(--text-0); font-weight: 700; overflow-wrap: anywhere; }
.cart-qty select {
  background: var(--ink-2); color: var(--text-0); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 8px 32px 8px 12px; min-height: 40px;
  font-size: var(--text-small);
}
.cart-line-total { color: var(--text-0); font-weight: 700; white-space: nowrap; }
.cart-drop {
  background: transparent; border: 1px solid var(--line); color: var(--text-2);
  border-radius: var(--radius); min-width: 38px; min-height: 38px; cursor: pointer;
  font-size: var(--text-small);
}
.cart-drop:hover { color: var(--text-0); border-color: var(--line-bright); }
@media (max-width: 620px) {
  .cart-line { grid-template-columns: 56px minmax(0, 1fr) auto; row-gap: 10px; }
  .cart-shot { width: 56px; height: 56px; }
  .cart-what { grid-column: 2 / 4; }
  .cart-qty { grid-column: 2 / 3; }
  .cart-line-total { grid-column: 3 / 4; text-align: right; }
  .cart-drop { grid-column: 1 / 2; grid-row: 2; }
}

.cart-summary {
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--ink-1);
  padding: 22px; display: grid; gap: 14px;
}
/* `display` is set by whichever rule wins, hidden or not: without this the
   summary of an EMPTY build list stayed on the screen, total and all
   (review-caught 2026-09-16). Same trap as the size chart's rows. */
.cart-summary[hidden], .added[hidden] { display: none; }
.summary-head { font-size: var(--text-name); margin: 0; }
.summary-lines { display: grid; gap: 8px; margin: 0; }
.summary-lines > div { display: flex; justify-content: space-between; gap: 14px; align-items: baseline; }
.summary-lines dt { color: var(--text-2); font-size: var(--text-small); margin: 0; }
.summary-lines dd { color: var(--text-1); margin: 0; }
.summary-total { border-top: 1px solid var(--line); padding-top: 10px; }
.summary-total dt { color: var(--text-1); font-size: var(--text-body); }
.summary-total dd {
  color: var(--text-0); font-family: var(--font-display); font-size: var(--text-section);
  line-height: 1.1;
}
.cart-summary .field { margin-bottom: 10px; }
.summary-when, .summary-call { margin: 0; font-size: var(--text-small); color: var(--text-2); }
.summary-who { margin: 0 0 10px; font-size: var(--text-small); color: var(--text-2); }
.summary-who b { color: var(--text-1); overflow-wrap: anywhere; }
.summary-who a { color: var(--gold-300); font-weight: 700; }
.summary-call a { color: var(--gold-300); font-weight: 700; }

/* ---------- the receipt for a sent quote ----------
   A quote is the only thing this store takes, so the page it lands on is the
   closest thing we have to an order confirmation: what we have, what it comes
   to, who we ring. */
.quote-done {
  max-width: 560px; margin: 26px 0 0; padding: 26px;
  border: 1px solid var(--volt-dim); border-radius: var(--radius-lg); background: var(--ink-1);
  display: grid; gap: 14px;
}
/* `display: grid` outranks the attribute on its own (see .cart-summary). */
.quote-done[hidden], .cart-grid[hidden] { display: none; }
.quote-done-head {
  margin: 0; color: var(--gold-300); font-size: var(--text-label); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em;
}
.quote-done-line { margin: 0; font-size: var(--text-section); line-height: 1.15; }
.quote-done-said { margin: 0; color: var(--text-1); }
.quote-done-do { display: flex; gap: 10px; flex-wrap: wrap; }
.quote-done-do .btn { flex: 1 1 auto; }

/* ---------- "added to your build list" ----------
   The confirmation a store owes you when you click Add: the part, how many,
   what that comes to, and the two things you might do next. */
.added {
  position: fixed; right: 18px; bottom: 18px; z-index: 60; width: min(380px, calc(100vw - 36px));
  display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 12px 14px;
  padding: 16px; border: 1px solid var(--volt-dim); border-radius: var(--radius-lg);
  background: var(--ink-1); box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}
.added-shot { width: 56px; height: 56px; object-fit: contain; }
.added-what { display: grid; gap: 3px; min-width: 0; }
/* No photo (a full list, a new truck's notice): the words take the row, not
   the photo's 56px column (2026-09-19). */
.added-shot[hidden] + .added-what { grid-column: 1 / -1; }
.added-head {
  color: var(--gold-300); font-size: var(--text-label); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em;
}
.added-name { color: var(--text-0); font-weight: 700; overflow-wrap: anywhere; }
.added-price { color: var(--text-1); font-size: var(--text-small); }
.added-do { grid-column: 1 / -1; display: flex; gap: 10px; flex-wrap: wrap; }
.added-do .btn { flex: 1 1 auto; }
@media (max-width: 620px) {
  .added { right: 12px; left: 12px; bottom: 12px; width: auto; }
}

/* A search that found nothing here, and something on the other shelf. */
.other-shelf {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 16px; margin: 16px 0 0; padding: 12px 14px; border: 1px solid var(--line);
  border-left: 2px solid var(--volt); border-radius: var(--radius);
  background: var(--ink-1); color: var(--text-1); font-size: var(--text-small);
}
.other-shelf p { margin: 0; }
.other-shelf b { color: var(--text-0); }
/* a button, not a link in a sentence: that link was a 19px tap target */
.other-shelf .btn { min-height: 34px; }

/* ---------- the count and the sort menu, over every grid ---------- */
.results-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 18px; margin: 18px 0 14px;
}
.results-count { margin: 0; color: var(--text-2); font-size: var(--text-small); }
.results-count b { color: var(--text-0); font-family: var(--font-display); font-size: var(--text-name); margin-right: 5px; }
.sort-field {
  display: flex; align-items: center; gap: 10px; color: var(--text-2);
  font-size: var(--text-label); text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700;
}
.sort-field select {
  background: var(--ink-2); color: var(--text-0); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 9px 38px 9px 13px; font-size: var(--text-small);
  text-transform: none; letter-spacing: normal; font-weight: 400; min-height: 40px;
}
.sort-field select:focus { border-color: var(--volt); }
.badge.stock {
  color: #79b473; border: 1px solid rgba(121, 180, 115, 0.35);
  background: rgba(121, 180, 115, 0.08);
  border-radius: 999px; padding: 2px 10px; font-size: var(--text-label);
  letter-spacing: 0.08em; text-transform: uppercase; width: fit-content;
}
.btn-sm { padding: 6px 12px; font-size: var(--text-label); }

/* ---------- photo guide (what the engine needs, as a place to stand) ---- */
.photo-guide {
  margin: 14px 0 4px; border: 1px solid var(--line-bright);
  border-radius: 10px; background: var(--panel, #101116);
}
.photo-guide summary {
  cursor: pointer; padding: 12px 16px; color: var(--text-1);
  font-weight: 600; font-size: var(--text-body); list-style: none;
}
.photo-guide summary::-webkit-details-marker { display: none; }
.photo-guide summary::before { content: "＋ "; color: var(--volt); }
.photo-guide[open] summary::before { content: "－ "; }
.photo-guide .pg-cue { color: var(--text-2); font-weight: 400; }
.pg-body { padding: 0 16px 16px; display: grid; gap: 14px; }
.pg-diagram {
  width: 100%; max-width: 340px; margin: 0 auto; display: block;
  background: #0c0d10; border-radius: 8px; padding: 6px;
}
.pg-list { margin: 0; padding-left: 18px; display: grid; gap: 9px;
  color: var(--text-2); font-size: var(--text-small); line-height: 1.5; }
.pg-list strong { color: var(--text-1); }
.pg-foot { margin: 0; color: var(--text-2); font-size: var(--text-small); }

/* ---------- account: sign in / create ---------------------------------- */
.auth-tabs { display: flex; gap: 8px; margin: 0 0 16px; }
.auth-tab {
  flex: 1; padding: 11px 14px; cursor: pointer; font-family: inherit;
  background: var(--panel, #101116); border: 1px solid var(--line-bright);
  border-radius: 10px; color: var(--text-2); font-size: var(--text-body);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.auth-tab:hover { border-color: var(--volt); color: var(--text-1); }
.auth-tab.on {
  border-color: var(--volt); color: var(--volt);
  background: rgba(212, 175, 55, 0.09);
}
.auth-pane.hidden { display: none; }
.auth-alt { margin-top: 16px; }

/* ---------- "get this exact build" — the conversion moment -------------- */
.exact-build {
  margin: 26px 0 8px; padding: clamp(20px, 3vw, 30px);
  border: 1px solid var(--line-gold, rgba(214, 178, 94, 0.28)); border-radius: 14px;
  background: linear-gradient(160deg, rgba(212, 175, 55, 0.09), rgba(212, 175, 55, 0.02) 60%),
              linear-gradient(180deg, var(--panel-2, #14151a), var(--panel, #101116));
  display: grid; gap: 18px;
}
@media (min-width: 820px) {
  .exact-build { grid-template-columns: 1fr 320px; align-items: start; }
  .exact-build #exact-status { grid-column: 1 / -1; }
}
.exact-recipe {
  margin: 6px 0 0; color: var(--text-1); font-size: var(--text-body); line-height: 1.5;
}
.exact-recipe strong { color: var(--text-0, #fff); }
.exact-price {
  margin: 12px 0 0; font-family: var(--font-display); font-size: var(--text-section);
  color: var(--volt); letter-spacing: 0.01em;
}
.exact-price > span:first-child {
  display: block; font-family: var(--font-body, inherit); font-size: var(--text-label);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-2);
}
.exact-price-note {
  display: block; font-family: var(--font-body, inherit); font-size: var(--text-label);
  letter-spacing: 0; text-transform: none; color: var(--text-2); margin-top: 2px;
}
.exact-form { display: grid; gap: 10px; }
.exact-form .hint { margin: 2px 0 0; }

/* ---------- a returning customer's saved truck -------------------------- */
.saved-trucks { margin: 0 0 24px; }
.saved-trucks-label {
  display: block; margin-bottom: 10px; color: var(--text-2);
  font-size: var(--text-label); letter-spacing: 0.1em; text-transform: uppercase;
}
.saved-truck {
  display: grid; grid-template-columns: 116px 1fr; gap: 16px; align-items: center;
  padding: 12px; margin-bottom: 10px; text-decoration: none;
  border: 1px solid var(--line-gold, rgba(214, 178, 94, 0.28)); border-radius: 12px;
  background: linear-gradient(160deg, rgba(212, 175, 55, 0.08), rgba(212, 175, 55, 0.02) 60%);
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.saved-truck:hover { border-color: var(--volt); }
.saved-truck img {
  width: 116px; height: 78px; object-fit: cover; border-radius: 8px;
  background: var(--panel, #101116);
}
.saved-truck-body { display: grid; gap: 3px; }
.saved-truck-body strong { color: var(--text-0, #fff); }
.saved-truck-body span { color: var(--volt); font-size: var(--text-small); }

/* ---------- render mode (exact vs photo-real) --------------------------- */
/* The border is on a wrapper, not the fieldset: a legend cuts a notch in its
   fieldset's border, and Safari cuts it even with the legend floated clear
   (same fix as the build page's steps). */
.render-mode {
  border: 1px solid var(--line-bright); border-radius: 12px;
  padding: 16px 18px; margin: 18px 0 4px;
}
.render-mode fieldset { min-width: 0; margin: 0; padding: 0; border: 0; background: none; }
.render-mode legend {
  padding: 0; margin: 0 0 6px; color: var(--text-2); font-size: var(--text-small);
  letter-spacing: 0.1em; text-transform: uppercase;
}
.rm-opt {
  display: grid; grid-template-columns: auto 1fr; gap: 12px;
  align-items: start; padding: 10px 4px; cursor: pointer;
}
.rm-opt + .rm-opt { border-top: 1px solid var(--line); }
.rm-opt input { margin-top: 4px; accent-color: var(--volt); }
.rm-body { display: grid; gap: 3px; }
.rm-body strong { color: var(--text-0, #fff); font-size: var(--text-body); }
.rm-body span { color: var(--text-2); font-size: var(--text-small); line-height: 1.45; }
.rm-opt input:checked ~ .rm-body strong { color: var(--volt); }

/* ---------- wipe-compare (before/after, and build vs build) ------------- */
.cmp { margin: 0 0 22px; }
.cmp-stage {
  position: relative; overflow: hidden; border-radius: var(--radius-lg, 14px);
  border: 1px solid var(--line-bright); cursor: ew-resize; touch-action: pan-y;
  background: var(--panel, #101116);
}
.cmp-stage img { width: 100%; display: block; user-select: none; -webkit-user-drag: none; }
.cmp-top { position: absolute; inset: 0; clip-path: inset(0 0 0 50%); }
.cmp-top img { height: 100%; object-fit: cover; }
.cmp-handle {
  position: absolute; top: 0; bottom: 0; left: 50%; width: 2px;
  background: rgba(255, 255, 255, 0.85); transform: translateX(-1px);
  box-shadow: 0 0 14px rgba(0, 0, 0, 0.6);
}
.cmp-handle::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 38px; height: 38px; margin: -19px 0 0 -19px; border-radius: 50%;
  background: rgba(12, 13, 16, 0.82); border: 1.5px solid var(--volt);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
}
.cmp-handle:focus-visible { outline: none; }
.cmp-handle:focus-visible::after { outline: 2px solid var(--volt); outline-offset: 3px; }
/* Tags live at the BOTTOM corners: the render's own spec plate occupies a
   TOP corner (whichever is quieter), and the watermark takes the bottom
   centre — so the corners down here are the only clear real estate. */
.cmp-tag {
  position: absolute; bottom: 12px; padding: 5px 11px; border-radius: 999px;
  background: rgba(12, 13, 16, 0.82); color: var(--text-1);
  font-size: var(--text-label); letter-spacing: 0.08em; text-transform: uppercase;
  pointer-events: none; max-width: 42%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.cmp-tag-l { left: 12px; }
.cmp-tag-r { right: 12px; color: var(--volt); }
.cmp-picker { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 14px; }
.cmp-side { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.cmp-side-label {
  font-size: var(--text-label); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-2); margin-right: 2px;
}
.cmp-chip {
  background: var(--panel-2, #14151a); border: 1px solid var(--line-bright);
  color: var(--text-2); border-radius: 999px; padding: 6px 13px;
  font-size: var(--text-small); cursor: pointer; font-family: inherit;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.cmp-chip:hover { border-color: var(--volt); color: var(--text-1); }
.cmp-chip.on { border-color: var(--volt); color: var(--volt); background: rgba(212, 175, 55, 0.1); }
.cmp-hint { margin: 10px 0 0; color: var(--text-2); font-size: var(--text-small); }

/* "What changed" — the render's own plain-language claim, above the photos.
   Deliberately borderless: DESIGN-VOICE.md calls the accent left-border strip
   the single most reliable AI tell. Type does the work. */
.what-changed {
  margin: -4px 0 20px;
  color: var(--text-2); font-size: var(--text-body); letter-spacing: 0.01em;
}
.what-changed strong { color: var(--volt); font-weight: 700; }

/* Package hand-off: wheel page -> tires pre-filtered to its diameters. */
.tire-handoff {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin: -12px 0 26px;
}
.tire-handoff-label { color: var(--text-2); font-size: var(--text-small); margin-right: 4px; }
.spec-chip.linky { color: var(--volt); text-decoration: none; border-color: var(--line-gold, rgba(214,178,94,0.28)); }
.spec-chip.linky:hover { color: var(--volt-bright, #f3e4c3); border-color: var(--volt); }

/* Brand chapter dividers — the all-brands view reads as organized sections,
   not one endless wall of cards. */
.brand-divider {
  display: flex; align-items: baseline; gap: 14px;
  margin: 34px 0 16px; padding-bottom: 10px;
  border-bottom: 1px solid var(--line-bright);
}
.brand-divider:first-of-type { margin-top: 8px; }
.brand-divider-name {
  font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.08em; font-size: var(--text-lead); color: var(--text-0, #fff);
}
.brand-divider-count {
  font-size: var(--text-label); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-2);
}
.brand-divider-link {
  margin-left: auto; font-size: var(--text-small); letter-spacing: 0.06em;
  color: var(--volt); text-decoration: none; text-transform: uppercase;
}
.brand-divider-link:hover { color: var(--volt-bright, #f3e4c3); }

/* ---------- what do you drive ----------
   Three questions, each one a full-width row on a phone: a truck is not a
   thing you pick out of the corner of your eye, and the answer decides every
   price the customer sees afterwards. */
.truck-pick { max-width: 560px; }
.truck-form { display: grid; gap: 16px; margin-top: 8px; }
.truck-form .field { margin: 0; }
.truck-form select { width: 100%; padding: 14px 14px; border-radius: var(--radius);
  background: var(--ink-3); border: 1px solid var(--line-bright); color: var(--text-0);
  font: inherit; }
.truck-form select:disabled { color: var(--text-2); border-color: var(--line); }

/* The answer, read back. The truck on its own line, because it is the thing
   being confirmed -- run together with the sentence after it, the name and the
   explanation read as one paragraph and neither lands. */
.truck-confirm { margin-top: 26px; }
.truck-verdict { margin: 0 0 14px; padding: 14px 16px; border-radius: var(--radius);
  border: 1px solid var(--volt); background: rgba(212, 175, 55, 0.07); }
.truck-verdict b { display: block; font-family: var(--font-display); font-size: var(--text-name);
  color: var(--text-0); letter-spacing: 0.01em; margin-bottom: 4px; }
.truck-verdict span { color: var(--text-1); font-size: var(--text-small); }

.truck-now { color: var(--text-1); margin: 0 0 22px; }
.truck-now b { color: var(--text-0); }
.truck-forget { display: inline; margin: 0; }
.truck-forget .linky { background: none; border: 0; padding: 0; font: inherit;
  color: var(--text-2); text-decoration: underline; cursor: pointer; }
.truck-forget .linky:hover { color: var(--volt); }
.truck-missing { border-top: 1px solid var(--line); padding-top: 18px; }

/* ---------- breadcrumbs ---------- */
.crumbs { display: flex; gap: 8px; align-items: center; font-size: var(--text-small);
  color: var(--text-2); padding-block: 22px 0; text-transform: uppercase; letter-spacing: 0.08em; }
.crumbs a { color: var(--text-2); text-decoration: none; }
.crumbs a:hover { color: var(--volt); }
.crumbs .sep { opacity: 0.4; }

/* ---------- finish swatches ---------- */
.swatches { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0 4px; }
.swatch { display: inline-flex; align-items: center; gap: 8px; padding: 7px 12px 7px 8px;
  border: 1px solid var(--line-bright); border-radius: 999px; font-size: var(--text-small); color: var(--text-1); }
.swatch i { width: 16px; height: 16px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.15);
  box-shadow: inset 0 1px 2px rgba(255,255,255,0.25); flex: none; }

/* ---------- product spec chips row ---------- */
.spec-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 4px; }
.spec-chip { border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px;
  font-size: var(--text-small); color: var(--text-1); background: var(--ink-1); }
.spec-chip b { color: var(--text-0); font-weight: 700; }

/* ---------- card render badge as gold corner ribbon ---------- */
.card { position: relative; }
.card .render-ribbon { position: absolute; top: 12px; left: 12px; z-index: 2;
  background: var(--gold-metal-x); color: #141005; font-size: var(--text-label); font-weight: 800;
  letter-spacing: 0.08em; text-transform: uppercase; padding: 4px 9px; border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.4); }

/* ---------- brand trust band (full-bleed rhythm break) ---------- */
.brand-band { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background:
    radial-gradient(700px 200px at 50% 0%, rgba(212,175,55,0.06), transparent 70%),
    linear-gradient(180deg, var(--ink-1), var(--ink-0));
  padding: 30px 0; margin: 26px 0; }
.brand-band .wrap { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; justify-content: center; }
.brand-band-label { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.12em;
  font-size: var(--text-label); color: var(--text-2); }

/* ---------- error / empty pages ---------- */
.error-page { max-width: 640px; margin: 0 auto; text-align: center; padding: 70px 20px 90px; }
.error-code { font-family: var(--font-display); font-size: var(--text-title); line-height: 1;
  margin-bottom: 8px; }
.error-page h1 { margin-bottom: 12px; }
.error-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 26px; }
.empty-state { text-align: center; padding: 40px 20px; color: var(--text-2); }
.empty-state .empty-mark { font-size: var(--text-section); margin-bottom: 10px; opacity: 0.5; }
.empty-state a { color: var(--volt); text-decoration: none; }

/* ---------- cinematic full-screen hero ---------- */
/* Break the hero OUT of the 880px main column and span the full viewport width
   (the side margins pull to each viewport edge; width stays auto so no
   horizontal scrollbar). Height: the video's own 16:9 (56.25vw) so the whole
   frame shows on normal screens, but never taller than one screen — and the
   WIDTH never shrinks to compensate. An earlier aspect-ratio + max-height combo
   did exactly that on wide-short windows: the capped height dragged the width
   down with it and left a black gap beside the video (owner-caught at
   1904x805). On short windows object-fit crops a little top/bottom instead. */
.hero-cine { position: relative;
  /* explicit 100vw (not auto): vw includes the scrollbar, so the box overhangs
     ~7px per side and the video reaches BOTH edges — otherwise the scrollbar's
     width surfaces as a thin black sliver on the right. The body clips the
     overhang so no horizontal scroll appears. */
  width: 100vw; margin-left: calc(50% - 50vw);
  height: min(56.25vw, 100svh); min-height: 460px;
  display: flex; align-items: flex-end;
  overflow: hidden; margin-bottom: 8px; }
.hero-cine-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero-cine-img, .hero-cine-media video { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 50%; display: block; }
/* slow cinematic drift so the STILL reads like footage; a real video brings its own motion */
.hero-cine-overlay { position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(90deg, rgba(8,9,11,0.86) 0%, rgba(8,9,11,0.55) 34%, rgba(8,9,11,0.12) 62%, transparent 100%),
    linear-gradient(0deg, rgba(8,9,11,0.92) 0%, rgba(8,9,11,0.15) 34%, transparent 60%); }
.hero-cine-content { position: relative; z-index: 2; padding: 0 26px clamp(64px, 7vw, 112px); width: 100%; max-width: 1280px;
  margin: 0 auto; }
.hero-cine-content h1 { font-size: var(--text-title); margin: 8px 0 14px;
  text-shadow: 0 2px 30px rgba(0,0,0,0.5); }
.hero-cine-content .lede { max-width: 46ch; color: var(--text-0); opacity: 0.92; }
.hero-cine-cta { display: flex; gap: 14px; flex-wrap: wrap; margin: 26px 0 4px; }
.diff-section { max-width: 900px; margin: 0 auto; }
@media (max-width: 700px) {
  /* Phones get a STACKED hero (owner-caught: the overlay headline was cut off
     and the 16:9 video lost both ends to the portrait crop). The video shows
     its whole frame at its own aspect; the headline sits below it on solid
     background where nothing can clip it. */
  .hero-cine { display: block; height: auto; min-height: 0; }
  .hero-cine-media { position: relative; inset: auto; aspect-ratio: 16 / 9; }
  .hero-cine-overlay { display: none; }
  .hero-cine-content { padding: 20px 20px 30px; }
  .hero-cine-content h1 { font-size: var(--text-title); text-shadow: none; }
}

/* ---------- featured showcase band ---------- */
@media (max-width: 700px) {
}

/* ---------- nav search (every real parts store has one) ---------- */
.nav-search { flex: 1; max-width: 420px; display: flex; margin: 0 6px; }
.nav-search input { flex: 1; min-width: 0; padding: 9px 14px; font: inherit; font-size: var(--text-small);
  background: var(--ink-2); border: 1px solid var(--line-bright); border-right: 0;
  border-radius: 8px 0 0 8px; color: var(--text-0); }
.nav-search input::placeholder { color: var(--text-2); }
.nav-search input:focus { border-color: var(--volt-dim); }
.nav-search button { padding: 0 14px; font-size: var(--text-body); cursor: pointer;
  background: var(--ink-3); border: 1px solid var(--line-bright); border-radius: 0 8px 8px 0;
  color: var(--text-1); }
.nav-search button:hover { color: var(--volt); border-color: var(--volt-dim); }
@media (max-width: 900px) {
  .nav-search { order: 3; flex-basis: 100%; max-width: none; margin: 6px 0 0; }
}

/* ---------- footer newsletter ---------- */
.foot-news { min-width: 220px; }
.news-form { display: flex; gap: 8px; }
.news-form input { flex: 1; min-width: 0; padding: 10px 12px; font: inherit; font-size: var(--text-small);
  background: var(--ink-2); border: 1px solid var(--line-bright); border-radius: 8px; color: var(--text-0); }
.news-form input:focus { border-color: var(--volt-dim); }

/* ---------- announcement strip (industry-universal above the nav) ---------- */
.promo-strip { background: var(--gold-metal-x); color: #141005; text-align: center;
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-small);
  letter-spacing: 0.1em; padding: 7px 12px; }

/* ---------- SEO copy block above the footer (retailer convention) ---------- */
.seo-block { border-top: 1px solid var(--line); padding: 36px 0 6px; color: var(--text-2);
  font-size: var(--text-small); line-height: 1.65; }
.seo-block .wrap { max-width: 900px; }
.seo-block h2 { font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--text-1); font-size: var(--text-body); margin: 0 0 10px; }

/* ---------- category tiles (research pattern #6) ---------- */
.cat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
.cat-tile { position: relative; min-height: 240px; display: flex; align-items: flex-end;
  overflow: hidden; border-radius: var(--radius-lg); border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1)); text-decoration: none;
  transition: border-color 0.2s, transform 0.15s; }
a.cat-tile:hover { border-color: var(--volt-dim); }
.cat-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0.55; transition: opacity 0.2s; }
a.cat-tile:hover img { opacity: 0.75; }
.cat-tile-body { position: relative; z-index: 1; padding: 18px;
  background: linear-gradient(0deg, rgba(8,9,11,0.9), transparent); width: 100%; }
.cat-tile-body h3 { margin: 0 0 2px; }
.cat-tile-body span { color: var(--text-2); font-size: var(--text-small); }
/* Dim the photo, not the words: fading the whole tile took its line to 3.22:1. */
.cat-tile.soon img { opacity: 0.3; }
.cat-tile.soon .cat-tile-body h3::after { content: " · soon"; color: var(--volt); font-size: 0.75em; }

/* ---------- under the pointer ----------
   Colour changes, nothing moves: cards lifting and photos zooming came off
   with the rest of the template effects (style reference). */
.site-nav .links a, .foot-col a { transition: color 0.2s ease, border-color 0.2s ease; }

/* ---------- degraded-render banner (AI stages failed) ---------- */
.degraded-banner { border: 1px solid #7a4a1a; background: rgba(160, 90, 20, 0.14);
  border-radius: var(--radius); padding: 16px 18px; margin-bottom: 22px;
  color: var(--text-1); font-size: var(--text-body); line-height: 1.55; }
.degraded-banner strong { color: #f0b357; display: block; margin-bottom: 4px; }
.degraded-banner details { margin-top: 10px; }
.degraded-banner summary { cursor: pointer; color: var(--text-2); }
.degraded-banner ul { margin: 8px 0 0; padding-left: 18px; font-size: var(--text-small); }
.degraded-banner code { color: var(--text-0); }

/* Account notices. One sentence about what is true, and where there is
   something to do about it, one button beside it. Deliberately quiet: this is
   an account page, not an alarm. */
.note {
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-bright);
  border-radius: var(--radius);
  padding: 14px 18px;
  margin: 18px 0 0;
  color: var(--text-1);
}
.note-good { border-left-color: var(--volt); }
.note-ask {
  border-left-color: var(--volt);
  display: flex; gap: 20px; align-items: center; justify-content: space-between;
  flex-wrap: wrap;
}
.note-ask strong { color: var(--text-0); }
.note-ask .btn { flex-shrink: 0; }

/* A submit button that reads as a text link. Used for "forgot your password",
   which has to live inside the sign-in form to reuse the address already typed
   there, but must not look like a second call to action next to it. */
.linkish {
  display: block; width: 100%; margin-top: 4px;
  background: none; border: 0; padding: 12px 0;
  color: var(--text-2); font: inherit; font-size: var(--text-small);
  text-align: center; cursor: pointer;
}
.linkish:hover { color: var(--volt); text-decoration: underline; }

/* Phone tap areas. Measured on a 390px iPhone viewport: breadcrumb links were
   20px tall and footer links 32px, against the ~44px a thumb actually needs.
   Padding only — no type sizes move, and negative margins hold the layout. */
@media (max-width: 600px) {
  .crumbs a { padding: 11px 0; margin: -11px 0; display: inline-block; }
  .foot-col a { padding: 6px 0; display: block; }
  /* The trail back to the shelf, not a second headline. Three long wheel words
     in uppercase with wide letter-spacing wrapped onto two lines and read
     louder than the product's own name (contact sheet 2026-09-17). The tap
     area above is padding, so it stays 44px however small the type gets. */
  .crumbs { font-size: var(--text-label); letter-spacing: 0.06em; gap: 6px; }
}

/* ---------- the desktop width bug ----------
   style.css line 47 sets `main { max-width: 880px; padding: 32px }` — a rule
   from the original build/calibrate flow, back when every page WAS that one
   column. It now wraps the whole storefront, so `.wrap`'s 1280px could never
   take effect: on a 1920px monitor the shop grid was boxed into 816px and drew
   TWO cards per row. That is the "it feels set up for mobile on a PC" — the
   site was never using the screen.

   `main` stops constraining; `.wrap` (1280px) does the job it was written for.
   The five pages that have no `.wrap` of their own still want a reading column
   rather than the whole monitor, so they get one explicitly. */
main { max-width: none; padding: 0; }
main > .result,
main > .start,
main > .demo,
main > .inspiration,
main > .admin { max-width: 880px; margin: 0 auto; padding: 32px; }

/* The variant picker on product pages. Selects, not chips: a select carries
   its own "one of these" affordance, works with a thumb, and lets an
   impossible option stay VISIBLE but disabled with the reason — hiding it
   would read as "we don't make that". */
.pk { margin: 18px 0 4px; display: flex; flex-direction: column; gap: 12px; }
.pk-row { display: flex; gap: 14px; flex-wrap: wrap; }
.pk-field { flex: 1 1 220px; display: flex; flex-direction: column; gap: 6px;
  color: var(--text-2); font-size: var(--text-small); text-transform: uppercase;
  letter-spacing: 0.12em; }
.pk-field select {
  background: var(--ink-2); color: var(--text-0); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px 12px; font-size: var(--text-body);
  text-transform: none; letter-spacing: normal;
}
.pk-field select:focus { border-color: var(--volt); }
.pk-field .term-hint { text-transform: none; letter-spacing: normal;
  font-size: var(--text-small); color: var(--text-2); }

/* ---------- policy pages ----------
   A policy is read by someone about to spend money and by a payment
   processor's reviewer. Both want to find one clause fast, so: one narrow
   column, headings that stand out from body copy, and generous line height.
   Measure is capped at ~68 characters — legal text is the last place to make
   someone track across a 1200px line. */
.legal { max-width: 760px; }
.legal h2 { font-family: var(--font-display); text-transform: uppercase;
  font-size: var(--text-body); letter-spacing: 0.09em; color: var(--text-0);
  margin: 38px 0 12px; padding-top: 18px; border-top: 1px solid var(--line); }
.legal h3 { font-size: var(--text-body); color: var(--text-0); margin: 24px 0 6px; }
.legal p, .legal li { color: var(--text-1); line-height: 1.68; max-width: 68ch; }
.legal p { margin: 0 0 14px; }
.legal b { color: var(--text-0); }
.legal ul, .legal ol { margin: 0 0 16px; padding-left: 22px; }
.legal li { margin-bottom: 9px; }
.legal a { color: var(--volt); }
.legal .lede { font-size: var(--text-body); color: var(--text-1); margin-bottom: 6px; }
.legal-updated { color: var(--text-2); font-size: var(--text-small); margin: 0 0 4px;
  text-transform: uppercase; letter-spacing: 0.1em; }

/* The one clause that costs a customer real money if they miss it. */
.legal-callout { border: 1px solid var(--gold-700); border-left: 3px solid var(--volt);
  background: rgba(201, 161, 91, 0.06); border-radius: var(--radius);
  padding: 20px 22px; margin: 4px 0 20px; }
.legal-callout p:last-child { margin-bottom: 0; }

.legal-foot { margin-top: 46px; padding-top: 22px; border-top: 1px solid var(--line); }
.legal-foot h2 { border: 0; padding-top: 0; margin-top: 0; }
.legal-nav { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 14px; }
.legal-nav a { color: var(--text-2); text-decoration: none; font-size: var(--text-small); }
.legal-nav a:hover { color: var(--volt); }

.contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 16px; margin: 22px 0 10px; }
.contact-card { padding: 20px 22px; }
.contact-card h3 { border: 0; padding-top: 0; margin: 0 0 8px; font-size: var(--text-small);
  letter-spacing: 0.14em; color: var(--text-2); }
.contact-card p { margin: 0 0 6px; }
.contact-card .gold { font-size: var(--text-body); font-weight: 700; }

/* The reference on the 500 page: the customer quotes it, we grep for it. */
.error-ref { display: inline-block; padding: 14px 20px; margin: 6px 0 26px; }
.error-id { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--text-lead); letter-spacing: 0.08em; color: var(--volt); user-select: all; }

/* How old the distributor price is. Quiet while the feed is fresh, plainer
   once it is old enough that the number has probably moved — the customer
   should hear that from the page, not from Clint on the call. */
.price-age { color: var(--text-2); font-size: var(--text-small); margin: 6px 0 0; max-width: 56ch; }
.price-age.is-stale { color: var(--gold-300); }

/* ---------- keyboard use ----------
   Every interactive thing shows where the keyboard is. `:focus-visible` (not
   `:focus`) means a mouse click does not leave a ring behind, so this costs
   pointer users nothing and gives keyboard users the whole site back.

   Three rules used to do `outline: none` and change a border colour instead.
   A colour change is not a focus indicator: it is invisible to anyone who
   cannot pick that shade out, and it disappears entirely against a focused
   field that already has that border. Those are restored above. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--volt);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Straight past the promo strip, the nav and the search box, to the page.
   Off-screen until focused, which is the first thing a keyboard user hits. */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--volt); color: var(--ink-0);
  padding: 12px 20px; font-weight: 700; text-decoration: none;
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }

/* Wide content scrolls inside its own box rather than being clipped by the
   phone's edge. The size table is 6 columns of numbers on a 375px screen —
   without this, the offset and price columns are simply gone on a phone, on
   the page whose entire job is saying what fits and what it costs.
   `tabindex=0` so a keyboard can reach the scroller too. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll .spec-table { min-width: 460px; }

/* A checkbox rendered at its 13px default is a coin-flip to hit with a thumb.
   24px is the WCAG minimum; 20px plus the label's padding clears it, and the
   whole label is the target anyway. */
.toggle input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--volt); }
.toggle { display: inline-flex; align-items: center; gap: 10px; padding: 8px 4px; cursor: pointer; }

/* ---------- operator desk: parts rows ----------
   Clint works the desk from his phone. These rows once used fixed minimum
   column widths adding up to about 500px, which a 375px phone could only show
   by laying the whole desk out 524px wide and rendering it zoomed out.
   minmax(0, …) lets every column shrink, and below 640px the description takes
   a full row with part number and price side by side beneath it. */
.parts-row { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1.3fr) minmax(0, 1fr) auto; gap: 8px; align-items: end; margin-bottom: 8px; }
.parts-row input { min-width: 0; width: 100%; }
@media (max-width: 640px) {
  .parts-row { grid-template-columns: 1fr 1fr; }
  .parts-row > :first-child { grid-column: 1 / -1; }
}

/* ---------- operator desk: deals that have stopped moving ----------
   A quiet red rule on the left and a faint wash, not a banner: it has to be
   the first thing Clint's eye lands on at 7am without making the rest of the
   desk feel like an alarm. Same treatment on the summary and on the card, so
   the two read as one signal. */
.stall-summary { border: 1px solid var(--line); border-left: 3px solid var(--danger);
  background: rgba(255, 93, 93, 0.06); border-radius: var(--radius);
  padding: 14px 18px; margin: 0 0 20px; color: var(--text-1); }
.stall-summary b { color: var(--text-0); }
.stall-summary a { color: var(--text-0); }
.stall-summary li { margin: 3px 0; }
.stall { margin: 10px 0 0; padding: 8px 12px; border-left: 3px solid var(--danger);
  background: rgba(255, 93, 93, 0.06); border-radius: 4px;
  color: var(--text-0); font-size: var(--text-body); }

/* Placeholders were never styled, so every box showed the browser's #757575:
   3.46:1 on an input, under the WCAG AA 4.5:1 minimum. Firefox also fades them
   to 54% unless told otherwise. */
::placeholder { color: var(--text-2); opacity: 1; }

/* ---------- dropdowns ----------
   Safari draws a <select> with its own light face and ignores the background
   colour set above, but keeps the light text colour: every dropdown on an
   iPhone or a Mac was a white box with white words in it (found 2026-09-11;
   Chrome draws them as styled). `appearance: none` makes every browser draw
   the styles, so the arrow is drawn here as well, clear of the text.
   `color-scheme: dark` asks for dark option lists, scrollbars and pickers
   wherever the browser still draws its own. The layout sweep measures each
   dropdown from its pixels, because its styles said it was fine all along. */
:root { color-scheme: dark; }
/* A field left to the browser is set in the browser's own face: a serif on
   Safari, the system face on Chrome. Every field takes the page's face instead,
   at no specificity, so a rule that sets one (the buttons) still wins. */
:where(input, select, textarea, button) { font-family: inherit; }
select:not([multiple]) {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23aeb4bd' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 8px;
  padding-right: 38px;
  cursor: pointer;
}

/* ---------- build start: the steps, and the truck photo drop zone ----------
   This was the one page still wearing the browser's form defaults: boxes with
   a notched legend, "Choose File / No file chosen", an Arial Black button. It
   read as a different site (shopper audit 2026-09-10), and the file picker
   "looks very boring" (owner, 2026-09-11). Its styles lived in the template,
   after this sheet, where they quietly outranked it; they live here now. */
.start form { display: grid; gap: 18px; max-width: 640px; }
/* The panel is a wrapper, not the fieldset: a legend cuts a notch in its
   fieldset's border, and Safari still cut it with the legend floated clear. */
.start .step {
  padding: 20px clamp(16px, 4vw, 26px) 22px;
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.start fieldset { display: grid; gap: 10px; min-width: 0; margin: 0; padding: 0; border: 0; background: none; }
.start legend {
  width: 100%; margin: 0 0 4px; padding: 0;
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-name);
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-0);
}
.step-no {
  display: inline-grid; place-items: center; flex: none;
  width: 28px; height: 28px; border-radius: 50%;
  border: 1px solid var(--volt); color: var(--volt);
  font-size: var(--text-small); letter-spacing: 0;
}
.start label { display: grid; gap: 6px; }
.start select { padding-block: 9px; padding-left: 10px; font: inherit; max-width: 100%; }
.start .hint { margin: 0; }
.start-next { justify-self: start; }
@media (max-width: 600px) { .start-next { justify-self: stretch; } }

/* Empty, the zone is one big target: the real file input covers it, invisible,
   so a tap opens the phone's camera-and-photos sheet. Chosen, the photo fills
   it. The states are data-state, not [hidden], which a display rule overrides. */
.drop {
  position: relative; overflow: hidden;
  border: 1.5px dashed var(--line-bright); border-radius: var(--radius);
  background: var(--ink-1);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}
.drop[data-state="empty"]:hover, .drop.is-over { border-color: var(--volt); }
.drop.is-over { background-color: var(--ink-2); box-shadow: 0 0 0 4px var(--volt-glow); }
.drop:has(.drop-input:focus-visible) { outline: 2px solid var(--volt); outline-offset: 3px; }
.drop.is-error { border-color: var(--danger); }
.drop:not([data-state="empty"]) { border-style: solid; border-color: var(--line); }
.drop-input {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; margin: 0; padding: 0; border: 0;
  opacity: 0; cursor: pointer;
}
.drop:not([data-state="empty"]) .drop-input { inset: auto; width: 1px; height: 1px; pointer-events: none; }
.drop:not([data-state="empty"]) .drop-empty,
.drop[data-state="empty"] .drop-full { display: none; }
.drop-empty { display: grid; justify-items: center; gap: 6px; padding: 30px 18px 26px; text-align: center; }
.drop-icon { width: 44px; height: 44px; margin-bottom: 4px; color: var(--volt); }
.drop-title {
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-lead);
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-0);
}
.drop-sub { color: var(--text-1); font-size: var(--text-small); }
.drop-btn { margin-top: 10px; }
.on-touch { display: none; }
@media (hover: none) and (pointer: coarse) {
  .on-touch { display: inline; }
  .on-pointer { display: none; }
}
.drop-shot { width: 100%; max-height: 360px; object-fit: contain; background: #000; vertical-align: middle; }
.drop-noview { margin: 0; padding: 36px 18px; text-align: center; color: var(--text-1); }
.drop-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px 14px; flex-wrap: wrap;
  padding: 12px 14px; border-top: 1px solid var(--line); background: var(--ink-2);
}
.drop-file { min-width: 0; color: var(--text-2); font-size: var(--text-small); overflow-wrap: anywhere; }
.drop-file strong { margin-right: 8px; color: var(--text-0); font-weight: 600; }
.drop-progress { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: rgba(255, 255, 255, 0.08); }
.drop-progress span { display: block; width: 0; height: 100%; background: var(--gold-metal-x); transition: width 0.2s ease; }
.drop-error { margin: 0; color: var(--danger); font-size: var(--text-small); }

/* The build page's text box drew in Safari's own serif on the old stylesheet's
   field colours. Its fields match the shelf's now. */
.start input[type="text"] {
  width: 100%; max-width: 360px; margin: 0;
  background-color: var(--ink-3); color: var(--text-0);
  border: 1px solid var(--line-bright); border-radius: 8px;
  padding: 10px 12px; font: inherit;
}
.start select { margin: 0; background-color: var(--ink-3); border: 1px solid var(--line-bright); border-radius: 8px; }

/* iOS Safari zooms the whole page into any field under 16px the moment it is
   tapped, and leaves it zoomed. On a touch screen every field is 16px. */
@media (hover: none) and (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]),
  select:not([multiple]), textarea:not([hidden]) { font-size: var(--text-body); }
}

/* ---------- the store's type roles ----------
   Approved by the owner on 2026-09-15 and applied to every page: seven roles
   in six sizes, where the store used to hold 60 one-off font sizes. Nothing is
   scoped any more — these ARE the store's sizes, and /styleguide is the page
   that shows them. A new size belongs in this block or nowhere. */
:root {
  --text-title: clamp(2.2rem, 5.5vw, 3.8rem);   /* page titles: Oswald, capitals */
  --text-section: clamp(1.5rem, 3vw, 2rem);     /* section headings, a product's price */
  --text-name: 1.125rem;                        /* product and card names: Oswald */
  --text-lead: 1.125rem;                        /* a page's opening sentence */
  --text-body: 1rem;
  --text-small: 0.875rem;                       /* help lines, meta, captions */
  --text-label: 0.75rem;                        /* field labels, tags: capitals, tracked */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 72px;
}
.t-title { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: var(--text-title);
  line-height: 1.02; letter-spacing: 0.015em; text-transform: uppercase; color: var(--text-0); }
.t-section { font-family: var(--font-display); font-weight: 600; font-size: var(--text-section);
  line-height: 1.1; letter-spacing: 0.01em; color: var(--text-0); }
.t-name { font-family: var(--font-display); font-weight: 500; font-size: var(--text-name);
  line-height: 1.2; letter-spacing: 0.01em; color: var(--text-0); }
.t-lead { margin: 0; font-size: var(--text-lead); line-height: 1.5; color: var(--text-1); max-width: 62ch; }
.t-body { margin: 0; font-size: var(--text-body); color: var(--text-1); }
.t-small { margin: 0; font-size: var(--text-small); color: var(--text-2); }
.t-label { font-size: var(--text-label); font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-2); }
.btn-link { background: none; border-color: transparent; color: var(--gold-300); padding-inline: 4px; }
.btn-link:hover { color: var(--gold-100); text-decoration: underline; text-underline-offset: 4px; }

.sg { display: grid; gap: var(--space-8); }
.sg-head { display: grid; gap: var(--space-3); }
.sg-kicker { color: var(--gold-300); }
.sg-block { display: grid; gap: var(--space-4); }
.sg-h2 { margin: 0; font-size: var(--text-section); font-weight: 600; letter-spacing: 0.01em; text-transform: none; }
.sg-note { margin: 0; max-width: 64ch; color: var(--text-2); font-size: var(--text-small); }
.sg-box {
  display: grid; gap: var(--space-4); align-content: start; min-width: 0;
  padding: var(--space-5); background: var(--ink-1);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.sg-scale { display: grid; margin: 0; border-top: 1px solid var(--line); }
.sg-row {
  display: grid; grid-template-columns: 12rem minmax(0, 1fr); gap: var(--space-2) var(--space-5);
  align-items: baseline; padding: var(--space-4) 0; border-bottom: 1px solid var(--line);
}
.sg-row dt { display: grid; gap: 2px; }
.sg-row dt b { color: var(--text-0); font-size: var(--text-small); }
.sg-row dt span { color: var(--text-2); font-size: var(--text-small); font-variant-numeric: tabular-nums; }
.sg-row dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.sg-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.sg-card { width: 100%; max-width: 280px; }
.sg-fields { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.sg-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-3);
  margin: 0; font-variant-numeric: tabular-nums; }
.sg-price b { font-family: var(--font-display); font-weight: 600; font-size: var(--text-section); line-height: 1; color: var(--text-0); }
.sg-price .set { font-weight: 700; color: var(--gold-300); }
.sg-price span { color: var(--text-2); font-size: var(--text-small); }
.sg-price span.set { font-size: var(--text-body); }
.sg-list { display: grid; gap: var(--space-2); margin: 0; padding-left: 1.1rem; color: var(--text-1); }
.sg-rules { display: grid; border-top: 1px solid var(--line); }
.sg-rule {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-5);
  padding: var(--space-4) 0; border-bottom: 1px solid var(--line);
}
.sg-rule b { color: var(--text-0); }
.sg-error { margin: 0; color: var(--danger); font-size: var(--text-small); font-weight: 500;
  text-transform: none; letter-spacing: normal; }
@media (max-width: 760px) {
  .sg-rule { grid-template-columns: 1fr; }
  .sg-row { grid-template-columns: 1fr; }
}

/* The reference page's own sample fields. Everything else on it uses the
   store's real classes, now that the proposal is the store's look. */
.sg-box .sg-input {
  width: 100%; max-width: none; margin: 0; padding: 12px;
  background: var(--ink-2); color: var(--text-0);
  border: 1px solid var(--line); border-radius: var(--radius);
  font-size: var(--text-body); text-transform: none; letter-spacing: normal;
}
.sg-box .sg-input:focus { border-color: var(--volt); }
.sg-box .sg-input.is-error { border-color: var(--danger); }
/* A button that cannot be used yet says so, on every page. */
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }

/* Read by screen readers, not drawn: the photo step announces its upload
   progress and results here (a review found them silent, 2026-09-11). */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* A button that can't be used yet but keeps its place in the tab order.
   `disabled` on the button that has focus throws a keyboard user back to the top
   of the page; the page's own handler refuses the click instead. */
.btn[aria-disabled="true"] { opacity: 0.55; cursor: progress; }

/* ---------- lift kits: ~2,000 of them, so the truck comes first ----------
   (2026-09-18) The shelf asks for the truck when it has none, each card says
   how the kit fits the truck it has, and every kit has a page of its own. */
.lift-card .kit-link { color: inherit; text-decoration: none; display: block; }
.card .thumb .tread-mark { opacity: 0.9; }
/* On white now: the old grey was drawn for the dark card and read 2.98:1. */
.card .thumb .hint { color: #5b6470; }

/* The truck bar: one on every shelf, in the same place, saying the same
   thing (2026-09-18). */
.truck-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px 18px; padding: 16px 20px; margin: 0 0 16px; }
.truck-bar.is-set { border-color: rgba(212, 175, 55, 0.35); }
/* The truck panel (base.html): pick or change the truck without leaving
   the page. [hidden] needs its own rule -- a display rule outranks it. */
.truck-panel { position: fixed; inset: 0; z-index: 80; display: flex; align-items: flex-start;
  justify-content: center; padding: 72px 16px 16px; background: rgba(4, 6, 10, 0.72); overflow-y: auto; }
.truck-panel[hidden] { display: none; }
.truck-panel-card { width: 100%; max-width: 440px; display: grid; gap: 12px; padding: 18px 18px 16px;
  background: var(--ink-2); border: 1px solid var(--line-bright); border-radius: var(--radius-lg); }
.truck-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.truck-panel-head h2 { margin: 0; font-size: var(--text-lead); }
.truck-panel-close { min-width: 40px; min-height: 40px; border: 0; background: transparent;
  color: var(--text-1); font-size: 28px; line-height: 1; cursor: pointer; }
.truck-panel .field { display: grid; gap: 6px; }
.truck-panel .field select { width: 100%; }
.truck-panel-do { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
.tp-error { margin: 0; }
html.tp-open { overflow: hidden; }
/* The kinds inside a parts group (shop_parts.html): the store's own card,
   two to a row on a phone, so it reads as a shelf and not a menu. */
.kinds-head { font-size: var(--text-lead); margin: 4px 0 12px; }
/* Shelf tops on a phone: the first card on the first screen (2026-09-19). */
.shelf .shelf-lede { margin: -6px 0 22px; }
@media (max-width: 600px) {
  .section.shelf { padding-top: 22px; }
  .shelf > .section-head { margin-bottom: 12px; }
  .shelf > .section-head h1 { font-size: clamp(1.7rem, 8vw, 2.2rem); }
  .shelf .shelf-lede { font-size: var(--text-small); margin: -4px 0 12px; }
  .shelf .truck-bar { padding: 12px 14px; gap: 8px 12px; margin-bottom: 12px; }
  .shelf .truck-bar-facts { font-size: var(--text-label); }
  .shelf .truck-bar-more { display: none; }
  /* The question and its sentence as one paragraph. */
  .shelf .truck-bar:not(.is-set) .truck-bar-text { display: block; }
  /* The header's "Change" is a line above; the tabs name the shelf. */
  .shelf .truck-bar.is-set .btn-ghost { display: none; }
  /* An empty row still costs the bar's gap. */
  .shelf .truck-bar.is-set .truck-bar-do:not(:has(.btn-volt)) { display: none; }
  .shelf > .kicker { display: none; }
  .shelf .photo-nav { margin-bottom: 12px; }
  .shelf .photo-nav.cats .photo-nav-img { aspect-ratio: 128 / 72; }
  .shelf .photo-nav.cats .photo-nav-item { gap: 4px; }
}
/* The truck bar's two ways out: every truck's stock, or another truck. */
.truck-bar-do { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.truck-bar-all { display: inline-flex; align-items: center; min-height: 32px; color: var(--volt);
  font-weight: 600; font-size: var(--text-small); text-decoration: underline; text-underline-offset: 3px; }
/* The parts shelf's departments (shop_parts.html). */
.parts-dept { margin: 0 0 26px; }
.dept-head { font-size: var(--text-lead); margin: 0 0 2px; }
.dept-line { margin: 0 0 12px; }
.grid-cards.kind-cards { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); margin-bottom: 28px; }
.kind-card .thumb { aspect-ratio: 4 / 3; }
.kind-card .name { font-size: var(--text-body); }
.kind-card .kind-count { margin-top: auto; padding-top: 6px; color: var(--volt); font-weight: 600;
  font-size: var(--text-small); }
.kind-line { margin: -8px 0 18px; color: var(--text-1); }
.kicker a.kicker-back { color: inherit; text-decoration: none; }
.kicker a.kicker-back:hover { text-decoration: underline; }
/* The other half of the set, under a product (_pairs.html). */
.pairs .section-note { margin: 4px 0 0; }
.pairs-links { display: flex; flex-wrap: wrap; gap: 8px; }
/* Links wrap under the heading rather than squeeze beside it. */
.pairs .section-head { flex-wrap: wrap; gap: 14px 20px; }
.pairs .section-head > div:first-child { flex: 1 1 20rem; }
.pairs-links .btn { white-space: nowrap; }
/* Consecutive pair rows: one gap, not two. */
.pairs + .pairs { padding-top: 0; }
/* The wheel shelf's door to the dually packages on the parts shelf. */
a.truck-bar.dually-more { margin-top: 10px; color: var(--text-0); text-decoration: none; }
a.truck-bar.dually-more:hover { border-color: var(--volt); }
.truck-bar-text { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px;
  color: var(--text-1); max-width: 62rem; line-height: 1.5; }
.truck-bar-text b { color: var(--text-0); }
.truck-bar-mark { color: var(--volt); font-weight: 700; }
.truck-bar-facts { flex-basis: 100%; color: var(--text-2); font-size: var(--text-small); }
.truck-bar-mark { margin-right: 4px; }
.truck-bar .btn { white-space: nowrap; }
.truck-bar-note { margin: -8px 0 16px; }

/* The header's icons: the account, the build list with its count, and on a
   phone the menu (2026-09-18). */
.nav-icons { display: flex; align-items: center; gap: 10px; }
.nav-icon { position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 10px; color: var(--text-1); background: none;
  border: 0; cursor: pointer; }
.nav-icon:hover, .nav-icon:focus-visible { color: var(--volt); background: var(--ink-2); }
.nav-icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.cart-badge { position: absolute; top: 3px; right: 1px; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--volt); color: #141005; font-size: 11px; font-weight: 800;
  line-height: 18px; text-align: center; font-variant-numeric: tabular-nums; }
.cart-badge[data-n="0"] { display: none; }
.site-nav .links a.nav-cta { color: var(--volt); border: 1px solid rgba(212, 175, 55, 0.45);
  border-radius: 999px; padding: 7px 14px; }
.site-nav .links a.nav-cta:hover { background: rgba(212, 175, 55, 0.1); }
.nav-menu-btn, .site-nav .links a.nav-menu-only { display: none; }
@media (max-width: 900px) {
  .site-nav { flex-wrap: wrap; gap: 8px 10px; padding: 10px 16px; }
  .site-nav .brand { order: 1; }
  .nav-icons { order: 2; margin-left: auto; }
  .nav-menu-btn { display: inline-flex; }
  .site-nav .nav-search { order: 3; flex-basis: 100%; margin: 2px 0 0; }
  .site-nav .links { order: 4; display: none; width: 100%; flex-direction: column; align-items: stretch;
    gap: 0; margin: 4px 0 0; padding: 4px 0; border-top: 1px solid var(--line); }
  .site-nav .links.open { display: flex; }
  .site-nav .links a, .site-nav .links a.nav-menu-only { display: block; padding: 14px 4px; margin: 0;
    font-size: var(--text-body); letter-spacing: 0.08em; border-bottom: 1px solid var(--line); }
  .site-nav .links a.nav-cta { border-radius: 0; border-width: 0 0 1px; padding: 14px 4px; }
  .site-nav .nav-account { display: none; }
  .site-nav .truck-strip { order: 5; width: calc(100% + 32px); margin: 2px -16px -10px; }
  .truck-strip-row { flex-wrap: nowrap; white-space: nowrap; overflow: hidden; padding-block: 8px; }
  .truck-strip-label { display: none; }
  .truck-strip-truck { overflow: hidden; text-overflow: ellipsis; }
  /* The truck's name gives way first; "Change" and the x never do. */
  .truck-strip-row > a { flex-shrink: 0; }
}
@media (max-width: 600px) {
  .promo-more { display: none; }
}

/* The guided build (2026-09-18): the next step after an Add, and the cart's
   steps. */
.added-next { display: block; margin-top: 6px; color: var(--volt); font-weight: 600;
  font-size: var(--text-small); }
.added-next[hidden] { display: none; }
.cart-steps { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 18px 0 0; }
.cart-steps[hidden] { display: none; }
/* An empty build list: the four shelves as photographs (cart.html). */
.cart-empty { max-width: 560px; margin: 24px auto 0; padding: 32px 0 8px; }
.cart-empty-head { margin: 0 0 6px; color: var(--text-0); font-weight: 600;
  font-size: var(--text-lead); }
.cart-empty-line { margin: 0 0 18px; }
.cart-empty .photo-nav { justify-content: center; margin: 0 0 18px; text-align: left; }
.cart-steps-label { color: var(--text-2); font-size: var(--text-label); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em; margin-right: 4px; }
.cart-step { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line-bright); color: var(--text-1); font-size: var(--text-small); }
.cart-step.done { border-color: rgba(212, 175, 55, 0.45); color: var(--text-0); }
.cart-step.done::before { content: "\2713"; color: var(--volt); font-weight: 700; }
a.cart-step:hover { border-color: var(--volt); color: var(--volt); }

/* The build list says what will not go on the saved truck (2026-09-18). */
.cart-fit-note { margin: 22px 0 0; max-width: 62rem; padding: 12px 16px; border-radius: 10px;
  border: 1px solid rgba(230, 120, 90, 0.5); background: rgba(230, 120, 90, 0.08); color: var(--text-0); }
.cart-fit-warn { display: block; margin-top: 4px; color: #f0a38b; font-size: var(--text-small); }
.cart-fit-fix { display: block; margin-top: 2px; color: var(--volt); font-size: var(--text-small); font-weight: 600; }
.size-path { color: var(--volt); font-size: var(--text-small); font-weight: 600; white-space: nowrap; }
.added.is-warn { border-color: #f0a38b; }
.added.is-warn .added-head { color: #f0a38b; }
.cart-line.no-fit .cart-name { color: var(--text-1); }

/* One search across the store (2026-09-18). */
.search-page { padding-top: clamp(28px, 4vw, 48px); }
.search-title { font-size: clamp(1.6rem, 3.4vw, 2.5rem); text-transform: none; letter-spacing: 0;
  line-height: 1.15; margin: 4px 0 6px; text-wrap: balance; }
.search-section .section-head { flex-wrap: wrap; gap: 10px 16px; }
.search-more { margin-top: 16px; }
.search-big { display: flex; gap: 10px; max-width: 720px; margin: 8px 0 18px; }
.search-big input { flex: 1; min-width: 0; font-size: 1.1rem; padding: 14px 16px; border-radius: 12px;
  border: 1px solid var(--line-bright); background: var(--bg-1, #121418); color: var(--text-0); }
.search-big input:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }
.search-summary a, .search-back a { color: var(--volt); }
.search-section { margin-top: 34px; }
.search-count { color: var(--text-2); font-size: 0.7em; font-weight: 500; margin-left: 6px; }
.search-none-fit { margin: -4px 0 14px; }
.search-empty { margin-top: 26px; }
.search-empty p { max-width: 62ch; color: var(--text-1); }
.search-empty a { color: var(--volt); }

/* The product page's full story: the maker's own words, what is in the box,
   the numbers (2026-09-18). Read like a spec sheet, not a wall. */
.kit-about p { max-width: 70ch; margin: 0 0 12px; color: var(--text-1); line-height: 1.6; }
.kit-about p b, .kit-features li b { color: var(--text-0); }
.kit-about h3 { font-family: var(--font-display); font-size: var(--text-name); margin: 22px 0 10px; }
.kit-more { max-width: 70ch; margin-top: 16px; }
.kit-more summary { cursor: pointer; color: var(--volt); font-weight: 600; padding: 6px 0; }
.kit-more[open] summary { margin-bottom: 10px; }
.box-list { list-style: none; margin: 0 0 14px; padding: 0; border-top: 1px solid var(--line);
  max-width: 820px; }
.spec-table.specs { max-width: 820px; }
.box-list li { display: grid; grid-template-columns: 3.2em 1fr auto; gap: 4px 12px; align-items: baseline;
  padding: 12px 0; border-bottom: 1px solid var(--line); }
.box-qty { font-weight: 700; color: var(--text-0); font-variant-numeric: tabular-nums; }
.box-name { color: var(--text-1); }
.box-sku { color: var(--text-2); font-size: var(--text-small); font-variant-numeric: tabular-nums; white-space: nowrap; }
.spec-table.specs th { width: 34%; }
@media (max-width: 600px) {
  .box-list li { grid-template-columns: 2.6em 1fr; }
  .box-sku { grid-column: 2; }
}
.lift-card .kit-link:hover .name { color: var(--volt); }
.lift-card .kit-body { padding-top: 0; }
/* Which one it is, under what it is (product_names.py). */
.lift-card .name-rest { display: block; margin-top: 4px; color: var(--text-2);
  font-size: var(--text-small); line-height: 1.4; overflow-wrap: anywhere; }
.product-name-rest { margin: 8px 0 0; color: var(--text-1); font-size: var(--text-body);
  line-height: 1.5; max-width: 60ch; overflow-wrap: anywhere; }
.kit-height { display: block; margin: 0 0 6px; font-size: var(--text-small); color: var(--text-1); }
.kit-fit { display: block; font-size: var(--text-small); color: var(--text-0);
  border-left: 2px solid var(--volt); padding-left: 10px; margin: 2px 0 6px; }
.kit-fit.no { border-left-color: var(--line-bright); color: var(--text-2); }
.pager { display: flex; gap: 14px; align-items: center; justify-content: center;
  margin-top: 24px; flex-wrap: wrap; }
.kit-stage { padding: 4%; background: #fff; }
.kit-stage img { filter: none; }
.photo-strip .kit-pick img { background: #fff; object-fit: contain; }
.kit-nofit { padding: 12px 14px; border-radius: var(--radius);
  border: 1px solid var(--line-bright); background: var(--ink-2, rgba(255,255,255,0.03)); }
.kit-nofit b { display: block; color: var(--text-0); margin-bottom: 4px; }
.kit-nofit span { font-size: var(--text-small); color: var(--text-1); }
.kit-nofit a, .fit-line a { color: var(--volt); }
.kit-notes { margin-top: 18px; padding: 16px 18px; border-radius: var(--radius-lg);
  border: 1px solid var(--line); }
.kit-notes h2, .kit-block h2 { font-size: var(--text-name); margin: 0 0 8px; }
.kit-notes p { margin: 0; color: var(--text-1); font-size: var(--text-small); }
.kit-detail { display: grid; gap: 34px; padding-block: 8px 56px; }
/* A grid item is as wide as its widest content unless told otherwise, and a
   fitment table is wide by nature -- it scrolls in its own box instead. */
.kit-detail > * { min-width: 0; }
.kit-block p { color: var(--text-1); max-width: 72ch; }
.kit-block td a, .kit-block p a { color: var(--volt); }
.kit-features { margin: 0; padding-left: 1.1em; display: grid; gap: 8px;
  color: var(--text-1); max-width: 72ch; }
.kit-block details summary { cursor: pointer; color: var(--volt); margin-bottom: 10px; }

/* ---------- tire photographs (2026-09-18) ----------
   WheelPros's own shots -- the tire, its tread, its sidewall -- on white, the
   way they are photographed. Shorter than a wheel's square stage: a tire is
   read from its side. */
.tire-photos { margin-bottom: 6px; }
.tire-stage { aspect-ratio: 4 / 3; background: #fff; padding: 4%; }
.tire-stage img { filter: none; }
.photo-strip .tire-pick img { background: #fff; object-fit: contain; }
@media (min-width: 1000px) {
  .tire-top.has-photo { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .tire-top.has-photo .tire-photos { grid-column: 1; grid-row: 1 / span 2; }
  .tire-top.has-photo .product-head { grid-column: 2; grid-row: 1; }
  .tire-top.has-photo .tire-aside { grid-column: 2; grid-row: 2; }
}


/* A dually size in another bolt pattern: shown, so the customer sees the
   whole line, and dimmed, because it does not bolt on. */
.spec-table tr.not-yours td { color: var(--text-2); }

/* The dually question: one plain line and three answers. */
.truck-rear { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 16px 14px;
  margin: 0 0 14px; display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; }
.truck-rear legend, .truck-setup legend { font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: 0.08em; font-size: var(--text-label); color: var(--text-2); padding: 0 6px; }
/* How it sits today: two optional answers, under the truck (2026-09-19). */
.truck-setup { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 16px 14px;
  margin: 0 0 14px; display: grid; gap: 10px; }
.truck-rear .hint { flex-basis: 100%; margin: 0; }
.truck-rear label { display: inline-flex; gap: 6px; align-items: center; color: var(--text-1); }

/* ---------- the showroom (2026-09-18) ----------
   "Think of the Apple company for car parts." Every way into the catalogue is
   a photograph of what is behind it, with one word under it: never a word on
   its own. */
.photo-nav {
  display: flex; gap: 14px; overflow-x: auto; scroll-snap-type: x proximity;
  padding: 4px 2px 12px; margin: 0 0 22px; scrollbar-width: none;
}
.photo-nav::-webkit-scrollbar { display: none; }
.photo-nav-item {
  flex: 0 0 auto; width: 128px; scroll-snap-align: start; text-decoration: none;
  display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center;
  color: var(--text-1);
}
.photo-nav-img {
  width: 128px; height: 88px; border-radius: 14px; overflow: hidden; display: block;
  background: #fff; border: 1px solid var(--line);
  transition: transform 160ms ease, border-color 160ms ease;
}
.photo-nav-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-nav-label { font-size: var(--text-small); font-weight: 600; line-height: 1.25; color: var(--text-0); }
.photo-nav-sub { font-size: var(--text-label); color: var(--text-2); margin-top: -4px; }
.photo-nav-item:hover .photo-nav-img, .photo-nav-item:focus-visible .photo-nav-img {
  transform: translateY(-2px); border-color: var(--volt);
}
.photo-nav-item.on .photo-nav-img { border: 2px solid var(--volt); }
.photo-nav-item.on .photo-nav-label { color: var(--volt); }
/* The four shelves, all on a phone's width (2026-09-18). */
.photo-nav.cats { display: grid; grid-template-columns: repeat(4, minmax(0, 128px)); overflow: visible; }
.photo-nav.cats .photo-nav-item { width: auto; min-width: 0; }
.photo-nav.cats .photo-nav-img { width: 100%; height: auto; aspect-ratio: 128 / 88; }
/* The wheel shelf by look: a whole wheel on white, never cropped to fill. */
.looks-head { margin: 0 0 8px; color: var(--text-0); font-weight: 600; font-size: var(--text-small); }
.photo-nav.looks .photo-nav-img img { object-fit: contain; padding: 6px; }
@media (prefers-reduced-motion: reduce) {
  .photo-nav-img { transition: none; }
  .photo-nav-item:hover .photo-nav-img { transform: none; }
}
@media (max-width: 600px) {
  .photo-nav-item { width: 104px; }
  .photo-nav-img { width: 104px; height: 72px; }
}

/* The front door leads with the name. */
.hero-brand { font-family: var(--font-display); font-weight: 700; letter-spacing: 0.01em;
  line-height: 0.92; font-size: clamp(3rem, 9vw, 7.5rem); margin: 0 0 14px; text-transform: uppercase; }
.hero-brand .gold { color: var(--gold-300); }
.hero-promise { font-size: clamp(1.15rem, 2.2vw, 1.5rem); color: var(--text-0); max-width: 38rem; margin: 0 0 22px; }
/* Once a truck is saved, the front door names it (2026-09-18). */
.hero-truck { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: -8px 0 0;
  color: var(--text-0); font-size: var(--text-body); }

/* The front page's catalogue -- shelves, then parts groups, then truck lines --
   reads as one run of pictures, not three sections each a screen apart. */
.section.section-follow { padding-top: 8px; }

/* A section of photo tiles on the front page, and on the parts shelf. */
.cat-tiles.many { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) { .cat-tiles.many { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Brands are logos, on the dark ground their light-on-dark art was made for. */
.brand-logos { display: flex; flex-wrap: wrap; gap: 26px 40px; align-items: center; justify-content: center; }
.brand-logos img { height: 40px; width: auto; max-width: 170px; object-fit: contain; opacity: 0.92; }
.brand-logos img:hover { opacity: 1; }
.brand-mark { height: 16px; width: auto; max-width: 110px; object-fit: contain; vertical-align: -3px; }
.brand-kicker { height: 30px; width: auto; max-width: 220px; object-fit: contain; display: block; margin-bottom: 6px; }
/* The front door's name and numbers, sized for the cinematic hero -- the
   older .hero rules never reached it, so the numbers stacked in a column. */
.hero-cine-content .hero-brand { font-size: clamp(3.2rem, 8.5vw, 7rem); margin: 0 0 12px; line-height: 0.92; }
.hero-cine-content .stat-row { display: flex; flex-wrap: wrap; gap: 14px 36px; margin-top: 30px; }
@media (max-width: 600px) {
  /* Four numbers as two pairs, not three and a straggler. */
  .hero-cine-content .stat-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; }
}
.hero-cine-content .stat b { font-family: var(--font-display); font-size: var(--text-section); line-height: 1; }
.hero-cine-content .stat span { color: var(--text-2); font-size: var(--text-label); text-transform: uppercase; letter-spacing: 0.14em; }
