/* Sagebrush palette, carried over from the printed reports so the tracker and
   the documents read as one thing. */
:root {
  /* Native controls - the date picker's calendar popup and its icon above all -
     are drawn by the browser, not by this stylesheet. Without this they render
     light-on-dark against the dark theme: a white calendar dropping out of a
     dark field, and an all-but-invisible icon. Declaring the scheme is what
     hands the UA the theme it is already painting around. */
  color-scheme: light dark;

  --ground: #EDEFE9;
  --surface: #FBFCF9;
  --surface-2: #F3F5EF;
  --ink: #171B14;
  --muted: #5B6154;
  --line: #D6DACE;
  --line-soft: #E3E6DD;
  --accent: #8A5A12;
  --accent-bright: #B4771F;
  --good: #2C6247;
  --good-bg: #E2EDE5;
  --alert: #9C3A25;
  --alert-bg: #F5E3DE;

  --sans: "Archivo", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --serif: "Source Serif 4", Georgia, "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #12150F; --surface: #191D16; --surface-2: #20241C;
    --ink: #E8EBE1; --muted: #99A08E; --line: #2C3128; --line-soft: #232821;
    --accent: #D9A03F; --accent-bright: #D9A03F;
    --good: #74C295; --good-bg: #1B2E24;
    --alert: #E28A72; --alert-bg: #33201B;
  }
}
/* The same palette again for someone who CHOSE dark with the theme picker
   (_ThemePicker.cshtml) on a device set to light. Kept beside the block above
   so the two are edited together - they must stay identical. color-scheme is
   pinned per choice so native controls (the date picker above all) follow the
   picker rather than the device. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ground: #12150F; --surface: #191D16; --surface-2: #20241C;
  --ink: #E8EBE1; --muted: #99A08E; --line: #2C3128; --line-soft: #232821;
  --accent: #D9A03F; --accent-bright: #D9A03F;
  --good: #74C295; --good-bg: #1B2E24;
  --alert: #E28A72; --alert-bg: #33201B;
}
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-underline-offset: 2px; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--accent-bright); outline-offset: 2px;
}

/* ---------- chrome ---------- */

/* A link to #gone or #arrived scrolls its table to the top of the window,
   which is exactly where the sticky topbar sits - so without this, clicking a
   sortable heading landed you with that heading hidden under the nav. Set on
   the scroller rather than per section so every in-page anchor gets it. Sized
   for the admin topbar at its tallest two-row wrap, with room to spare. */
html { scroll-padding-top: 120px; }

.topbar {
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  position: sticky; top: 0; z-index: 10;
}
.topbar__inner {
  max-width: 1240px; margin: 0 auto; padding: 0 20px;
  display: flex; align-items: center; gap: 28px; min-height: 56px;
}
.brand { font-weight: 700; letter-spacing: -0.02em; font-size: 16px; text-decoration: none; color: var(--ink); }
.brand span { color: var(--accent); }
.nav { display: flex; gap: 20px; flex: 1; flex-wrap: wrap; }
.nav a {
  font-size: 13.5px; font-weight: 500; text-decoration: none; color: var(--muted);
  padding: 4px 0; border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--ink); }
.nav a.active { color: var(--ink); border-bottom-color: var(--accent-bright); }
/* Thirteen links for an admin. At 20px the Bots link pushed the bar to three
   rows up to 1200px wide; at 14px it holds two from 1150px, a little better
   than the twelve did at 20px (measured 2026-10-16). Members keep 20px. */
.nav--admin { column-gap: 14px; }
/* The phone menu (below): on a wide screen the button is hidden and the drawer
   is display: contents, so its children sit in the bar exactly as before. */
.topbar__menu { display: none; }
.topbar__drawer { display: contents; }
.nav__sep { display: none; }

main { max-width: 1240px; margin: 0 auto; padding: 32px 20px 80px; }

/* ---------- typography ---------- */

h1 { font-size: 27px; font-weight: 700; letter-spacing: -0.022em; margin: 0 0 6px; text-wrap: balance; }
h2 {
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  margin: 0 0 14px; padding-bottom: 10px; border-bottom: 2px solid var(--ink);
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
}
h2 .note { font-family: var(--mono); font-size: 11px; font-weight: 400; letter-spacing: 0.03em; text-transform: none; color: var(--muted); }
.lede { color: var(--muted); font-family: var(--serif); font-size: 16px; margin: 0 0 28px; max-width: 70ch; }
section { margin-bottom: 40px; }

/* ---------- cards ---------- */

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 3px; overflow: hidden; }
.card { background: var(--surface); padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 2px; }
.card__name { font-size: 13.5px; font-weight: 600; }
.card__sub { font-size: 12px; color: var(--muted); }
.card__big { font-family: var(--mono); font-size: 25px; font-weight: 500; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; margin-top: 8px; line-height: 1; }
.card--accent { background: var(--surface-2); }
.card--accent .card__big { color: var(--accent); }
/* A card that is a link keeps the card's colors; the hover is the affordance. */
a.card--link { color: inherit; text-decoration: none; }
a.card--link:hover { background: var(--surface-2); }
a.card--link:hover .card__name { color: var(--accent); }

/* ---------- series colors ---------- */

/* Validated against THIS site's surfaces (#FBFCF9 light, #191D16 dark) with
   the dataviz validator: slots 1-4 plus the gray Other clear color-blind
   separation on every adjacent pair in both themes. Aqua and yellow fall under
   3:1 on the light surface, which is why the legend table under the donuts
   always carries every name, count and share.

   On :root rather than on .mix because the lot chart at the foot of /dealer
   draws from the same slots - two charts on one page taking their blues from
   two different declarations is how they end up disagreeing. */
:root {
  --series-1: #2a78d6; --series-2: #eb6834; --series-3: #1baf7a; --series-4: #eda100;
  --series-other: #8a8f82;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; --series-4: #c98500;
    --series-other: #6f7566;
  }
}
:root[data-theme="dark"] {
  --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; --series-4: #c98500;
  --series-other: #6f7566;
}

/* ---------- brand / category donuts (/dealer) ---------- */
.s1 { --c: var(--series-1); } .s2 { --c: var(--series-2); } .s3 { --c: var(--series-3); }
.s4 { --c: var(--series-4); } .s0 { --c: var(--series-other); }

.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 3px; overflow: hidden; margin-bottom: 16px; }
.seg button { font: inherit; font-size: 13px; padding: 6px 14px; border: 0; background: var(--surface); color: var(--muted); cursor: pointer; }
.seg button + button { border-left: 1px solid var(--line); }
.seg button[aria-pressed="true"] { background: var(--surface-2); color: var(--ink); font-weight: 600; }

.mix__pies { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 16px; }
.donut { margin: 0; background: var(--surface); border: 1px solid var(--line); border-radius: 3px; padding: 14px 16px 18px; }
.donut figcaption { font-size: 13.5px; font-weight: 600; margin-bottom: 6px; }
.donut svg { display: block; width: 100%; max-width: 220px; margin: 0 auto; overflow: visible; }
.donut__arc { fill: none; stroke: var(--c); stroke-width: 26; cursor: default; transition: opacity .12s; }
.donut__arc:focus { outline: none; }
/* Hovering one slice recedes the rest of THAT donut only. */
.donut svg:has(.donut__arc:hover, .donut__arc:focus) .donut__arc:not(:hover):not(:focus) { opacity: .3; }
.donut__n { font-family: var(--sans); font-size: 26px; font-weight: 600; fill: var(--ink); text-anchor: middle; }
.donut__l { font-family: var(--sans); font-size: 10.5px; fill: var(--muted); text-anchor: middle; }
.donut__empty { height: 160px; display: grid; place-items: center; color: var(--muted); font-size: 13px; }

/* Sortable table headings: the heading stays a heading, the link is the
   whole label, and the active column is the one in full ink. */
