/* SC01Check
   ------------------------------------------------------------------
   The product is a decoder, so the option code is the design motif:
   a mono chip with a hairline rule, sitting beside its plain meaning.
   Everything else stays quiet so the chips carry the page.
*/

/* Fonts are linked from _head.php, NOT imported here.
   An @import cannot be discovered until this file has downloaded and parsed,
   which serialises HTML -> site.css -> font CSS -> font files. Linking them
   in the document head lets the font CSS start in parallel with this file. */

:root {
  /* Surfaces. Three depths rather than one flat white, so cards can sit ON
     something instead of floating in a void. */
  --paper:  #ffffff;
  --wash:   #f7f8fa;
  --sunk:   #eff2f6;

  --ink:    #0d1117;
  /* DARKENED FROM #5b6472. Most of the small print on this site is
     .small.muted at 13.5px, and the old value measured 5.63:1 against the
     wash — technically AA and genuinely hard to read at that size. This is
     7.55:1, AAA, and keeps the same blue-grey cast rather than going flat
     grey. Only the light theme changed; the dark theme's slate was always
     fine against a near-black page. */
  --slate:  #49515d;
  --faint:  #8b93a1;
  --rule:   #e4e8ef;
  --hair:   #eef1f6;

  /* Semantic accents. Four hues on a cool-to-warm arc, each with a text
     colour, a tint for surfaces and an edge for borders. Constrained to four
     on purpose: more would read as decoration rather than meaning. */
  --verify:      #0a5c4c;   /* brand, and "yes this is real"   */
  --verify-bg:   #e8f4f0;
  --verify-edge: #b7dcd1;

  --charge:      #0b5c74;   /* Supercharging, anything electrical */
  --charge-bg:   #e6f3f8;
  --charge-edge: #b2d9e6;

  --drive:       #3b3aa8;   /* autonomy, software, FSD */
  --drive-bg:    #ecedfb;
  --drive-edge:  #c6c7f0;

  --warn:        #8a5200;   /* battery wear, caution */
  --warn-bg:     #fcf3e5;
  --warn-edge:   #eed7b0;

  --deny:        #a3231c;
  --deny-bg:     #fbeceb;
  --deny-edge:   #f1c4c1;

  --focus:  #0a5c4c;

  --sans: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --r:  8px;
  --r-lg: 14px;

  /* Layered rather than a single blur — closer to how light actually falls,
     and the reason cards read as lifted instead of outlined. */
  --shadow-sm: 0 1px 2px rgba(13,17,23,.04);
  --shadow:    0 1px 2px rgba(13,17,23,.04), 0 4px 10px -3px rgba(13,17,23,.07),
               0 14px 28px -14px rgba(13,17,23,.12);
  --shadow-lg: 0 2px 4px rgba(13,17,23,.04), 0 8px 20px -6px rgba(13,17,23,.10),
               0 28px 56px -22px rgba(13,17,23,.18);
}

/* The attribute must beat component styles. [hidden] is only display:none in
   the UA stylesheet, so any rule setting an explicit display silently defeats
   it -- learned when a hidden button rendered visible and inert. */
[hidden] { display: none !important; }


[data-theme='dark'] {
  --paper:  #0e1014;
  --wash:   #15181f;
  --sunk:   #1b1f28;

  --ink:    #eceef3;
  --slate:  #98a0af;
  --faint:  #6d7583;
  --rule:   #262c37;
  --hair:   #1e232c;

  --verify:      #56d5b3;
  --verify-bg:   #0f2621;
  --verify-edge: #1e5045;

  --charge:      #55c6e8;
  --charge-bg:   #0c2430;
  --charge-edge: #1b4d63;

  --drive:       #9a99f5;
  --drive-bg:    #1a1a33;
  --drive-edge:  #37356b;

  --warn:        #e5aa57;
  --warn-bg:     #2a2010;
  --warn-edge:   #574121;

  --deny:        #f08076;
  --deny-bg:     #2b1614;
  --deny-edge:   #5d2c28;

  --focus:  #56d5b3;

  --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
  --shadow:    0 1px 2px rgba(0,0,0,.4), 0 4px 10px -3px rgba(0,0,0,.45),
               0 14px 28px -14px rgba(0,0,0,.6);
  --shadow-lg: 0 2px 4px rgba(0,0,0,.4), 0 8px 20px -6px rgba(0,0,0,.5),
               0 28px 56px -22px rgba(0,0,0,.7);
}

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

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

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

a { color: inherit; text-decoration-color: var(--rule); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 3px;
}

.wrap { width: min(1080px, calc(100vw - 36px)); margin: 0 auto; }
.narrow { width: min(620px, calc(100vw - 36px)); margin: 0 auto; }

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

.top {
  border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(8px);
}
.top-in { display: flex; align-items: center; gap: 20px; height: 62px; }

.brand {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -.02em;
  text-decoration: none;
  display: inline-flex; align-items: baseline; gap: 1px;
}
.brand .sig { color: var(--verify); }