th.sortable a { color: inherit; text-decoration: none; }
th.sortable a:hover { color: var(--accent); }
th.sortable--on { color: var(--ink); }

/* The implausible-price flag. Small and round so it reads as an annotation
   on the number, not a status; the reason is its tooltip and accessible name. */
.flag {
  display: inline-grid; place-items: center; width: 15px; height: 15px; margin-left: 5px;
  border-radius: 50%; background: var(--alert-bg); color: var(--alert);
  font-family: var(--sans); font-size: 10.5px; font-weight: 700; line-height: 1;
  vertical-align: 1px; cursor: help;
}
.card__big .flag { vertical-align: 5px; }

/* /changes: a unit's own dated steps, opened from its Moves cell. */
.moves__toggle { padding: 0; white-space: nowrap; }
.moves__toggle::after { content: " ▸"; }
.moves__toggle--open::after { content: " ▾"; }
.moves__steps td { background: var(--surface-2); padding-top: 6px; padding-bottom: 10px; }
.moves__steps ol { margin: 0; padding-left: 20px; display: grid; gap: 4px; font-variant-numeric: tabular-nums; }
.moves__steps li { font-size: 13px; }
.moves__steps .code { display: inline-block; min-width: 88px; }

.mix__rest td { color: var(--muted); }
.mix__rest .mix__rest-name { padding-left: 30px; }
.linkish { font: inherit; font-size: 13px; background: none; border: 0; padding: 8px 0 0; color: var(--accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }

.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: var(--c); margin-right: 8px; vertical-align: -1px; }

/* ---------- tables ---------- */

.scroller { overflow-x: auto; border: 1px solid var(--line); border-radius: 3px; background: var(--surface); }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
caption { caption-side: top; text-align: left; padding: 14px 16px 12px; border-bottom: 1px solid var(--line); background: var(--surface-2); font-weight: 600; }
th {
  text-align: left; font-size: 10px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--muted); padding: 10px 13px;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
td { padding: 9px 13px; border-bottom: 1px solid var(--line-soft); vertical-align: baseline; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-2); }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.01em; text-align: right; }
th.num { text-align: right; }
.code { font-family: var(--mono); font-size: 12px; color: var(--muted); white-space: nowrap; }
.strong { font-weight: 600; }
.best { color: var(--good); font-weight: 600; }
.dash { color: var(--muted); }
.down { color: var(--good); font-weight: 600; }
.up { color: var(--alert); font-weight: 600; }

.chip { display: inline-block; font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; padding: 3px 7px; border-radius: 2px; white-space: nowrap; }
.chip--good { background: var(--good-bg); color: var(--good); }
.chip--alert { background: var(--alert-bg); color: var(--alert); }
.chip--flat { background: var(--surface-2); color: var(--muted); border: 1px solid var(--line); }

/* ---------- controls ---------- */

.filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 16px; }
.field { display: flex; flex-direction: column; gap: 4px; }
.field label { font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); }
/* Targeted by element rather than by class, so a new input type is invisible
   to this rule until it is listed here. email/number/password arrived with the
   sign-in and admin screens; date with the pickers on /changes and /turnover. */