.nav { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.nav a {
  padding: 7px 11px; border-radius: var(--r); text-decoration: none;
  color: var(--slate); font-size: 14.5px; font-weight: 500;
}
.nav a:hover { background: var(--wash); color: var(--ink); }
.nav a.here { color: var(--ink); }

.theme-btn {
  border: 1px solid var(--rule); background: transparent; color: var(--slate);
  width: 34px; height: 34px; border-radius: var(--r); cursor: pointer;
  display: grid; place-items: center; padding: 0;
}
.theme-btn:hover { color: var(--ink); border-color: var(--slate); }
.theme-btn svg { width: 16px; height: 16px; }
[data-theme='dark'] .icon-moon,
:root:not([data-theme='dark']) .icon-sun { display: none; }

/* ------------------------------------------------------------------ type */

h1, h2, h3 { line-height: 1.15; letter-spacing: -.025em; margin: 0; font-weight: 600; }
h1 { font-size: clamp(2rem, 5.2vw, 3.3rem); font-weight: 600; }
h2 { font-size: clamp(1.4rem, 3vw, 1.95rem); }
h3 { font-size: 1.05rem; }

/* SECTION MARKERS.
   Uppercase letter-spaced mono, stacked above a heading, is the single most
   common section device on the web right now and the thing that made this
   site read as a sibling of another in the same niche. Same markup, told
   differently: lower case, a heavier weight, and a short rule running out
   from the left so the label sits ON the line rather than floating above
   it. Costs nothing, changes the rhythm of every page. */
.eyebrow {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: .01em; text-transform: none; color: var(--slate);
}
.eyebrow::before {
  content: ""; flex: none;
  width: 14px; height: 2px; border-radius: 2px;
  background: var(--verify);
}
.lede { font-size: 1.12rem; color: var(--slate); max-width: 62ch; }
.muted { color: var(--slate); }
.small { font-size: 13.5px; }

/* --------------------------------------------------- signature: code chip */

.code {
  font-family: var(--mono); font-size: 13px; font-weight: 500;
  border: 1px solid var(--rule); border-radius: 4px;
  padding: 2px 7px; white-space: nowrap;
  background: var(--paper); color: var(--ink);
  display: inline-block;
}
.code .d { color: var(--slate); }
.code.is-verify { border-color: var(--verify); color: var(--verify); background: var(--verify-bg); }
.code.is-warn   { border-color: var(--warn);   color: var(--warn);   background: var(--warn-bg); }
.code.is-deny   { border-color: var(--deny);   color: var(--deny);   background: var(--deny-bg); }

/* readout: the decode panel, styled like an inspection printout */
.readout {
  border: 1px solid var(--rule); border-radius: 10px;
  background: var(--paper); box-shadow: var(--shadow); overflow: hidden;
}
.readout-head {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 16px; border-bottom: 1px solid var(--rule);
  background: var(--wash);
  font-family: var(--mono); font-size: 12.5px; color: var(--slate);
}
.readout-head .vin { color: var(--ink); letter-spacing: .04em; }
.row {
  display: grid; grid-template-columns: 92px minmax(0, 1fr) auto;
  gap: 14px; align-items: center;
  padding: 11px 16px; border-bottom: 1px solid var(--rule);
}
.row:last-child { border-bottom: 0; }
.row .what { font-size: 14.5px; }
.row .note { font-size: 12.5px; color: var(--slate); }
.tag {
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; padding: 3px 7px; border-radius: 3px;
}
.tag.ok   { background: var(--verify-bg); color: var(--verify); }
.tag.no   { background: var(--deny-bg);   color: var(--deny); }

/* ------------------------------------------------------- warranty card --
   Tinted with --charge, the blue already in the palette. The greens and
   ambers on this page work because each hue means one thing consistently;
   a fifth colour invented for this block would say "another colour" where
   the system says "another kind of fact".

   The tint is on the CARD, and the rows inside stay on paper, so the block
   reads as one thing with parts rather than a stack of blue boxes. */
.warranty-card {
  background: linear-gradient(180deg, var(--charge-bg) 0%, var(--paper) 58%);
  border-color: var(--charge-edge);
}
.warranty-card .eyebrow-ic { color: var(--charge); }

.warranty-item {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 10px 12px;
}
/* A hairline in the hue on the leading edge — enough to tie the rows to
   the card without repeating the tint four times. */
.warranty-item { border-left: 3px solid var(--charge-edge); }


/* ---------------------------------------------------------------- garage --
   A thumbnail is too small to recognise a car by, and too useful to make
   people open the report just to check which one it is. Hovering grows it.

   It grows RIGHTWARD AND IN PLACE, from transform-origin left centre. The
   card around the table clips its children, so a picture that expanded in
   every direction would be sliced off at the left edge — which looks like a
   rendering fault rather than a feature. Growing inward keeps it whole.

   Transform only: no layout property changes, so the row does not move and
   the table does not reflow under the cursor. */
td.veh-thumb img {
  transition: transform .16s ease, box-shadow .16s ease;
  transform-origin: left center;
  position: relative;
  z-index: 1;
}
td.veh-thumb:hover img,
td.veh-thumb:focus-within img {
  transform: scale(2.6);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .28);
  z-index: 40;
}
/* The cell needs to sit above its neighbours or the enlarged picture slides
   under the next row's content. */
td.veh-thumb:hover, td.veh-thumb:focus-within { position: relative; z-index: 40; }

@media (prefers-reduced-motion: reduce) {
  td.veh-thumb img { transition: none; }
}

/* No hover on a touch screen, and a picture that grows under a fingertip is
   a picture you cannot see. */
@media (hover: none) {
  td.veh-thumb:hover img { transform: none; box-shadow: none; }
}


.tag.mid  { background: var(--warn-bg);   color: var(--warn); }
.tag.flat { background: var(--wash);      color: var(--slate); }

/* stagger the readout in on load; the one piece of motion on the page */
.stagger > * { opacity: 0; transform: translateY(6px); animation: rise .5s ease forwards; }
.stagger > *:nth-child(1) { animation-delay: .05s; }
.stagger > *:nth-child(2) { animation-delay: .13s; }
.stagger > *:nth-child(3) { animation-delay: .21s; }
.stagger > *:nth-child(4) { animation-delay: .29s; }
.stagger > *:nth-child(5) { animation-delay: .37s; }
@keyframes rise { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .stagger > * { animation: none; opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- layout */

section { padding: 68px 0; }
section + section { border-top: 1px solid var(--rule); }
.hero { padding: 76px 0 64px; }
.hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 52px; align-items: center; }
@media (max-width: 860px) { .hero-grid { grid-template-columns: minmax(0, 1fr); gap: 34px; } }

.stack > * + * { margin-top: 16px; }
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
/* minmax(0, 1fr), not 1fr.
   A bare 1fr has a MINIMUM of min-content, so one long unbroken string in a
   card — a marketplace listing title, a URL — forces its column wider than
   its share and shoves the whole grid sideways. The page then reads as
   off-centre with its right edge cut off, which is exactly what the for-sale
   board was doing. minmax(0, …) lets a column be narrower than its contents
   and hand the problem to the text instead. */
.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }

/* ---------------------------------------------------- packed columns --
   A GRID MAKES EVERY ROW AS TALL AS ITS TALLEST CARD. On an admin page
   where one card is a six-row table and its neighbour is three buttons,
   that is a screen of white space — the short card is padded out to match
   whatever happens to sit beside it.

   CSS columns pack instead: each card takes its own height and the next
   one starts immediately below. Nothing is stretched and no gaps are left.

   The trade is READING ORDER — cards fill the first column top to bottom,
   then the second, rather than left-right in pairs. For a dashboard of
   independent panels that is no loss; it would be wrong for anything
   meant to be read in sequence. */
.card-cols { column-count: 2; column-gap: 18px; }
.card-cols > * {
  break-inside: avoid;          /* never split a card across columns */
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;     /* older WebKit */
  margin: 0 0 18px;
  display: inline-block;        /* stops a card straddling the break */
  width: 100%;
}
@media (max-width: 900px) { .card-cols { column-count: 1; } }
.grid4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }

/* Grid and flex children default to min-width:auto, which is the same trap
   one level down. */
.grid2 > *, .grid3 > *, .grid4 > * { min-width: 0; }

/* And the text itself has to be willing to break, or it just overflows the
   card instead of the grid.

   `break-word`, NOT `anywhere` — the difference is not cosmetic. `anywhere`
   also shrinks an element's MIN-CONTENT size, which told every table inside
   a card that its columns could be one character wide. A nowrap URL then
   took the whole row and the other columns collapsed into vertical
   letter-per-line strips. `break-word` breaks long words when it has to
   without offering to make everything narrower. */
.card { overflow-wrap: break-word; }
@media (max-width: 860px) { .grid2, .grid3, .grid4 { grid-template-columns: minmax(0, 1fr); } }

.card {
  border: 1px solid var(--rule); border-radius: 10px; padding: 22px;
  background: var(--paper);
}
.card.wash { background: var(--wash); }

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-weight: 500; font-size: 15px;
  padding: 11px 18px; border-radius: var(--r); cursor: pointer;
  border: 1px solid var(--ink); background: var(--ink); color: var(--paper);
  text-decoration: none;
}
.btn:hover { opacity: .88; }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn.ghost:hover { border-color: var(--ink); opacity: 1; }
.btn.go { background: var(--verify); border-color: var(--verify); color: #fff; }
[data-theme='dark'] .btn.go { color: #06120f; }
.btn[disabled] { opacity: .45; cursor: not-allowed; }
.btn.wide { width: 100%; }

/* ----------------------------------------------------------------- forms */

label { display: block; font-size: 13.5px; font-weight: 500; margin-bottom: 6px; }
/* Every text-like control, not just the three original types. A field
   added later as type=number or type=url fell through to the browser
   default and rendered as a bare white box next to properly styled
   siblings -- which is exactly what happened on the settings page and
   the VIN import form. Listing the types is the fix; a bare `input`
   selector would also catch checkboxes and radios. */
input[type=text], input[type=email], input[type=password],
input[type=number], input[type=url], input[type=tel], input[type=search],
input[type=date], input[type=datetime-local], textarea, select {
  width: 100%; font: inherit; padding: 11px 13px;
  border: 1px solid var(--rule); border-radius: var(--r);
  background: var(--paper); color: var(--ink);
}
/* Checkboxes and radios must keep their intrinsic size. */
input[type=checkbox], input[type=radio] { width: auto; }
select { appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 51%, calc(100% - 13px) 51%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
  padding-right: 34px; }
input:focus { border-color: var(--focus); }
.vin-input {
  font-family: var(--mono); letter-spacing: .12em; text-transform: uppercase;
  font-size: 16px;
}
.field + .field { margin-top: 14px; }
.hint { font-size: 12.5px; color: var(--slate); margin-top: 6px; }

/* ----------------------------------------------------------------- flash */

.flash { padding: 12px 15px; border-radius: var(--r); margin-bottom: 18px; font-size: 14.5px; border: 1px solid; }
.flash.info { background: var(--wash); border-color: var(--rule); }
.flash.ok   { background: var(--verify-bg); border-color: var(--verify); color: var(--verify); }
.flash.err  { background: var(--deny-bg); border-color: var(--deny); color: var(--deny); }

/* ------------------------------------------------------------------ misc */

.meter { display: flex; gap: 18px; flex-wrap: wrap; align-items: baseline; }
.meter b { font-family: var(--mono); font-size: 21px; font-weight: 600; }

table.data { width: 100%; border-collapse: collapse; font-size: 14.5px; }
table.data th {
  text-align: left; font-family: var(--mono); font-size: 11.5px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--slate);
  font-weight: 500; padding: 9px 10px; border-bottom: 1px solid var(--rule);
}
table.data td { padding: 10px; border-bottom: 1px solid var(--rule); vertical-align: top; }

/* A monospace cell holds one indivisible thing — a VIN, a key, a price, a
   mileage. Wrapping one splits a figure across two lines mid-digit, which
   is the worst possible place to break something meant to be read at a
   glance. Admin tables already scroll sideways when they need to, so
   refusing to wrap costs nothing. */
table.data td.mono, table.data th.mono { white-space: nowrap; }

/* Opt-out for the few mono cells that hold something long and genuinely
   breakable, like a URL. */
table.data td.mono.wrap { white-space: normal; word-break: break-all; }

/* A HEADER NEVER WRAPS. It is two or three words, and a column squeezed
   thin turns it into a vertical strip of letters, which is what happened to
   "Where" and "Last" on the agent page. */
table.data th { white-space: nowrap; }

/* Give a wrapping cell something to wrap INSIDE. max-width on a td is
   ignored under the default auto table layout, so the URL column simply
   grew until it owned the row. */
table.data td.wrap { max-width: 340px; }
table.data tr:last-child td { border-bottom: 0; }
table.data td.mono { font-family: var(--mono); font-size: 13px; }

.price { font-family: var(--mono); font-size: 27px; font-weight: 600; letter-spacing: -.02em; }
.per { font-size: 12.5px; color: var(--slate); }

.foot { border-top: 1px solid var(--rule); padding: 34px 0; color: var(--slate); font-size: 13.5px; }
.foot a { text-decoration: none; }

.pill {
  display: inline-block; font-family: var(--mono); font-size: 11.5px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--verify);
  background: var(--verify-bg); border-radius: 3px; padding: 3px 8px;
}

/* ------------------------------------------------------------------ admin */