input[type=search], input[type=text], input[type=email], input[type=number],
input[type=password], input[type=date], select, textarea {
  font: inherit; font-size: 13.5px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: 3px;
  background: var(--surface); color: var(--ink); min-width: 150px;
}
textarea { min-height: 64px; resize: vertical; }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent-bright); outline-offset: 1px;
}
button, .btn {
  font: inherit; font-size: 13.5px; font-weight: 500; padding: 7px 14px;
  border: 1px solid var(--line); border-radius: 3px; cursor: pointer;
  background: var(--surface); color: var(--ink); text-decoration: none; display: inline-block;
}
button:hover, .btn:hover { background: var(--surface-2); }
.btn--primary { background: var(--accent-bright); border-color: var(--accent-bright); color: #fff; }
.btn--primary:hover { filter: brightness(1.06); background: var(--accent-bright); }
button[disabled] { opacity: .5; cursor: not-allowed; }

.empty { padding: 40px 20px; text-align: center; color: var(--muted); font-family: var(--serif); }
.pager { display: flex; gap: 8px; align-items: center; margin-top: 14px; font-size: 13px; color: var(--muted); }

/* ---------- caveats ---------- */

/* Every number on this site is inferred from someone else's website, so the
   places where the inference can be wrong get said out loud rather than
   buried in a tooltip. */
.warn {
  border: 1px solid var(--alert); border-left-width: 3px; border-radius: 3px;
  background: var(--alert-bg);
  padding: 12px 16px; margin: 0 0 18px;
  font-family: var(--serif); font-size: 14px; line-height: 1.45;
}
.warn--soft { border-color: var(--line); border-left-color: var(--accent); background: var(--surface-2); color: var(--muted); }

.floor { color: var(--muted); font-family: var(--mono); font-size: 11px; }

/* Leaves the site for the dealer's own page, so it is marked as such
   rather than looking like the internal unit links beside it. */
.ext { font-size: 12px; white-space: nowrap; text-decoration: none; border-bottom: 1px solid var(--line); }
.ext:hover { border-bottom-color: var(--accent); }

/* ---------- sparkline ---------- */

.spark { display: block; width: 100%; height: 150px; }
.spark-line { fill: none; stroke: var(--accent-bright); stroke-width: 2; }
.spark-area { fill: var(--accent-bright); opacity: .10; }
.spark-dot { fill: var(--accent-bright); }
.spark-grid { stroke: var(--line); stroke-width: 1; }
.spark-label { font-family: var(--mono); font-size: 10px; fill: var(--muted); }

/* ---------- the last 30 days (/dealer) ---------- */

/* One frame, two scales: counts on the left, the lot on the right. The chart
   keeps its own width rather than shrinking to the phone - thirty days squeezed
   into 360px is a smudge, and the page already scrolls tables sideways in
   exactly this frame. */
.lot30__frame { padding: 16px 16px 10px; }
.lot30__svg { display: block; width: 100%; min-width: 620px; height: auto; overflow: visible; }

.lot30, .lot30__chart { --c-lot: var(--accent-bright); --c-in: var(--series-1); --c-out: var(--series-3); }
.s-lot { --c: var(--c-lot); } .s-in { --c: var(--c-in); } .s-out { --c: var(--c-out); }

.lot30__line { fill: none; stroke: var(--c); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
/* Dashed, not only green: the two count lines have to be separable in print, in
   forced colors, and by a reader who cannot tell the hues apart. */
.lot30__line.s-out { stroke-dasharray: 5 3; }
/* The lot is the backdrop, so it is drawn quieter than what is happening on
   top of it - a thinner line over a wash rather than a third bold stroke. */
.lot30__line.s-lot { stroke-width: 1.75; }
.lot30__area { fill: var(--c-lot); opacity: .065; }
.lot30__dot { fill: var(--c); }
.lot30__dot.s-lot { opacity: .85; }
/* Hollow: a morning whose numbers need reading with care. */
.lot30__dot--flag { fill: var(--surface); stroke: var(--c); stroke-width: 1.6; }
/* The window's average, dotted so it cannot be mistaken for a day's reading. */
.lot30__avg { stroke: var(--c); stroke-width: 1.25; stroke-dasharray: 1 4; stroke-linecap: round; opacity: .75; }
.lot30__base { stroke: var(--line); stroke-width: 1; }
.lot30__tick-mark { stroke: var(--line); stroke-width: 1; }
.lot30__tick-mark.s-lot { stroke: var(--c-lot); opacity: .6; }
.lot30__cross { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 2 3; pointer-events: none; }
.lot30__hit { fill: transparent; }

/* Each axis is named in the color of the line it measures - the one thing
   that keeps a two-scale chart readable. */
.lot30__axis-name { font-family: var(--sans); font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; fill: var(--muted); }
.lot30__axis-name.s-lot, .lot30__val.s-lot { fill: var(--c-lot); }
.lot30__val, .lot30__tick { font-family: var(--mono); font-size: 10px; fill: var(--muted); font-variant-numeric: tabular-nums; }
/* Anchored in CSS, not on the element: a text-anchor ATTRIBUTE loses to this
   rule, and the right-hand numbers then ran backwards into the plot and sat on
   top of the line they label. */
.lot30__val { text-anchor: end; }
.lot30__val.s-lot { text-anchor: start; }
.lot30__tick { text-anchor: middle; }

/* The tooltip, in one fixed place. It holds the newest morning until a pointer
   moves it, so it is a caption as much as a readout. */
.lot30__read { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin: 16px 0 10px; font-size: 13.5px; color: var(--muted); }
.lot30__read b { font-weight: 600; color: var(--ink); font-size: 15px; letter-spacing: -0.02em; }
.lot30__when { font-family: var(--mono); font-size: 12px; color: var(--ink); font-weight: 500; min-width: 88px; }
.lot30__lot b { color: var(--accent); }
.lot30__in b { color: var(--series-1); }
.lot30__out b { color: var(--series-3); }
.lot30__caveat { font-family: var(--serif); font-size: 13px; color: var(--alert); }

.lot30__legend { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; margin: 10px 0 14px; font-size: 12.5px; color: var(--muted); }
.lot30__key { display: inline-block; width: 16px; height: 0; border-top: 2px solid var(--c); vertical-align: 2px; margin-right: 7px; }
.lot30__key--dash { border-top-style: dashed; }
.lot30__key--avg { border-top-style: dotted; border-top-color: var(--muted); }
/* The lot's key carries its wash as well as its line, because that is what the
   eye is actually looking for in the frame. */
.lot30__key--band { height: 9px; border-bottom: 9px solid var(--c-lot); border-bottom-color: color-mix(in srgb, var(--c-lot) 12%, transparent); vertical-align: -3px; }
.lot30__key--flag { width: 9px; height: 9px; border: 1.6px solid var(--muted); border-radius: 50%; background: var(--surface); margin-right: 7px; vertical-align: -1px; }
/* Which axis a series is read off, said in the legend rather than only drawn. */
.lot30__item { white-space: nowrap; }
/* Horizontal drags scrub the chart (lot30.js); vertical ones still scroll the page. */
.lot30__svg { touch-action: pan-y; }
.lot30__side { font-family: var(--mono); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); opacity: .75; margin-left: 5px; }

/* The chart on a phone - the dealer page and the front page's hero alike.
   At 620px minimum it scrolled sideways inside its frame, so a phone showed
   half a month and a scrollbar. Here it fits the width instead, and because
   the whole drawing then shrinks to under half size, everything a reader has
   to see is drawn bigger in the chart's own units: labels, lines, dots. The
   two axis titles go - at that size they collide - and the legend, which
   says left and right, carries the keying on its own. */
@media (max-width: 600px) {
  .lot30__svg { min-width: 0; }
  .lot30__frame { padding: 10px 6px 6px; }
  .lot30__axis-name { display: none; }
  .lot30__val, .lot30__tick { font-size: 23px; dominant-baseline: central; }
  .lot30__tick-mark { display: none; }
  .lot30__line { stroke-width: 3.6; }
  .lot30__line.s-lot { stroke-width: 3.2; }
  .lot30__line.s-out { stroke-dasharray: 9 6; }
  .lot30__dot { r: 4.4px; }
  .lot30__avg { stroke-width: 2.6; stroke-dasharray: 2 8; }
  .lot30__cross { stroke-width: 2; }

  .lot30__chart .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lot30__chart .card { padding: 11px 12px 13px; }
  .lot30__chart .card__big { font-size: 21px; margin-top: 6px; }
  .lot30__chart .card__sub { font-size: 11.5px; }
  .lot30__read { gap: 2px 12px; font-size: 13px; margin: 12px 0 8px; }
  .lot30__when { min-width: 0; flex-basis: 100%; }
  /* Dates sit a little lower, clear of the count axis's 0 at the corner. */
  .lot30__tick { transform: translateY(8px); }
  .lot30__legend { gap: 6px 16px; font-size: 12px; }
  /* Color already ties each line to its axis - the lot's numbers are in its
     accent - and the left/right tags are what made the legend wrap badly. */
  .lot30__side { display: none; }
}

/* ---------- behavior: gates and bars ---------- */

/* A note that is a paragraph rather than an aside beside a figure. The inline
   .note is 11px mono and disappears at the top of a page; this one has to be
   read, because it is what qualifies every number under it. */
.note--block {
  font-family: var(--serif); font-size: 14px; line-height: 1.6; color: var(--muted);
  max-width: 78ch; margin: 0 0 18px;
}
.note--block strong { color: var(--ink); font-weight: 600; }

/* Sits in a .cards grid alongside real cards, so a withheld figure occupies
   the space its number will occupy rather than leaving a hole. */
.gate { background: var(--surface-2); padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 6px; }
.gate--locked { border-left: 3px solid var(--line); }
.gate--soon { border-left: 3px solid var(--accent-bright); }
.gate__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.gate__name { font-size: 13.5px; font-weight: 600; }
.gate__answers { font-family: var(--serif); font-size: 13px; color: var(--muted); margin: 0; }
.gate__bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; margin-top: 4px; }
.gate__bar span { display: block; height: 100%; background: var(--accent-bright); }
.gate__meta { font-family: var(--mono); font-size: 11px; color: var(--muted); margin: 0; }
.gate__meta strong { color: var(--ink); font-weight: 500; }
.gate__why { font-family: var(--serif); font-size: 12.5px; color: var(--muted); margin: 4px 0 0; font-style: italic; }

/* A gate outside a .cards grid still needs the grid's frame around it. */
.gates { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 3px; overflow: hidden; margin-top: 14px; }

/* Horizontal histogram. CSS widths rather than SVG: seven categorical rows
   with a text label and a value on each is a table with one graphical column,
   and it stays legible when the viewport is narrow, which a fixed viewBox
   does not. Still server-rendered and still no charting library. */
.bars { display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 3px; overflow: hidden; }
.bar { display: grid; grid-template-columns: 130px 1fr 120px; align-items: center; gap: 14px; background: var(--surface); padding: 10px 16px; }
.bar__label { font-size: 13px; font-weight: 500; }
.bar__track { background: var(--surface-2); height: 18px; border-radius: 2px; overflow: hidden; }
.bar__fill { display: block; height: 100%; background: var(--accent-bright); min-width: 2px; }
.bar__value { font-size: 12.5px; color: var(--muted); text-align: right; }

/* Further back than we have been watching. Muted and struck through rather
   than empty, so it cannot be misread as "no machine is this old". */
.bar--unobservable { background: var(--surface-2); }
.bar--unobservable .bar__label { color: var(--muted); }
.bar--unobservable .bar__track { background: repeating-linear-gradient(135deg, var(--line-soft) 0 6px, transparent 6px 12px); }
.bar--unobservable .bar__value { font-family: var(--sans); font-size: 11.5px; font-style: italic; }

/* An age we do not know. Hatched, full width, and captioned as off-scale. */
.bar--censored { margin-top: 1px; border: 1px solid var(--line); border-radius: 3px; }
.bar--censored .bar__fill { width: 100%; background: repeating-linear-gradient(135deg, var(--line) 0 5px, var(--line-soft) 5px 10px); }

@media (max-width: 640px) {
  .bar { grid-template-columns: 96px 1fr; row-gap: 4px; }
  .bar__value { grid-column: 2; text-align: left; }
}

footer { border-top: 1px solid var(--line); margin-top: 40px; padding-top: 18px; font-family: var(--mono); font-size: 11px; color: var(--muted); }