.adminbar {
  border-bottom: 1px solid var(--rule);
  background: var(--wash);
}
.adminbar-in { display: flex; align-items: center; gap: 6px; height: 46px; }
.adminbar a {
  padding: 6px 11px; border-radius: var(--r); text-decoration: none;
  color: var(--slate); font-size: 14px; font-weight: 500;
}
.adminbar a:hover { background: var(--paper); color: var(--ink); }
.adminbar a.here { color: var(--ink); background: var(--paper); border: 1px solid var(--rule); }

select {
  /* appearance:none strips the native widget INCLUDING its background, so
     without these the control falls back to the browser default -- white on
     white text in dark mode, which is what it was doing. Matches the text
     inputs above deliberately: a form should not have two kinds of field. */
  width: 100%; font: inherit; padding: 11px 13px;
  border: 1px solid var(--rule); border-radius: var(--r);
  background-color: var(--paper); color: var(--ink);
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--slate) 50%),
                    linear-gradient(135deg, var(--slate) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px !important;
}
select:focus { border-color: var(--focus); outline: none; }

/* Arriving here from the Watch button. :target does the whole job in CSS -- the
   ring fades after a few seconds so it draws the eye once and then gets out of
   the way, rather than sitting there permanently as decoration. */
.actions:target { scroll-margin-top: 90px; }
.actions:target .field select {
  border-color: var(--verify);
  box-shadow: 0 0 0 3px var(--verify-bg);
  animation: sc01-settle 4s ease-out forwards;
}
@keyframes sc01-settle {
  0%, 55% { box-shadow: 0 0 0 3px var(--verify-bg); border-color: var(--verify); }
  100%    { box-shadow: 0 0 0 0 transparent;        border-color: var(--rule); }
}
@media (prefers-reduced-motion: reduce) {
  /* Keep the highlight, drop the movement. */
  .actions:target .field select { animation: none; }
}

/* --- action bar under a report -------------------------------------------
   Every control on one line, equal height, wrapping together on a phone. The
   buttons and the select were previously in separate flex rows at different
   heights, which is what made it look unfinished. */
.actions {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
  margin-top: 24px;
}
.actions form { display: flex; gap: 10px; align-items: flex-end; margin: 0; }
.actions .btn {
  height: 44px; padding: 0 20px; display: inline-flex;
  align-items: center; justify-content: center; white-space: nowrap;
  /* Floor, not a fixed width: forcing every button to match the longest would
     leave "Save" swimming in space. This just stops the short ones looking
     like an afterthought next to the long ones. */
  min-width: 124px;
}
/* Save belongs to the select next to it, not to the row of peer buttons, so it
   is exempt from the floor. Giving it the same 124px pushed the row onto two
   lines for no benefit. */
.actions .field + .btn { min-width: auto; padding: 0 16px; }
.actions select { height: 44px; padding-top: 0; padding-bottom: 0; min-width: 196px; }
.actions .field { margin: 0; }
.actions .field label { display: block; margin-bottom: 5px; }

@media (max-width: 640px) {
  /* One per line beats two-and-a-half per line. */
  .actions, .actions form { width: 100%; flex-direction: column; align-items: stretch; }
  .actions .btn, .actions select { width: 100%; }
}
textarea { font-family: var(--sans); }
details > summary { list-style: none; }
details > summary::-webkit-details-marker { display: none; }
details > summary::before { content: '▸ '; color: var(--slate); }
details[open] > summary::before { content: '▾ '; }


/* ---------------------------------------------------------------- icons */

.ic { flex: none; vertical-align: -.16em; }

.brand { gap: 9px; align-items: center; }
.brand span { letter-spacing: -.02em; }

.readout-head { gap: 9px; }
.readout-head .ic { color: var(--slate); }

/* section marks in card eyebrows */
/* The icon variant carries its own marker, so it takes the rule but not a
   second one — the icon IS the left-hand mark. */
.eyebrow-ic {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: .01em; text-transform: none; color: var(--slate);
  margin-bottom: 14px;
}
.eyebrow-ic svg { color: var(--verify); }

/* ------------------------------------------------------- battery gauge */

.gauge { display: flex; align-items: center; gap: 13px; }
.gauge-txt { display: flex; flex-direction: column; line-height: 1.25; }
.gauge-txt b { font-family: var(--mono); font-size: 19px; font-weight: 600; letter-spacing: -.02em; }
.gauge-txt span { font-size: 12px; color: var(--slate); }

/* ---------------------------------------------------- verdict emphasis */

.verdict {
  display: flex; align-items: center; gap: 11px;
  padding: 14px 16px; border-bottom: 1px solid var(--rule);
}
.verdict .badge {
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; flex: none;
}
.verdict .badge.ok   { background: var(--verify-bg); color: var(--verify); }
.verdict .badge.no   { background: var(--deny-bg);   color: var(--deny); }
.verdict .badge.mid  { background: var(--warn-bg);   color: var(--warn); }
.verdict .badge.flat { background: var(--wash);      color: var(--slate); }
.verdict .headline { font-size: 16px; font-weight: 600; letter-spacing: -.015em; }

/* feature strip on the landing page */
.strip { display: flex; gap: 10px; align-items: center; }
.strip .ic { color: var(--verify); }


/* ======================================================================
   MOBILE
   The people using this are standing next to a car with a phone, often
   one-handed and in daylight. Tap targets get bigger, tables stop being
   tables, and nothing is allowed to overflow the viewport.
   ====================================================================== */

/* Nothing may force a horizontal scrollbar on the document. */
html, body { max-width: 100%; overflow-x: hidden; }

/* Long VINs, tokens and URLs must wrap rather than push the layout wide. */
.code, .mono, table.data td.mono { overflow-wrap: anywhere; }

/* Tables that must keep their shape scroll inside their own box. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0 -2px;
}

@media (max-width: 900px) {
  /* Two across on tablets rather than jumping straight to one. */
  .grid4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {

  body { font-size: 15.5px; }

  /* --- header: let the nav scroll sideways instead of wrapping to
         three ragged lines. Brand and theme button stay put. --- */
  .top-in { height: auto; min-height: 58px; padding: 8px 0; gap: 10px; }
  .brand { font-size: 15.5px; }
  .nav {
    gap: 2px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex: 1;
    justify-content: flex-end;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { padding: 9px 9px; font-size: 14px; white-space: nowrap; }

  /* --- the admin bar had no mobile rules at all, so it overflowed and the
         last items were simply unreachable. Same treatment as .nav above,
         which is the behaviour worth copying. --- */
  .adminbar-in {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    height: auto;
    min-height: 44px;
    gap: 2px;
    justify-content: flex-start;
  }
  .adminbar-in::-webkit-scrollbar { display: none; }
  /* Without flex:none the links compress instead of scrolling. */
  .adminbar-in > * { flex: none; white-space: nowrap; }
  .adminbar a { padding: 8px 10px; font-size: 13.5px; }
  /* "Back to site" is pushed right by margin-left:auto on desktop. In a
     scrolling row that leaves a long empty gap to scroll past. */
  .adminbar-in a[style*="margin-left"] { margin-left: 6px !important; }
  .theme-btn { flex: none; width: 38px; height: 38px; }

  section { padding: 40px 0; }
  .hero { padding: 34px 0 30px; }
  .grid2, .grid3, .grid4 { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .card { padding: 17px; }

  /* --- readout rows: the tag was being squeezed against the text.
         Code and status share the top line, detail sits below. --- */
  .row {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "code tag" "body body";
    gap: 8px 10px;
    padding: 13px 14px;
  }
  .row > :nth-child(1) { grid-area: code; }
  .row > :nth-child(2) { grid-area: body; }
  .row > :nth-child(3) { grid-area: tag; justify-self: end; }
  .row .what { font-size: 15px; }

  .verdict { padding: 13px 14px; gap: 10px; flex-wrap: wrap; }
  .verdict .headline { font-size: 15.5px; }
  .verdict .badge { width: 30px; height: 30px; }

  .readout-head { padding: 10px 14px; font-size: 12px; }

  /* --- buttons: full width and thumb-sized --- */
  .btn { width: 100%; padding: 13px 18px; min-height: 46px; font-size: 15.5px; }
  .btn.ghost, .btn.go { width: 100%; }
  .nav .btn.go { width: auto; min-height: 0; padding: 8px 13px; font-size: 14px; }
  form .btn, .card .btn { width: 100%; }

  /* Any inline row of buttons becomes a stack. */
  section > .wrap > div[style*="display:flex"],
  .card > div[style*="display:flex"] { flex-direction: column; align-items: stretch; }

  /* min-width on flex children was forcing overflow at 360px. */
  [style*="min-width:280px"], [style*="min-width: 280px"],
  [style*="min-width:260px"], [style*="min-width: 260px"],
  [style*="min-width:250px"], [style*="min-width: 250px"],
  [style*="min-width:180px"], [style*="min-width: 180px"] { min-width: 0 !important; }

  input[type=text], input[type=email], input[type=password],
  input[type=number], input[type=url], input[type=tel], input[type=search],
  input[type=date], input[type=datetime-local], textarea, select {
    font-size: 16px;              /* under 16px iOS zooms the whole page */
    padding: 13px;
  }
  .vin-input { letter-spacing: .06em; font-size: 16px; }

  /* --- data tables become stacked records. Fixed px column widths and
         three columns do not survive a 360px screen. --- */
  table.data.stack, table.data.stack thead, table.data.stack tbody,
  table.data.stack tr, table.data.stack th, table.data.stack td {
    display: block;
    width: auto !important;
  }
  table.data.stack thead { display: none; }
  table.data.stack tr {
    border-bottom: 1px solid var(--rule);
    padding: 12px 2px;
  }
  table.data.stack tr:last-child { border-bottom: 0; }
  table.data.stack td {
    border: 0;
    padding: 3px 0;
  }
  /* Stacked rows: EVERY cell left-aligns and wraps -- the desktop actions
     cell carries nowrap + right-align inline, which on a 360px card shoved
     every button after the first off the right edge. Hide/Restore/Delete
     were there all along, just outside the screen. */
  table.data.stack td {
    white-space: normal !important;
    text-align: left !important;
  }
  table.data.stack td form {
    display: inline-block;
    margin: 6px 8px 0 0;
  }
  /* The thumbnail rides alongside the VIN on a phone rather than sitting on
     a row of its own — stacked, a lone picture reads as a broken cell. */
  /* Stacked on a phone the cell is full width, so the note has room to
     wrap and truncating it there would hide text for no reason. */
  table.data.stack td[data-label="VIN"] div span[title] {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
  }
  table.data.stack td[data-label="VIN"] div { flex-wrap: wrap; }

  table.data.stack td.veh-thumb {
    float: left;
    padding: 0 12px 0 0 !important;
    width: auto !important;
  }
  table.data.stack tr::after { content: ''; display: block; clear: both; }
  table.data.stack td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--slate);
    margin-bottom: 2px;
  }

  /* Key/value tables keep two columns but drop the fixed width. */
  table.data th[style*="width:40%"] { width: 42% !important; }

  .gauge { gap: 10px; }
  .gauge svg { width: 108px; }
  .price { font-size: 23px; }
  .meter { gap: 14px; }
  .foot > .wrap { flex-direction: column; align-items: flex-start !important; gap: 10px; }
  .foot span[style*="text-align:right"] { text-align: left !important; margin-left: 0 !important; }
}

/* ---------------------------------------------------------- filter bar --
   The for-sale board's filters. Eight controls in a wrapping flex row is
   fine at desktop width and a mess on a phone -- fields end up different
   widths on every line and the checkboxes land wherever there is a gap.
   A grid keeps every control the same width and lets the count per row
   change cleanly with the viewport. */
.filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  align-items: end;
}
.filter-grid .field { margin: 0; min-width: 0; }
/* Selects now inherit the shared control styling; this only tightens the
   padding for a dense filter row and pins 16px so iOS does not zoom. */
.filter-select { padding: 9px 11px; font-size: 16px; }
/* Toggles and buttons are their own full-width rows, so they never end up
   squeezed into a leftover grid cell. */
.filter-toggles {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 12px;
}
.filter-toggles label {
  display: flex;
  gap: 8px;
  align-items: center;
  cursor: pointer;
}
.filter-actions { display: flex; gap: 10px; margin-top: 12px; }

@media (max-width: 640px) {
  /* Two across on a phone: any narrower and the labels wrap mid-word. */
  .filter-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .filter-toggles { gap: 10px; }
  .filter-toggles label { flex: 1 1 100%; }
  .filter-actions { flex-direction: column; }
  .filter-actions .btn { width: 100%; }
}