@media (max-width: 640px) {
  .topbar__inner { flex-wrap: wrap; padding: 10px 16px; gap: 12px; }
  main { padding: 22px 16px 60px; }
  h1 { font-size: 22px; }
}

/* The topbar on a phone: the brand and one button naming the page, with the
   nav, the admin links, View as and Sign out in a drawer beneath. Five
   wrapped rows of links in a sticky bar used to cover two thirds of every
   screen. Without scripts the drawer simply stays open. */
@media (max-width: 640px) {
  .topbar__inner { padding: 0 16px; gap: 0 12px; min-height: 54px; }
  .topbar__menu {
    display: inline-flex; align-items: center; gap: 8px; margin-left: auto; min-height: 40px; padding: 0 12px;
    font-size: 14px; font-weight: 600; color: var(--ink); background: var(--surface);
    border: 1px solid var(--line); border-radius: 3px;
  }
  .topbar__menu svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
  .topbar--open .topbar__menu { background: var(--surface-2); }
  .topbar__drawer {
    display: flex; flex-direction: column; flex-basis: 100%; gap: 14px; padding: 4px 0 16px;
    max-height: calc(100vh - 60px); overflow-y: auto;
  }
  .js .topbar__drawer { display: none; }
  .js .topbar--open .topbar__drawer { display: flex; }
  .nav { flex-direction: column; gap: 0; flex: none; }
  .nav a { padding: 12px 2px; font-size: 15px; border-bottom: 1px solid var(--line-soft); }
  .nav a.active { color: var(--accent); font-weight: 600; border-bottom-color: var(--line-soft); }
  /* Admin links sit below a gap, apart from what every member sees. */
  .nav__sep { display: block; height: 14px; border-bottom: 1px solid var(--line); }
  .topbar__user { flex-wrap: wrap; gap: 10px 12px; font-size: 13px; }
  /* .topbar__user form sets display: inline, which would win over .viewas alone. */
  .topbar__user form.viewas { display: flex; flex-basis: 100%; }
  /* Scoped up a level: the base .viewas select rule comes later in this file. */
  .topbar__user .viewas select { flex: 1; min-height: 40px; max-width: none; font-size: 14px; }
  .topbar__user button { min-height: 38px; padding: 6px 16px; font-size: 13px; }
}

/* Cards and tables on a phone, on every page. Cards go two to a row - one per
   row made four summary numbers fill a screen. Tables become stacked entries:
   the first cell is the entry's title, the rest run beneath it as "Column
   value" pairs, labelled by wwwroot/js/tables.js (which also marks the table
   .stackable, so without scripts it scrolls sideways as it always did).
   The heading row goes, so a sortable table gets a "Sort by" picker instead. */
.sortpick { display: none; }
@media (max-width: 640px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card { padding: 11px 12px 13px; }
  .card__name { font-size: 13px; }
  .card__sub { font-size: 11.5px; }
  .card__big { font-size: 20px; margin-top: 6px; }

  .scroller--stacked { overflow: visible; }
  table.stackable, table.stackable tbody { display: block; }
  table.stackable thead { display: none; }
  table.stackable caption { display: block; }
  table.stackable tbody tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 1px 12px; padding: 8px 12px; border-bottom: 1px solid var(--line-soft); }
  table.stackable tbody tr:last-child { border-bottom: 0; }
  table.stackable tbody td { display: inline; padding: 0; border: 0; text-align: left; white-space: normal; font-size: 12.5px; }
  /* Codes and figures are nowrap in a table cell; in an entry a long stock
     number or run note must wrap, or it pushes the page sideways. */
  table.stackable .code, table.stackable .num { white-space: normal; overflow-wrap: anywhere; }
  /* Past the first 40 entries a phone shows a button instead (tables.js). */
  table.stackable.is-capped tr.is-rest { display: none; }
  /* The row display above would otherwise beat the hidden attribute - the
     dealer page's "Other" brands are hidden rows until asked for. */
  table.stackable [hidden] { display: none !important; }
  table.stackable tbody td:first-child { flex-basis: 100%; font-size: 13.5px; font-weight: 600; }
  table.stackable tbody td:empty { display: none; }
  table.stackable td[data-label]::before {
    content: attr(data-label); margin-right: 5px;
    font-family: var(--sans); font-size: 11px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--muted);
  }
  .sortpick { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: 13px; color: var(--muted); }
  .sortpick select { flex: 1; min-height: 38px; }
  .showall { display: block; width: 100%; margin: 8px 0 0; min-height: 40px; }
  .chip { font-size: 11px; }
  .flag { font-size: 11px; }
  /* Two donuts side by side, not two screens of ring. */
  .mix__pies { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .donut { padding: 10px 10px 12px; }
  .donut svg { max-width: 150px; }
  table.stackable .chip { white-space: normal; overflow-wrap: anywhere; }
  .field label, .req__meta dt { font-size: 11px; }
}
.showall { display: none; }

/* Today's dealers grouped by market (admin). A wide screen ignores the groups:
   the wrappers are display: contents, so the cards are the grid's own items
   again, in their original order. */
.mktgroup, .mktgroup__cards { display: contents; }
.mktgroup__head { display: none; }
@media (max-width: 640px) {
  .mktgroups { display: block; background: none; border: 0; overflow: visible; }
  .mktgroup { display: block; margin-bottom: 8px; border: 1px solid var(--line); border-radius: 3px; background: var(--surface); overflow: hidden; }
  .mktgroup__head {
    display: flex; width: 100%; min-height: 50px; align-items: baseline; gap: 10px; padding: 13px 14px;
    border: 0; border-radius: 0; background: none; text-align: left; color: var(--ink);
  }
  .mktgroup__name { font-weight: 600; font-size: 14.5px; flex: 1; }
  .mktgroup__sum { font-size: 12px; color: var(--muted); white-space: nowrap; }
  .mktgroup__head::after { content: "+"; font-family: var(--mono); font-size: 16px; color: var(--accent); margin-left: 4px; }
  .mktgroup__head[aria-expanded="true"]::after { content: "\2212"; }
  .mktgroup__cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; background: var(--line); border-top: 1px solid var(--line); }
  .js .mktgroup:not(.is-open) .mktgroup__cards { display: none; }
  .mktgroups > .card { border: 1px solid var(--line); border-radius: 3px; }
  .mktregion { display: block; margin: 16px 2px 8px; font-size: 12.5px; font-weight: 600; color: var(--muted); }
  .mktregion:first-child { margin-top: 0; }
}

/* Footnotes: a dagger in the text, the note at the foot of the page (or of
   the tour's screen). The mark is padded out so a thumb can hit it. */
.fnref, .fnback {
  display: inline-block; min-width: 18px; padding: 0 3px; margin-left: 2px; text-align: center;
  font-family: var(--serif); font-size: 13px; font-weight: 600; line-height: 1; letter-spacing: 0;
  color: var(--accent); text-decoration: none; vertical-align: super;
}
.fnback { margin: 0 4px 0 0; vertical-align: baseline; }
.footnotes { border-top: 1px solid var(--line); margin-top: 36px; padding-top: 14px; }
.footnotes p, .tour__foot { font-family: var(--serif); font-size: 13.5px; line-height: 1.55; color: var(--muted); margin: 0 0 8px; max-width: 76ch; }
.tour__foot { border-top: 1px dashed var(--line); padding-top: 12px; margin: 4px 0 18px; }
.footnotes p:target, .tour__foot:target { background: var(--surface-2); outline: 1px solid var(--line); }
@media (max-width: 640px) { .fnref { padding: 6px 7px; margin: -6px -4px -6px 0; } }
.filters__toggle { display: none; }
@media (max-width: 640px) {
  .filters__toggle { display: block; width: 100%; min-height: 42px; text-align: left; font-weight: 600; }
  .filters--folds:not(.filters--open) > :not(.filters__toggle) { display: none; }
  .filters--folds .filters__toggle::after { content: " +"; float: right; font-family: var(--mono); color: var(--accent); }
  .filters--open .filters__toggle::after { content: " 2"; }
  .filters--folds.filters--open > .field { flex: 1 1 140px; }
  .filters--folds.filters--open input, .filters--folds.filters--open select { width: 100%; }
}