/* Admin data tables: sideways swipe on small screens, exactly like the nav.
   The wrapper is inert on desktop (content fits, no scrollbar); on mobile the
   table keeps its desktop layout and the thumb does the panning. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media (max-width: 700px) {
  .table-scroll > table.data { min-width: 640px; }
}

/* Tesla API spend grid: four across on desktop, 2x2 on phones. The old
   inline 1fr x4 forced four ~85px columns on a 360px screen. */
.spend-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 640px) {
  .spend-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 16px; }
}

@media (max-width: 400px) {
  .wrap, .narrow { width: calc(100vw - 24px); }
  h1 { font-size: 1.72rem; }
  .nav a { padding: 8px 7px; font-size: 13.5px; }
  .card { padding: 14px; }
}




/* unreviewed shared-IP alerts, shown on every admin page */
.adminbadge {
  display: inline-block; min-width: 17px; padding: 1px 5px;
  border-radius: 9px; background: var(--deny); color: #fff;
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  line-height: 1.5; text-align: center; vertical-align: 1px;
}


/* ======================================================================
   VISUAL REFRESH
   The light theme was white cards on a white page separated by hairlines —
   correct, but flat. Everything below adds depth and meaning-bearing colour
   without turning a money/trust product into a carnival: four hues, used
   systematically, at low saturation.
   ====================================================================== */

body { background: var(--wash); }

/* Sections alternate paper/wash so the page has rhythm instead of one
   continuous scroll of white. */
section { background: var(--paper); position: relative; }
section:nth-of-type(even) { background: var(--wash); }
section + section { border-top: 0; }

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

.hero {
  background:
    radial-gradient(1100px 420px at 12% -8%, var(--verify-bg) 0%, transparent 62%),
    radial-gradient(900px 380px at 92% 4%, var(--charge-bg) 0%, transparent 58%),
    var(--paper);
  border-bottom: 1px solid var(--rule);
  overflow: hidden;
}
/* A faint engineering grid — a spec sheet, which is what the product is. */
.hero::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    linear-gradient(var(--rule) 1px, transparent 1px),
    linear-gradient(90deg, var(--rule) 1px, transparent 1px);
  background-size: 46px 46px;
  opacity: .28;
  -webkit-mask-image: radial-gradient(720px 340px at 50% 0%, #000 0%, transparent 78%);
          mask-image: radial-gradient(720px 340px at 50% 0%, #000 0%, transparent 78%);
  pointer-events: none;
}
.hero > * { position: relative; }

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

.card {
  border-radius: var(--r-lg);
  border-color: var(--rule);
  box-shadow: var(--shadow-sm);
  transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease;
}
.card.wash { background: var(--wash); border-color: var(--hair); box-shadow: none; }
section:nth-of-type(even) .card.wash { background: var(--paper); }

/* Only cards that are links should lift — a static panel that moves is noise. */
a.card:hover {
  box-shadow: var(--shadow);
  border-color: var(--verify-edge);
  transform: translateY(-2px);
}

/* ------------------------------------------------------ featured cards --
   A featured car glows blue AT REST, so it reads as promoted while the eye
   is scanning rather than only once the cursor lands on it.

   Blue because --charge is the only free hue here: green already means
   "your cursor is on this", amber means wear and red means a problem. A
   featured car is none of those — it is simply worth a look, and it must
   not borrow a colour that already means something else.

   HOVER MUST STILL WIN, and it does not come for free: a.card:hover sits
   EARLIER in this file and a.card.is-featured is the more specific
   selector, so the blue would have survived the cursor. Checked rather than
   assumed — the two-class hover rule below restores it.

   Two states, never both: blue says "we picked this", green says "you are
   on this", and a card showing both says neither clearly. */
a.card.is-featured {
  border-color: var(--charge-edge);
  box-shadow: 0 0 0 1px var(--charge-edge), 0 6px 18px -10px var(--charge);
}
a.card.is-featured:hover {
  border-color: var(--verify-edge);
  box-shadow: var(--shadow);
}

/* Tinted variants. The tint carries the meaning: cyan is electrical, indigo
   is software, amber is wear, verdigris is confirmed. */
.tint-charge { background: var(--charge-bg); border-color: var(--charge-edge); }
.tint-drive  { background: var(--drive-bg);  border-color: var(--drive-edge); }
.tint-power  { background: var(--warn-bg);   border-color: var(--warn-edge); }
.tint-verify { background: var(--verify-bg); border-color: var(--verify-edge); }
.tint-money  { background: var(--verify-bg); border-color: var(--verify-edge); }

.tint-charge .eyebrow, .tint-charge .eyebrow-ic { color: var(--charge); }
.tint-drive  .eyebrow, .tint-drive .eyebrow-ic  { color: var(--drive); }
.tint-power  .eyebrow, .tint-power .eyebrow-ic  { color: var(--warn); }
.tint-verify .eyebrow, .tint-verify .eyebrow-ic { color: var(--verify); }

/* --------------------------------------------------------- readouts --- */

.readout {
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  border-color: var(--rule);
  overflow: hidden;
}
/* A coloured cap identifies the panel before a word is read. */
.readout { border-top: 3px solid var(--rule); }
.readout.for-charge { border-top-color: var(--charge); }
.readout.for-drive  { border-top-color: var(--drive); }
.readout.for-power  { border-top-color: var(--warn); }

.readout-head {
  background: linear-gradient(var(--wash), var(--paper));
  border-bottom-color: var(--hair);
  letter-spacing: .14em;
}
.readout.for-charge .readout-head { background: linear-gradient(var(--charge-bg), var(--paper)); color: var(--charge); }
.readout.for-drive  .readout-head { background: linear-gradient(var(--drive-bg),  var(--paper)); color: var(--drive); }
.readout.for-charge .readout-head .ic { color: var(--charge); }
.readout.for-drive  .readout-head .ic { color: var(--drive); }

.row { border-bottom-color: var(--hair); }
.row:hover { background: var(--wash); }

/* ------------------------------------------------------ code chips ---- */

.code {
  border-radius: 5px;
  background: var(--wash);
  border-color: var(--rule);
  font-weight: 500;
}
/* Tint by family, so a Supercharging code and an Autopilot code are
   distinguishable at a glance in a long option list. */
.code.fam-sc { background: var(--charge-bg); border-color: var(--charge-edge); color: var(--charge); }
.code.fam-ap { background: var(--drive-bg);  border-color: var(--drive-edge);  color: var(--drive); }
.code.is-verify { background: var(--verify-bg); border-color: var(--verify-edge); color: var(--verify); }
.code.is-warn   { background: var(--warn-bg);   border-color: var(--warn-edge);   color: var(--warn); }
.code.is-deny   { background: var(--deny-bg);   border-color: var(--deny-edge);   color: var(--deny); }
.code .d { opacity: .55; }

/* ----------------------------------------------------------- tags ----- */

.tag {
  font-weight: 500;
  border: 1px solid transparent;
  /* Narrow table cells were splitting a tag across two lines mid-word. */
  white-space: nowrap;
}
.tag.ok   { border-color: var(--verify-edge); }
.tag.mid  { border-color: var(--warn-edge); }
.tag.no   { border-color: var(--deny-edge); }
.tag.flat { border-color: var(--rule); }

/* --------------------------------------------------------- verdict ---- */

.verdict { border-bottom-color: var(--hair); }
.verdict .badge { box-shadow: inset 0 0 0 1px currentColor; }
.verdict .badge.ok   { box-shadow: inset 0 0 0 1px var(--verify-edge); }
.verdict .badge.no   { box-shadow: inset 0 0 0 1px var(--deny-edge); }
.verdict .badge.mid  { box-shadow: inset 0 0 0 1px var(--warn-edge); }

/* --------------------------------------------------------- buttons ---- */

.btn {
  border-radius: var(--r);
  font-weight: 600;
  letter-spacing: -.005em;
  box-shadow: var(--shadow-sm);
  transition: transform .12s ease, box-shadow .18s ease, opacity .18s ease;
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow); opacity: 1; }
.btn:active { transform: translateY(0); box-shadow: var(--shadow-sm); }
.btn.go {
  background: linear-gradient(180deg, #0d6d5b, var(--verify));
  border-color: var(--verify);
}
[data-theme='dark'] .btn.go {
  background: linear-gradient(180deg, #62e0be, var(--verify));
}
.btn.ghost { background: var(--paper); box-shadow: var(--shadow-sm); }
.btn.ghost:hover { border-color: var(--verify); color: var(--verify); }

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

.top {
  /* Fallback first: a browser without color-mix() still gets a solid header
     rather than transparent text sitting on the scrolling content. */
  background: var(--paper);
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  border-bottom-color: var(--rule);
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .top { background: var(--paper); }
}
.nav a.here { color: var(--verify); }
.nav a:hover { background: var(--verify-bg); color: var(--verify); }

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

table.data th {
  background: var(--wash);
  color: var(--faint);
  border-bottom-color: var(--rule);
}
table.data td { border-bottom-color: var(--hair); }
table.data tbody tr:hover { background: var(--wash); }
.card table.data th:first-child { border-top-left-radius: var(--r); }

/* --------------------------------------------------------- pricing ---- */

.price { letter-spacing: -.03em; }
.pill {
  background: var(--verify-bg); color: var(--verify);
  border: 1px solid var(--verify-edge);
}

/* ----------------------------------------------------------- forms ---- */

input[type=text], input[type=email], input[type=password],
input[type=number], input[type=url], input[type=tel], input[type=search],
input[type=date], input[type=datetime-local], textarea, select {
  border-radius: var(--r);
  background: var(--paper);
  transition: border-color .15s ease, box-shadow .15s ease;
}
input:focus {
  border-color: var(--verify);
  box-shadow: 0 0 0 3px var(--verify-bg);
  outline: none;
}

/* ----------------------------------------------------------- flash ---- */

.flash { border-radius: var(--r); border-width: 1px; }
.flash.ok  { border-color: var(--verify-edge); }
.flash.err { border-color: var(--deny-edge); }

/* ------------------------------------------------------------ misc ---- */

.foot { background: var(--paper); border-top-color: var(--rule); }
.gauge-txt b { letter-spacing: -.02em; }
hr, .rule { border: 0; border-top: 1px solid var(--hair); }

@media (prefers-reduced-motion: reduce) {
  .btn, .card, a.card { transition: none; }
  .btn:hover, a.card:hover { transform: none; }
}

/* ------------------------------------------------- vehicle render ----- */

.shot {
  position: relative;
  margin-bottom: 20px;
  max-width: 100%;
  /* The CONTAINER defines the size, not the image. The compositor render is
     1440x810, and anything that stops the img's CSS applying -- a stale
     stylesheet, a blend-mode bug -- would otherwise let it lay out at its
     natural 1440px and burst off a phone screen. A fixed ratio box makes that
     impossible. */
  aspect-ratio: 16 / 9;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
  background:
    radial-gradient(680px 300px at 50% 120%, var(--verify-bg) 0%, transparent 70%),
    linear-gradient(var(--wash), var(--paper));
  box-shadow: var(--shadow);
}
.shot img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: 100%;
  object-fit: contain;
  /* The compositor renders on transparency; the wash behind shows through and
     the car appears to sit on a surface rather than float in a box. */
  mix-blend-mode: multiply;
}

/* Browsers without aspect-ratio fall back to intrinsic height, still capped. */
@supports not (aspect-ratio: 16 / 9) {
  .shot { aspect-ratio: auto; }
  .shot img { height: auto; }
}
[data-theme='dark'] .shot img { mix-blend-mode: normal; }
[data-theme='dark'] .shot {
  background: radial-gradient(680px 300px at 50% 120%, var(--verify-bg) 0%, transparent 70%),
              linear-gradient(var(--sunk), var(--wash));
}
.shot-note {
  position: absolute; left: 14px; bottom: 12px;
  font-size: 12px; color: var(--slate);
  background: color-mix(in srgb, var(--paper) 80%, transparent);
  border: 1px solid var(--hair);
  border-radius: 999px; padding: 4px 11px;
  backdrop-filter: blur(4px);
}
@media (max-width: 640px) {
  /* iOS Safari has a long-standing bug where mix-blend-mode on an image inside
     a border-radius + overflow:hidden box escapes the container and paints at
     natural size. The blend is decorative; correct layout is not. */
  .shot img { mix-blend-mode: normal; }

  /* Crop the compositor's generous empty margins so the car fills more of a
     smaller box, instead of a wide strip of background with a tiny car in it. */
  .shot { aspect-ratio: 3 / 2; }
  .shot img { object-fit: cover; transform: scale(1.08); }

  .shot-note {
    position: static; display: block; margin: 0 12px 12px;
    text-align: center; backdrop-filter: none;
  }
}

@media (max-width: 400px) {
  .shot { aspect-ratio: 4 / 3; }
  .shot img { transform: scale(1.12); }
}

/* ------------------------------------------------- render gallery ----- */

.shot-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin: -10px 0 20px;
}
.shot-strip figure {
  margin: 0;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  overflow: hidden;
  background: linear-gradient(var(--wash), var(--paper));
  text-align: center;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.shot-strip figure:hover { border-color: var(--ink); }
.shot-strip figure.active {
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--ink);
}
.shot-strip figure:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.shot-strip img {
  display: block; width: 100%; height: auto;
  mix-blend-mode: multiply;
}
[data-theme='dark'] .shot-strip img { mix-blend-mode: normal; }
[data-theme='dark'] .shot-strip figure { background: linear-gradient(var(--sunk), var(--wash)); }
.shot-strip figcaption {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--slate);
  padding: 6px 4px 8px; border-top: 1px solid var(--hair);
}
@media (max-width: 640px) {
  .shot-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --------------------------------------------- report header + share --- */

.rpt-head { display: flex; gap: 20px; align-items: flex-start; }
.rpt-head-main { flex: 1; min-width: 0; }
.rpt-head-side { flex: none; padding-top: 20px; }
.rpt-head-side .btn { width: auto; white-space: nowrap; }

@media (max-width: 640px) {
  .rpt-head { flex-direction: column; gap: 12px; }
  .rpt-head-side { padding-top: 0; width: 100%; }
  .rpt-head-side .btn { width: 100%; }
}

/* ------------------------------------------------ collapsible blocks --- */

details.fold { padding: 0; }
details.fold > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  cursor: pointer;
  list-style: none;          /* hide the default triangle */
  border-radius: var(--r-lg);
  user-select: none;
}
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary:hover { background: rgba(0,0,0,.02); }
[data-theme='dark'] details.fold > summary:hover { background: rgba(255,255,255,.03); }
details.fold[open] > summary { border-bottom: 1px solid var(--warn-edge); border-radius: var(--r-lg) var(--r-lg) 0 0; }