/* ---------- accounts ---------- */

/* Sign-in sits alone on the page with no nav to balance it, so it gets a
   column narrow enough to read as a single task rather than a form on a
   dashboard. */
.auth { max-width: 380px; margin: 40px auto; }
.auth h1 { margin-bottom: 14px; }
.auth .filters { flex-direction: column; align-items: stretch; }
.auth .field, .auth input { width: 100%; }
.auth .btn { text-align: center; }

/* The signed-in identity, pushed to the far end of the topbar. .nav already
   carries flex:1, so this needs no margin of its own. */
/* Theme picker: three icon buttons joined into one control, quiet enough to
   sit in either header. Hidden until _ThemeHead's script marks the page
   theme-js, because without scripts the buttons could not do anything. */
.theme { display: none; margin-left: auto; border: 1px solid var(--line); border-radius: 3px; overflow: hidden; flex: none; }
.theme-js .theme { display: inline-flex; }
.theme button {
  display: grid; place-items: center; width: 28px; height: 26px; padding: 0;
  border: 0; border-radius: 0; background: var(--surface); color: var(--muted);
}
.theme button + button { border-left: 1px solid var(--line); }
.theme button:hover { color: var(--ink); background: var(--surface-2); }
.theme button[aria-pressed="true"] { color: var(--accent); background: var(--surface-2); }
/* Not on phones (owner's call, 2026-09-24): the header there has room for the
   brand and Sign in and little else, and a phone already follows the system
   theme. A choice saved on the device still applies. */
@media (max-width: 600px) { .theme-js .theme { display: none; } }
.theme svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

.topbar__user { display: flex; align-items: center; gap: 12px; font-size: 12.5px; color: var(--muted); }
.topbar__user strong { color: var(--ink); font-weight: 600; }
.topbar__user form { display: inline; }
.topbar__user button {
  font-size: 12.5px; padding: 3px 9px; color: var(--muted);
}

/* A member's market, named in the page lede so it is never a mystery which
   dealers the numbers cover. */
.scope { font-size: 12.5px; color: var(--muted); }
.scope strong { color: var(--ink); font-weight: 600; }

/* Admin forms are denser than filter bars and want labelled rows rather than a
   single line of controls. */
.stack { display: flex; flex-direction: column; gap: 12px; max-width: 460px; }
.stack .field { width: 100%; }
.stack .field input, .stack .field select, .stack .field textarea { width: 100%; }
.stack__actions { display: flex; gap: 10px; align-items: center; }

/* Dealer membership is a long list of checkboxes; two columns keeps a
   six-state market from running off the screen. */
.checks { columns: 2; column-gap: 24px; }
.checks label {
  display: flex; align-items: baseline; gap: 7px; padding: 3px 0;
  font-size: 13.5px; break-inside: avoid;
}
.checks input[type=checkbox] { accent-color: var(--accent-bright); }

@media (max-width: 640px) {
  .checks { columns: 1; }
}

/* The request form is a real form, not a two-field sign-in, so it gets a
   wider column than .auth while keeping the same centered single-task feel. */
.auth--wide { max-width: 560px; }
.auth--wide .stack { max-width: none; }
.auth--wide .lede { font-size: 15px; margin-bottom: 20px; }
.auth .field .note { font-size: 12px; text-transform: none; letter-spacing: 0; font-weight: 400; }

/* Honeypot. Moved out of sight rather than display:none, because some bots
   skip hidden inputs and the point is that they fill this one in. Kept out of
   the tab order and the accessibility tree by the markup. */
.offscreen {
  position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden;
}

/* Review queue: the corroboration signals next to a request. */
.signals { display: flex; flex-wrap: wrap; gap: 5px; }
.req { display: grid; gap: 14px; grid-template-columns: 1fr; }
.req__meta { display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; font-size: 13.5px; }
.req__meta dt { font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); align-self: baseline; }
.req__meta dd { margin: 0; }
.req__quote { font-family: var(--serif); font-size: 14.5px; color: var(--ink); margin: 0; white-space: pre-wrap; }

/* ---------- landing ---------- */

/* The signed-out front page. Same tokens as the app so the two read as one
   thing, but its own shell: no nav, no filters, one loud element. */

.landing { display: flex; flex-direction: column; min-height: 100vh; }

/* Sticky, like the app's topbar: on a page this long, Sign in and Request
   access should never be more than a glance away. */
.landing__bar {
  position: sticky; top: 0; z-index: 20;
  border-bottom: 1px solid var(--line); background: var(--surface);
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; padding: 0 24px; min-height: 60px;
}
.landing__bar a:not(.brand) { font-size: 13.5px; font-weight: 500; color: var(--muted); text-decoration: none; }
.landing__bar a:not(.brand):hover { color: var(--ink); }

.landing__main { flex: 1; max-width: 1060px; width: 100%; margin: 0 auto; padding: 0 24px; }

/* Hero: the three questions, then the dealer page's own 30-day chart in a
   frame. One column, because the chart is the product and needs the width -
   squeezed beside the headline, its two scales would be unreadable. */
.hero { padding: 64px 0 52px; }
.hero__say { max-width: 780px; }
.hero h1 {
  font-size: clamp(32px, 4.6vw, 50px); font-weight: 700; letter-spacing: -0.032em;
  line-height: 1.06; margin: 0 0 22px;
}
/* One question per line, always - the three beats are the design. */
.hero h1 span { display: block; }
.hero__lede {
  font-family: var(--serif); font-size: 17px; line-height: 1.58;
  color: var(--muted); margin: 0 0 28px; max-width: 62ch;
}
.hero__acts { display: flex; gap: 10px; flex-wrap: wrap; }
.hero__acts .btn { padding: 10px 20px; font-size: 14px; }
.hero__who { font-size: 12.5px; color: var(--muted); margin: 16px 0 0; }

/* The chart's frame: the tour's frame, so the two read as the same product. */
.hero__chart {
  margin: 44px 0 0; padding: 18px 20px 6px;
  border: 1px solid var(--ink); border-radius: 3px; background: var(--ground);
  box-shadow: 8px 8px 0 var(--line-soft);
}
.hero__cap { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; font-size: 14.5px; margin: 0 0 14px; }
.hero__cap strong { font-weight: 700; letter-spacing: -0.01em; }
.hero__cap-note { font-size: 12px; color: var(--muted); }
.hero__chart .lot30__legend { margin-bottom: 8px; }
/* Name the gesture the device actually has. */
.for-touch { display: none; }
@media (hover: none) { .for-hover { display: none; } .for-touch { display: inline; } }

/* Three things it knows. Hairline-separated columns rather than cards: the
   points are peers, not objects, and boxing them would compete with the tag. */
.knows {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 36px;
  border-top: 1px solid var(--line); padding: 40px 0 44px;
}
.knows__item h2 {
  font-size: 15px; font-weight: 600; letter-spacing: -0.012em; text-transform: none;
  border: 0; padding: 0; margin: 0 0 8px; display: block;
}
.knows__item p { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0; }

.plain { border-top: 1px solid var(--line); padding: 32px 0 56px; }
.plain h2 {
  font-size: 15px; font-weight: 600; letter-spacing: -0.012em; text-transform: none;
  border: 0; padding: 0; margin: 0 0 8px; display: block;
}
.plain p { font-family: var(--serif); font-size: 15px; line-height: 1.6; color: var(--muted); margin: 0; max-width: 72ch; }

.landing__foot {
  border-top: 1px solid var(--line); background: var(--surface);
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 18px 24px; font-size: 12.5px; color: var(--muted);
}

/* In-page links sit between the brand and Sign in. They are a table of
   contents for one long page, so they are quieter than Sign in, which is the
   only way into the product. */
.landing__nav { display: flex; gap: 22px; flex: 1; justify-content: center; }
.landing__signin { font-weight: 600 !important; color: var(--ink) !important; }
.landing__end { display: flex; align-items: center; gap: 16px; }
.landing__end .theme { margin-left: 0; }

/* A long-form section: sentence-case heading at a size between the hero and
   the three peers above, then a serif lede. Deliberately not the app's
   uppercase ruled h2 - that style belongs to the app, and the tour uses it. */
.sect { border-top: 1px solid var(--line); padding: 56px 0 8px; margin: 0; }
.sect__head { max-width: 62ch; margin-bottom: 28px; }
.sect__title {
  font-size: clamp(24px, 2.8vw, 30px); font-weight: 700; letter-spacing: -0.026em; line-height: 1.12;
  text-transform: none; border: 0; padding: 0; margin: 0 0 10px; display: block;
}
.sect__lede { font-family: var(--serif); font-size: 16.5px; line-height: 1.6; color: var(--muted); margin: 0; }

/* The tour. A window onto the app: its own copy of the topbar, where the nav
   links ARE the tabs, above a screen that uses the app's own cards, tables and
   bars. The frame is the only new object; everything inside it is the real
   product's styling, so the tour cannot drift into a prettier fiction. */
.tour {
  border: 1px solid var(--ink); border-radius: 3px; background: var(--ground);
  box-shadow: 8px 8px 0 var(--line-soft); overflow: hidden;
}
.tour__bar {
  display: flex; align-items: center; gap: 28px; min-height: 52px; padding: 0 20px;
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.tour__bar .brand { font-size: 14.5px; flex: none; }
/* position: relative makes the bar the tabs' offsetParent, which landing.js
   relies on to scroll the chosen tab into view sideways. */
.tour__tabs { display: flex; gap: 20px; overflow-x: auto; scrollbar-width: none; position: relative; }
.tour__tabs::-webkit-scrollbar { display: none; }
.tour__tabs [role="tab"] {
  font: inherit; font-size: 13.5px; font-weight: 500; color: var(--muted);
  background: none; border: 0; border-radius: 0; border-bottom: 2px solid transparent;
  padding: 15px 0 13px; white-space: nowrap; cursor: pointer;
}
.tour__tabs [role="tab"]:hover { color: var(--ink); background: none; }
.tour__tabs [role="tab"][aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent-bright); }

.tour__screen { padding: 26px 24px 8px; }
/* Without scripts every panel shows, stacked, and the tabs (which would do
   nothing) are hidden. The script adds .tour--js and takes over. */
.tour:not(.tour--js) .tour__tabs { display: none; }
.tour:not(.tour--js) .tour__panel + .tour__panel { border-top: 1px dashed var(--line); margin-top: 28px; padding-top: 28px; }
.tour__panel[hidden] { display: none; }

/* The app's own h1 and h2, at the app's sizes. Heading LEVELS are h3/h4 so the
   page keeps one h1 and a sane outline; only the look is borrowed. */
.tour__h1 { font-size: 23px; font-weight: 700; letter-spacing: -0.022em; margin: 0 0 4px; text-wrap: balance; }
.tour__lede { font-family: var(--serif); font-size: 15px; color: var(--muted); margin: 0 0 18px; max-width: 70ch; }
.tour__h2 {
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  margin: 26px 0 12px; padding-bottom: 9px; border-bottom: 2px solid var(--ink);
}
.tour__panel .cards { margin-bottom: 4px; }
/* Six cards in the app's auto-fit grid leave two empty cells at this width;
   three columns fill two rows exactly. */
.tour__panel .cards--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tour__steps { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; }
.tour__explain {
  font-family: var(--serif); font-size: 15px; line-height: 1.6; color: var(--ink);
  margin: 18px 0 20px; max-width: 68ch; padding-left: 14px; border-left: 2px solid var(--accent-bright);
}
.tour__fine { margin: 0; padding: 11px 20px; font-size: 12px; color: var(--muted); background: var(--surface); border-top: 1px solid var(--line); }
.tour .bar { grid-template-columns: 120px 1fr 150px; }

/* The nudge: a quiet line at the right of the tour's bar saying this is live.
   Hidden by the script the moment the visitor clicks anything in the tour. */
.tour__hint {
  margin: 0 0 0 auto; flex: none; display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--accent); white-space: nowrap;
}
.tour__hint svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.tour:not(.tour--js) .tour__hint { display: none; }
/* [hidden] loses to the display above, so say it outright. */
.tour__hint[hidden] { display: none; }

/* The one dealer card that opens a page. It carries a visible cue, and until
   the visitor has clicked anything it pulses three times and then stops -
   the page's single piece of motion nobody asked for, spent on the one thing
   a visitor would otherwise not know is there. */
.tour__open { position: relative; }
.tour__open-cue { font-size: 12px; font-weight: 600; color: var(--accent); margin-top: 8px; text-decoration: underline; text-underline-offset: 3px; }
.tour__open:hover .tour__open-cue { text-decoration-thickness: 2px; }
.tour:not(.tour--js) .tour__open-cue { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .tour--js:not(.tour--used) .tour__open { animation: tour-nudge 1.8s ease-out 1.5s 3; }
}
@keyframes tour-nudge {
  0%   { box-shadow: inset 0 0 0 0 var(--accent-bright); }
  25%  { box-shadow: inset 0 0 0 2px var(--accent-bright); }
  100% { box-shadow: inset 0 0 0 2px transparent; }
}

.tour__crumb { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }
.tour__more { font-size: 13px; margin: 10px 0 0; }
.tour__h2 { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; }
.tour__h2 .note { font-family: var(--mono); font-size: 11px; font-weight: 400; letter-spacing: 0.03em; text-transform: none; color: var(--muted); }
.tour__gap { margin-top: 12px; }
.tour .mix__pies { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tour .donut svg { max-width: 170px; }
.tour__h1:focus { outline: none; }

/* What it measures: a definition list in two columns with hairlines, because
   each is a term and its meaning - not eight products to shop between. */
.measures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; margin: 0; }
.measures__item { border-top: 1px solid var(--line); padding: 16px 0 18px; display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 16px; }
.measures dt { font-weight: 600; font-size: 15px; letter-spacing: -0.01em; }
.measures dd { margin: 0; font-family: var(--serif); font-size: 15px; line-height: 1.55; color: var(--muted); }

/* How it works IS a sequence - read, record, compare, report - so it is the
   one place on the page that is numbered. */
.how { list-style: none; counter-reset: how; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; }
.how li { counter-increment: how; border-top: 2px solid var(--ink); padding-top: 14px; }
.how li::before { content: counter(how); display: block; font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--accent); margin-bottom: 8px; }
.how h3 { font-size: 15px; font-weight: 600; letter-spacing: -0.012em; margin: 0 0 6px; }
.how p { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0; }

.faq { max-width: 76ch; padding-bottom: 40px; }
.faq__item { border-top: 1px solid var(--line); }
.faq__item summary {
  cursor: pointer; list-style: none; padding: 16px 32px 16px 0; position: relative;
  font-weight: 600; font-size: 15.5px; letter-spacing: -0.01em;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "+"; position: absolute; right: 4px; top: 13px;
  font-family: var(--mono); font-size: 18px; font-weight: 400; color: var(--accent);
}
.faq__item[open] summary::after { content: "\2212"; }
.faq__item summary:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.faq__item p { font-family: var(--serif); font-size: 15.5px; line-height: 1.62; color: var(--muted); margin: 0 0 18px; max-width: 68ch; }