.fold-mark {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--warn-bg); color: var(--warn);
  box-shadow: inset 0 0 0 1px var(--warn-edge);
}
.fold-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fold-text b { font-size: 15px; letter-spacing: -.01em; }
.fold-text .small { line-height: 1.4; }

.fold-cue {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--slate);
  border: 1px solid var(--rule); border-radius: 999px; padding: 5px 11px;
  background: var(--paper);
}
details.fold > summary:hover .fold-cue { border-color: var(--warn); color: var(--warn); }
.fold-cue svg { transition: transform .18s ease; }
details.fold[open] .fold-cue svg { transform: rotate(180deg); }
.fold-cue .open { display: none; }
details.fold[open] .fold-cue .closed { display: none; }
details.fold[open] .fold-cue .open { display: inline; }

/* the body of a folded block gets its own padding, since summary owns the top */
details.fold > *:not(summary) { margin-left: 18px; margin-right: 18px; }
details.fold > *:last-child { margin-bottom: 16px; }

@media (max-width: 640px) {
  details.fold > summary { padding: 14px; gap: 10px; }
  .fold-cue { padding: 4px 9px; font-size: 11px; }
  .fold-text b { font-size: 14.5px; }
  details.fold > *:not(summary) { margin-left: 14px; margin-right: 14px; }
}

@media (prefers-reduced-motion: reduce) { .fold-cue svg { transition: none; } }

/* ------------------------------------------------------------- tabs ---- */

/* SCROLLS SIDEWAYS WHEN IT HAS TO.
   The garage grew tabs — Active, three standings, Inactive — and on a phone
   the last of them sat off the edge of the screen with no way to reach it.
   A row that cannot be scrolled is a row whose far end does not exist.

   Same treatment the nav and the admin bar already use: scroll, no visible
   scrollbar, and flex-shrink off so the tabs keep their size rather than
   squeezing into unreadable slivers. */
.tabs {
  display: flex; gap: 4px; border-bottom: 1px solid var(--rule); margin-top: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a { flex: none; scroll-snap-align: start; }

/* A HINT THAT THERE IS MORE.
   With the scrollbar hidden, a row that runs off the edge is
   indistinguishable from one that simply ends — so the last tab looks like
   the last tab. Fading the right edge says otherwise without adding a
   control to a row that is already a row of controls.

   Only on narrow screens, and the fade sits over the rule rather than the
   text so it never dims a label being read. */
@media (max-width: 760px) {
  .tabs {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
            mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
  }
  /* No fade once the end is reached — animation-timeline is not widely
     supported yet, so this is the honest compromise: the fade is constant,
     and it costs a couple of pixels of the final tab's padding, not its
     text. */
  .tabs a:last-child { padding-right: 22px; }
}
.tabs a {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px; text-decoration: none;
  font-size: 14.5px; font-weight: 500; color: var(--slate);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  white-space: nowrap;
}
.tabs a:hover { color: var(--ink); }
.tabs a.on { color: var(--verify); border-bottom-color: var(--verify); }
.tabs a span {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  background: var(--wash); color: var(--slate);
  border-radius: 999px; padding: 1px 7px; line-height: 1.6;
}
.tabs a.on span { background: var(--verify-bg); color: var(--verify); }

@media (max-width: 640px) {
  .tabs a { flex: 1; justify-content: center; padding: 10px 8px; font-size: 14px; }
}

/* --------------------------------------------------- sortable headers -- */

th a.sort {
  color: inherit; text-decoration: none;
  display: inline-flex; align-items: center; gap: 3px;
  white-space: nowrap;
}
th a.sort:hover { color: var(--ink); }
th a.sort.on { color: var(--verify); }


/* <b> defaults to 700, which would pull a whole extra font file for the sake of
   a slightly heavier bold. 600 is already loaded and reads the same at these
   sizes. */
b, strong { font-weight: 600; }