.close { border-top: 1px solid var(--line); padding: 48px 0 64px; text-align: left; }
.close h2 {
  font-size: clamp(24px, 2.8vw, 30px); font-weight: 700; letter-spacing: -0.026em; text-transform: none;
  border: 0; padding: 0; margin: 0 0 10px; display: block;
}
.close p { font-family: var(--serif); font-size: 16.5px; line-height: 1.6; color: var(--muted); margin: 0 0 22px; max-width: 60ch; }
.close .btn { padding: 10px 20px; font-size: 14px; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

@media (max-width: 860px) {
  .hero { padding: 44px 0 36px; }
  .hero__chart { padding: 14px 12px 4px; margin-top: 32px; }
  .knows { grid-template-columns: 1fr; gap: 28px; }
  .landing__nav { display: none; }
  .measures { grid-template-columns: 1fr; }
  .how { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tour__bar .brand { display: none; }
  .tour__hint { display: none; }
  .tour__screen { padding: 20px 14px 6px; }
  .tour__panel .cards--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .measures__item { grid-template-columns: 1fr; gap: 4px; }
  .how { grid-template-columns: 1fr; gap: 24px; }
  .tour .bar { grid-template-columns: 96px 1fr; }
  .tour .bar__value { grid-column: 2; text-align: left; }
}

/* ---------- the front page on a phone ----------
   Most people will meet the site here first, from a link on a phone, so this
   is not a shrunken desktop: the headline keeps its three lines, the chart
   fits the screen, and the tour's tables become stacked entries. */
@media (max-width: 600px) {
  .landing__bar { padding: 0 16px; gap: 12px; min-height: 54px; }
  .landing__main { padding: 0 16px; }

  /* Sized to the width so each question stays on its own line - broken
     mid-phrase, three beats read as six ragged ones. */
  .hero { padding: 30px 0 26px; }
  .hero h1 { font-size: 6.3vw; line-height: 1.14; letter-spacing: -0.03em; margin-bottom: 16px; }
  .hero h1 span { white-space: nowrap; }
  .hero__lede { font-size: 16px; line-height: 1.55; margin-bottom: 22px; }
  .hero__acts .btn { flex: 1 1 0; text-align: center; }
  .hero__who { font-size: 12px; }
  .hero__chart { margin-top: 28px; padding: 12px 10px 4px; box-shadow: 4px 4px 0 var(--line-soft); }
  .hero__cap { font-size: 13.5px; margin-bottom: 10px; }

  .knows { padding: 28px 0 32px; gap: 20px; }
  .sect { padding-top: 40px; }
  .sect__head { margin-bottom: 20px; }
  .sect__title { font-size: 24px; }
  .sect__lede { font-size: 15.5px; }
  .close { padding: 36px 0 44px; }
  .close .btn { display: block; text-align: center; }
  .landing__foot { flex-direction: column; align-items: flex-start; gap: 6px; padding: 16px; }

  /* The tour. */
  .tour { box-shadow: 4px 4px 0 var(--line-soft); }
  .tour__bar { padding: 0 12px; min-height: 48px; }
  /* A fade at the right edge says the row of tabs goes on; the padding keeps
     the last tab clear of it once scrolled to the end. */
  .tour__tabs { gap: 18px; padding-right: 28px; -webkit-mask-image: linear-gradient(to right, #000 82%, transparent); mask-image: linear-gradient(to right, #000 82%, transparent); }
  .tour__screen { padding: 16px 12px 4px; }
  .tour__h1 { font-size: 20px; }
  .tour__lede { font-size: 14.5px; margin-bottom: 14px; }
  .tour__h2 { margin-top: 22px; flex-wrap: wrap; row-gap: 2px; }
  .tour__explain { font-size: 14.5px; margin: 16px 0 18px; }
  .tour .cards, .tour__panel .cards--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tour .card { padding: 11px 12px 13px; }
  .tour .card__name { font-size: 12.5px; }
  .tour .card__sub { font-size: 11px; }
  .tour .card__big { font-size: 20px; margin-top: 6px; }

  .tour__steps { font-weight: 400; }
}

/* Dealer map. Leaflet brings its own stylesheet; this is only the frame
   around it and the key underneath, so the page still reads as this site
   rather than as a map embedded in one. */
.map {
  height: 620px; margin: 18px 0 10px;
  border: 1px solid var(--line); border-radius: 3px; background: var(--surface-2);

  /* position+z-index together open a STACKING CONTEXT, and that is the whole
     point of these two lines - not the stacking order they appear to set.

     Leaflet's stylesheet numbers its own furniture from 200 (tile pane) to
     1000 (the corner control anchors). The topbar is z-index 10 and is the
     only z-index this file otherwise declares, so every one of those beat it
     and the map scrolled UNDER the sticky header while painting OVER it -
     OpenStreetMap place names straight across the nav links.

     Raising the topbar instead is the usual fix and is a race: it has to stay
     ahead of a number Leaflet owns, in a library we load unpinned-ish from a
     CDN, and a plugin or a future release only has to out-bid it once. Here
     the entire 200-1000 range is sealed inside this box, which then sits at 0
     against the topbar's 10. Nothing Leaflet can number escapes.

     Popups are unaffected: .leaflet-container already sets overflow:hidden,
     so they were clipped to this box before this rule existed. */
  position: relative; z-index: 0;
}

/* Leaflet paints its own white ground and controls, which sit badly against
   the dark theme. Toning them down is cheaper than theming the tiles. */
.map .leaflet-tile-pane { filter: saturate(0.85); }
.map .leaflet-container { background: var(--surface-2); font: inherit; }
.map .leaflet-popup-content { font-size: 13px; line-height: 1.5; }

.map-stats { font-size: 13.5px; color: var(--muted); margin: 0 0 4px; }
.map-key { font-size: 12.5px; color: var(--muted); margin: 0 0 18px; }
.map-key__ring {
  display: inline-block; width: 11px; height: 11px; border-radius: 50%;
  vertical-align: middle; background: transparent; border: 2.5px solid #b4232a;
}

@media (max-width: 860px) {
  .map { height: 420px; }
}

/* Dealer picker on a market. The flat checklist was written for six dealers
   and now carries well over a hundred, so it is grouped by state with a
   type-to-filter above it. */
.picker { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; flex-wrap: wrap; }
.picker__search {
  flex: 1 1 280px; max-width: 420px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: 3px;
  background: var(--surface); color: var(--ink); font: inherit; font-size: 13.5px;
}
.picker__count { font-size: 12.5px; }

.picker__group { margin: 0 0 18px; }
.picker__group[hidden] { display: none; }

.picker__state {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 12.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 6px; padding-bottom: 5px;
  border-bottom: 1px solid var(--line-soft);
}

/* Three columns here rather than the two .checks uses elsewhere: these rows
   are short and there are a great many of them. */
.picker__group .checks { columns: 3; }
.picker__group .checks label[hidden] { display: none; }

@media (max-width: 980px) { .picker__group .checks { columns: 2; } }
@media (max-width: 640px) { .picker__group .checks { columns: 1; } }

/* Market legend under the dealer map. Doubles as the filter, so the items are
   buttons rather than list rows. */
.legend {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 18px; padding: 0;
}
.legend__item {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; font: inherit; font-size: 12.5px;
  border: 1px solid var(--line); border-radius: 3px;
  background: var(--surface); color: var(--muted);
  cursor: pointer; text-align: left;
}
.legend__item:hover { color: var(--ink); border-color: var(--muted); }
.legend__item.is-on { color: var(--ink); border-color: var(--accent-bright); background: var(--surface-2); }
.legend__item .code { font-size: 11.5px; opacity: 0.8; }

.legend__swatch {
  width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid rgba(0, 0, 0, 0.25);
}
.legend__swatch--all {
  background: linear-gradient(135deg, #2e9e5b 0%, #3d7fd6 50%, #d98b2b 100%);
}

/* "View as" — an admin reading the site through one market's scope. */
.viewas { display: inline-flex; align-items: center; gap: 6px; }
.viewas__label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
.viewas select {
  font: inherit; font-size: 12.5px; padding: 3px 6px;
  border: 1px solid var(--line); border-radius: 3px;
  background: var(--surface); color: var(--ink); max-width: 220px;
}

/* Deliberately loud. Every figure below it is narrowed while it is showing,
   and a scoped number read as a total is a mistake that leaves no trace. */
.previewbar {
  background: var(--accent); color: #fff;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
}
.previewbar__inner {
  max-width: 1180px; margin: 0 auto; padding: 9px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  font-size: 13px; flex-wrap: wrap;
}
.previewbar strong { font-weight: 600; }
.previewbar__fine { display: block; opacity: 0.82; font-size: 12px; margin-top: 2px; }
.previewbar button {
  font: inherit; font-size: 12.5px; padding: 4px 11px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.55); border-radius: 3px;
  background: transparent; color: #fff;
}
.previewbar button:hover { background: rgba(255, 255, 255, 0.14); }

@media (max-width: 640px) {
  .viewas__label { display: none; }
  .previewbar__inner { padding: 9px 16px; }
}

/* Admin markets, grouped by region (Pages/Admin/Markets.cshtml). */
.region { margin: 0 0 18px; border-top: 1px solid var(--line); padding-top: 10px; }
.region__head { cursor: pointer; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding: 4px 0 10px; list-style: none; }
.region__head::-webkit-details-marker { display: none; }
.region__head::before { content: "+"; font-family: var(--mono); color: var(--accent); width: 1ch; }
.region[open] > .region__head::before { content: "\2212"; }
.region__name { font-weight: 600; font-size: 17px; }
.region__actions { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 10px; }
form.inline { display: inline; margin-left: 6px; }
.mktregion { display: none; }

/* Runs: dealer health (Pages/Runs.cshtml). */
.healthbar { display: flex; flex-wrap: wrap; gap: 6px 22px; margin: 0 0 14px; font-size: 14px; color: var(--muted); }
.healthbar strong { color: var(--ink); font-size: 18px; font-weight: 600; margin-right: 3px; }
.rundealers summary { cursor: pointer; font-size: 12.5px; color: var(--accent); margin-top: 4px; }

/* Error and status pages (Pages/Status.cshtml, Pages/Error.cshtml). */
.status { max-width: 560px; padding: 48px 0 24px; }
.status__code { font-family: var(--mono); font-size: 13px; color: var(--muted); margin: 0 0 6px; }
.status .stack__actions { margin-top: 18px; }

/* ---------- public documents + site footer ---------- */

/* Terms, Privacy, About our crawler. A reading column, not a dashboard: one
   measure of serif text, sentence-case headings rather than the app's ruled
   uppercase section labels, which read as data tables to come. */
.doc { max-width: 72ch; margin: 8px auto 0; }
.doc h1 { margin-bottom: 4px; }
.doc__meta { font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin: 0 0 28px; }
.doc__lede { font-family: var(--serif); font-size: 17px; color: var(--muted); margin: 6px 0 24px; }
.doc h2 {
  font-size: 16px; font-weight: 600; letter-spacing: -0.012em; text-transform: none;
  border: 0; padding: 0; margin: 32px 0 8px; display: block;
}
.doc p, .doc li { font-family: var(--serif); font-size: 15.5px; line-height: 1.65; }
.doc p { margin: 0 0 14px; }
.doc ul { margin: 0 0 14px; padding-left: 22px; }
.doc li { margin-bottom: 6px; }
.doc code, .doc__code { font-family: var(--mono); font-size: 13px; }
.doc__code {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 3px;
  padding: 12px 14px; margin: 0 0 14px; white-space: pre-wrap; overflow-wrap: anywhere;
}

/* The agree box on Request Access: a whole-row label, so the text is a hit
   target too, with the box aligned to the first line when it wraps. */
.agree { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; line-height: 1.45; }
.agree input { margin: 3px 0 0; flex: none; accent-color: var(--accent-bright); width: 16px; height: 16px; }

.faq__more { font-size: 14px; color: var(--muted); margin: -24px 0 40px; }

/* Every page's last line: who runs this and where the rules are. The bare
   `footer` rule above styles the app's price caveat; this is a different
   element and overrides it. */
.sitefoot {
  max-width: 1240px; margin: 0 auto; padding: 18px 20px 28px;
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px 24px;
  font-family: var(--sans); font-size: 12.5px; color: var(--muted);
}
/* The landing body is a flex column, where auto side margins shrink an item
   to its content - so the landing's footer drops them and spans the page. */
.landing__foot.sitefoot { max-width: none; width: 100%; margin: 0; padding: 18px 24px; background: var(--surface); }
.sitefoot__links { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.sitefoot__links a { color: var(--muted); text-decoration: none; }
.sitefoot__links a:hover { color: var(--ink); text-decoration: underline; }

@media (max-width: 640px) {
  .sitefoot { padding: 16px 16px 24px; flex-direction: column; align-items: flex-start; }
  .landing__foot.sitefoot { padding: 16px; }
  .sitefoot__links a { padding: 6px 0; }
  .doc p, .doc li { font-size: 15px; }
}

/* Unconfirmed applications under the review queue (Admin/Requests). A
   <details> whose summary reads as the page's section labels do, so a closed
   one looks like a heading with a count rather than a widget. */
.unconfirmed summary {
  cursor: pointer; list-style: none;
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  padding-bottom: 10px; margin-bottom: 14px; border-bottom: 2px solid var(--ink);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px;
}
.unconfirmed summary::-webkit-details-marker { display: none; }
.unconfirmed summary::before { content: "+"; font-family: var(--mono); color: var(--muted); }
.unconfirmed details[open] summary::before { content: "\2212"; }
.unconfirmed summary .note { font-family: var(--mono); font-size: 11px; font-weight: 400; letter-spacing: 0.03em; text-transform: none; color: var(--muted); }
.unconfirmed summary:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.unconf td { vertical-align: top; }
.unconf .note { margin-top: 4px; max-width: 34ch; }
.unconf__acts { display: flex; flex-direction: column; gap: 6px; align-items: stretch; white-space: nowrap; }
.unconf__acts .btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* A request in the review queue at phone width. Grid items default to
   min-width: auto, so the longest thing in the card - a dealer <select> whose
   widest option sets its width, a long address, a nowrap chip - pushed the
   whole card past the screen edge. Zero minimums, and chips that may wrap. */
.req { grid-template-columns: minmax(0, 1fr); }
.req > *, .req__meta dd { min-width: 0; }
.req__meta dd { overflow-wrap: anywhere; }
.req .stack select { max-width: 100%; }
@media (max-width: 640px) {
  .req .chip, .unconf .chip { white-space: normal; overflow-wrap: anywhere; }
  /* Repeated here, after the base .req__meta rule: the earlier phone rule
     that says the same loses to it on source order and never applied. */
  .req__meta dt { font-size: 11px; }
}

/* Dealer page: what the dealer's site says about fees (Pages/Dealer.cshtml). */
.disclosure { margin: -16px 0 28px; padding: 12px 14px; border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: 3px; background: var(--surface); max-width: 760px; }
.disclosure__label { font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); margin-right: 6px; }
.disclosure .chip { margin-right: 4px; }
.disclosure__quote { margin: 10px 0 6px; padding: 0 0 0 12px; border-left: 2px solid var(--line); font-family: var(--serif); font-size: 15px; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.disclosure .note { margin: 4px 0 0; }
@media (max-width: 640px) {
  .disclosure .chip { white-space: normal; }
  .disclosure__label { font-size: 11px; }
}
