/* Shared styles. Palette and report components ported from docs/report-prototype.html.

   THEMING: components reference only semantic CSS custom properties (declared in :root
   here with neutral defaults). The brand pack (brand.css, loaded after this file) maps
   those semantic tokens onto the "What's the Car Worth?" palette + type. Keep this file
   free of hard-coded colours so the brand layer fully controls the look.

   Semantic tokens (not raw palette): --color-good/-bg (positive: pass, live figures, good
   deal), --color-bad/-bg (negative/alert), --color-warn/-bg (caution), --color-rule
   (header accent line), --color-figure (headline numbers), --color-primary (buttons/links). */

:root {
  color-scheme: light;

  /* Typography */
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-plate: var(--font-mono);
  --font-size-base: 15px;

  /* Surfaces & text */
  --color-bg: #f5f6f8;
  --color-surface: #fff;
  --color-surface-alt: #f8f9fb;
  --color-text: #1c2330;
  --color-muted: #6b7480;
  --color-faint: #8a929c;
  --color-disabled: #c4c9d0;
  --color-dash: #c4c9d0;

  /* Borders */
  --color-border: #e3e6ea;
  --color-border-soft: #eceef1;
  --color-border-input: #cdd2d8;
  --color-border-alt: #e6e9ee;

  /* Interactive */
  --color-primary: #1257a8; /* secondary buttons / structure */
  --color-primary-contrast: #fff;
  --color-primary-hover: #0e4685;
  --color-link: var(--color-primary);
  --color-btn-bg: var(--color-primary);
  --color-btn-text: var(--color-primary-contrast);
  --color-btn-hover: var(--color-primary-hover);
  --color-section: var(--color-muted); /* h2 section labels */

  /* Accents & semantics */
  --color-rule: #c8102e; /* header underline */
  --color-figure: #c8102e; /* headline numbers (cost total) */
  --color-derived: #7b2cbf; /* sell-target highlight text */
  --color-derived-bg: transparent; /* sell-target highlight chip background */
  --color-good: #1a8f3c;
  --color-good-bg: #e3f6e8;
  --color-bad: #c8102e;
  --color-bad-bg: #fde8ea;
  --color-warn: #b06f00;
  --color-warn-bg: #fff3e0;
  --color-flag-amber-border: #e09b00;
  --color-flag-amber-bg: #fff9ec;
  --color-row-hover: #f0f6ff;
  --color-row-active: #eaf2ff;

  /* Number plate */
  --color-plate-bg: #ffd200;
  --color-plate-border: #d9b400;
  --color-plate-text: #111;

  /* Shape & layout */
  --radius-card: 10px;
  --radius: 8px;
  --radius-sm: 6px;
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04);
  /* Responsive page width: use the available desktop real estate (data tables are wide) but cap so
     prose stays readable and huge monitors don't stretch lines absurdly. Scales with the viewport. */
  --layout-max: min(96vw, 1680px);
  --header-rule-width: 3px;
}

* {
  box-sizing: border-box;
}
body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  line-height: 1.45;
  font-size: var(--font-size-base);
}
/* Figures: prices, mileages, registrations, dates. */
.mono,
.reg-plate,
.cost-total,
.val-box .amt,
.rep-cost {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.wrap {
  max-width: var(--layout-max);
  margin: 0 auto;
  padding: 24px 20px 60px;
}
header.app {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  border-bottom: var(--header-rule-width) solid var(--color-rule);
  padding: 10px 0 16px;
  margin-bottom: 24px;
}
/* Hamburger menu (mobile only). Pure CSS: a hidden checkbox toggled by the burger label shows/hides
   the nav — no JS. The burger is hidden on desktop, where the nav shows inline as usual. */
.nav-burger {
  display: none;
  margin-left: auto;
  cursor: pointer;
  font-size: 24px;
  line-height: 1;
  padding: 4px 8px;
  user-select: none;
  border: 1px solid var(--color-rule);
  border-radius: 6px;
}
.topnav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

/* Brand lockup: badge + wordmark, vertically centred. */
.brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}
.brand-lockup .mk {
  width: 50px;
  height: 50px;
  flex: none;
  border-radius: 12px;
  background: var(--ink, #0f1d2e);
  color: #fff;
  font-weight: 900;
  font-size: 28px;
  letter-spacing: -2px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
.brand-lockup .wm {
  font-size: 23px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink, #0f1d2e);
}
.brand-lockup .q {
  color: var(--green, #1db877);
}
header.app .tag {
  color: var(--color-muted);
  font-size: 13px;
}
.topnav {
  margin-left: auto;
  font-size: 13px;
  display: flex;
  gap: 14px;
  align-items: center;
}
.topnav a {
  color: var(--color-link);
  text-decoration: none;
}
.topnav a:hover {
  text-decoration: underline;
}
.topnav .navuser {
  color: var(--color-muted);
}
h2 {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 2px;
  color: var(--color-section);
  margin: 30px 0 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: 18px 20px;
  margin-bottom: 16px;
  box-shadow: var(--shadow-card);
}
.auth-card {
  max-width: 460px;
}
.auth-card label {
  display: block;
  margin-bottom: 14px;
  font-weight: 600;
  font-size: 14px;
}
.auth-card label.inline {
  font-weight: 400;
  display: flex;
  align-items: center;
  gap: 8px;
}
.auth-card input[type='email'],
.auth-card input[type='password'],
.auth-card input[type='text'],
.auth-card select {
  display: block;
  width: 100%;
  margin-top: 5px;
  padding: 8px 10px;
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 400;
}
.auth-card hr {
  border: none;
  border-top: 1px solid var(--color-border-soft);
  margin: 20px 0;
}
/* Report section icons (wtcw-icons.svg via <use>); inherit colour via currentColor. */
.ico {
  width: 18px;
  height: 18px;
  flex: none;
  vertical-align: -4px;
  color: var(--color-muted);
}
.ico.active {
  color: var(--color-good);
}
table {
  width: 100%;
  /* border-collapse: collapse breaks position:sticky on <th> in Chromium — use separate + 0 spacing
     (visually identical with our single border-bottom per cell) so the floating header actually sticks. */
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}
/* Row shading on hover so the eye tracks a single record across the now-wider tables (Ross 2026-06-25).
   Applies to every data table; the sticky header row (thead) is excluded. */
tbody tr:hover td {
  background: var(--color-row-hover);
}
th,
td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-border-soft);
}
th {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-faint);
  font-weight: 600;
}
/* Floating header (Ross 2026-06-25): column headers stick to the top of the viewport as the page
   scrolls, so the headings stay visible on long tables. Applies to every table site-wide. A solid
   surface background + a bottom rule keep the rows from showing through; box-shadow (not the collapsed
   border, which sticky drops) draws the separating line. Requires no overflow-hidden/auto ancestor —
   table cards must not clip. Only true column headers (thead) stick, not row-label <th> in a tfoot. */
thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--color-surface);
  box-shadow: inset 0 -1px 0 var(--color-border);
}
tr:last-child td {
  border-bottom: none;
}
.history-row {
  cursor: pointer;
}
.history-row:hover {
  background: var(--color-row-hover);
}
.history-row.active {
  background: var(--color-row-active);
}
.reg-plate {
  display: inline-block;
  background: var(--color-plate-bg);
  color: var(--color-plate-text);
  font-weight: 700;
  border-radius: 4px;
  padding: 2px 8px;
  letter-spacing: 1px;
  border: 1px solid var(--color-plate-border);
  white-space: nowrap; /* a registration must never wrap onto two lines */
}
/* Truncated table cell (e.g. the make+model column in the reports history) — keeps the column narrow;
   the full value is in the cell's title attribute on hover. */
.trunc {
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Aligned filter row (project standard): each control stacks label-over-input and the columns
   line up in a responsive grid. Use this for any filter bar so they're consistent across the site. */
.filter-grid {
  display: grid;
  /* min() so a column can shrink below 150px on a narrow phone instead of forcing the page to
     scroll sideways — identical on wide screens (portfolio responsive standing order). */
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: 10px 14px;
  align-items: end;
  padding: 12px;
}
.filter-grid label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 12px;
  color: var(--color-muted, #667085);
}
.filter-grid label select,
.filter-grid label input {
  width: 100%;
  /* No box around filter controls (Ross preference) — square-edged, borderless, flat tinted fill so
     the field reads as a control without an outline. Applied site-wide for consistency with the
     naked filter buttons below. */
  border: none;
  border-radius: 0;
  background: var(--mist);
  padding: 8px 10px;
}
.filter-grid .filter-actions {
  display: flex;
  gap: 8px;
  align-items: flex-end; /* line the buttons up with the bottom of the filter input boxes */
  flex-wrap: wrap;
}
/* Filter buttons: naked + square (Ross preference) — no border, no rounding; a flat tinted chip so
   they're still visibly clickable. Applies to every filter bar's buttons (Refresh/Reset, etc.). */
.filter-grid .filter-actions button,
.filter-grid .filter-actions .btn-sec {
  border: none;
  border-radius: 0;
  background: var(--mist);
  color: var(--color-primary);
  padding: 8px 14px;
}
.vehicle-line {
  font-size: 18px;
  font-weight: 600;
  margin: 2px 0 4px;
}
.sub {
  color: var(--color-muted);
  font-size: 13px;
}
.val-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-top: 4px;
}
.val-box {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-alt);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.val-box .lbl {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-faint);
}
.val-box .amt {
  font-size: 22px;
  font-weight: 700;
  margin-top: 2px;
}
.val-box.green .amt {
  color: var(--color-good);
}
.val-box.red .amt {
  color: var(--color-bad);
}
.val-box.blue .amt {
  color: var(--color-primary);
}
.pill {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 20px;
}
.pill.pass {
  background: var(--color-good-bg);
  color: var(--color-good);
}
.pill.fail {
  background: var(--color-bad-bg);
  color: var(--color-bad);
}
.pill.warn {
  background: var(--color-warn-bg);
  color: var(--color-warn);
}
.flag {
  border-left: 4px solid var(--color-bad);
  background: var(--color-bad-bg);
  padding: 10px 14px;
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 10px 0;
  font-size: 14px;
}
.flag.amber {
  border-left-color: var(--color-flag-amber-border);
  background: var(--color-flag-amber-bg);
}
.note {
  color: var(--color-muted);
  font-size: 13px;
}
/* Market-position graphic (Ross 2026-06-28): a horizontal track over the comparable price range with the
   interquartile band shaded, the median ticked, and a marker (asking / suggested-sell price) + verdict.
   Tone colours reuse the existing semantic tokens — green good, muted-grey fair, amber above-market
   (amber is a caution, not the alert/red, which stays reserved). */
.mkt-pos {
  font-size: 13px;
}
.mkt-pos-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 26px; /* headroom for the marker amount bubble that sits above the track */
}
.mkt-pos-scope {
  font-weight: 600;
  color: var(--color-muted);
}
.mkt-pos-verdict {
  font-weight: 700;
}
.mkt-good {
  color: var(--color-good);
}
.mkt-ok {
  color: var(--color-muted);
}
.mkt-warn {
  color: var(--color-warn);
}
.mkt-track {
  position: relative;
  height: 10px;
  border-radius: 5px;
  background: #e6e8eb; /* neutral track — NOT --color-rule (that's the brand red, reads as an alert) */
}
.mkt-iqr {
  position: absolute;
  top: 0;
  height: 100%;
  background: var(--color-good-bg);
  border-radius: 5px;
}
.mkt-median {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 16px;
  background: var(--color-muted);
  transform: translateX(-1px);
}
.mkt-marker {
  position: absolute;
  top: -4px;
  width: 3px;
  height: 18px;
  border-radius: 2px;
  background: currentColor; /* tone class sets the colour */
  transform: translateX(-1.5px);
}
.mkt-marker-amt {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-weight: 700;
  font-size: 12px;
  background: var(--color-card, #fff);
  padding: 0 3px;
}
.mkt-scale {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-size: 11px;
  color: var(--color-muted);
}
/* Placeholder state for a not-yet-connected integration (reads as pending, not error). */
.pending {
  color: var(--color-faint);
  font-size: 12px;
  font-style: italic;
  margin: 4px 0 0;
}
a.srclink {
  color: var(--color-link);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
}
a.srclink:hover {
  text-decoration: underline;
}

/* --- Comparables card: the count and the full search, where they can be seen -----------------
   Ross, 2026-08-04, on a report that already carried both: he could not find the total ("Cheapest
   10 of 40") or the full-search link, because the first was small print and the second was styled
   as a footnote at the tail of a block of drop-downs. A number nobody can find is not shown. */
.at-headline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin: 2px 0 10px;
}
.at-headline .at-count {
  font-size: 16px;
  font-weight: 600;
  color: var(--color-primary);
}
.at-headline .at-count .sub {
  font-weight: 400;
}
/* The full-search link reads as an action, not as small print, and sits beside the count. */
a.at-openall {
  margin-left: auto;
  background: var(--color-btn-bg);
  color: var(--color-btn-text);
  border-radius: var(--radius);
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
a.at-openall:hover {
  filter: brightness(0.94);
}
/* Every advert in the table is a link to that advert. It has always opened in a new tab; it just
   did not look like a link, which is the whole of the complaint. */
a.at-advert {
  color: var(--color-link);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}
/* --- Source badges: which marketplace a row came from (Ross 2026-08-04) --------------------
   AutoTrader and eBay sit in ONE price-sorted list, because the cheapest ten must be cheapest
   overall or the ranking that produces the sell target is broken. The badge is how a reader tells
   them apart, and the Source filter above the table shows one at a time. */
.src-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 3px;
  vertical-align: middle;
  letter-spacing: 0.02em;
}
.src-at {
  background: var(--mist);
  color: var(--color-primary);
}
.src-ebay {
  background: #fdf0d5;
  color: #8a5a00;
}
/* Shown ONLY when the plate was read from the photographs and confirmed against DVSA. Its absence
   is not a claim that a car is wrong — it says we have not checked, which is the honest state for
   every eBay row until the photo-plate reader has run against it. */
.reg-ok {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 3px;
  background: #e6f4ea;
  color: #1e6b34;
  vertical-align: middle;
}

/* "Change the search" — the filter grid, collapsed by default so the cars are the first thing on
   the card. Forced open whenever a note above it tells the reader to change a filter. */
details.at-filters {
  margin: 0 0 10px;
}
details.at-filters > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-link);
  padding: 6px 0;
  list-style: revert;
}
@media (hover: none) {
  /* A comfortable tap target on touch, where a 13px line of text is not one. */
  details.at-filters > summary {
    padding: 10px 0;
  }
}
.right {
  text-align: right;
}
.muted-row td {
  color: var(--color-faint);
  font-style: italic;
}
footer {
  margin-top: 36px;
  color: var(--color-faint);
  font-size: 12px;
  text-align: center;
}
.badge-cheap {
  font-size: 11px;
  color: var(--color-good);
  font-weight: 600;
}
.dash {
  color: var(--color-dash);
}
.cost-total {
  font-size: 30px;
  font-weight: 800;
  color: var(--color-figure);
  margin: 2px 0 8px;
}
.cost-table {
  width: auto;
  min-width: 320px;
}
.cost-table td {
  padding: 6px 10px;
}
.derived {
  background: var(--color-derived-bg);
  color: var(--color-derived);
  font-weight: 700;
  padding: 0 5px;
  border-radius: 3px;
}
.btn {
  margin-top: 12px;
  background: var(--color-btn-bg);
  color: var(--color-btn-text);
  border: none;
  border-radius: var(--radius);
  padding: 9px 16px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.btn:hover:not(:disabled) {
  background: var(--color-btn-hover);
}
.btn:disabled {
  background: var(--color-disabled);
  cursor: not-allowed;
}
/* Same format as .btn, distinct colour — for the "View on Motorway" action so it sits next to the
   green "Run valuation report" as a matching pair (teal vs green). */
.btn-motorway {
  background: #0e7c86;
}
.btn-motorway:hover:not(:disabled) {
  background: #0a626a;
}
.optsel {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.donetag {
  font-size: 11px;
  color: var(--color-good);
  font-weight: 600;
}
.cost-cols {
  display: flex;
  gap: 30px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.cost-left {
  flex: 1;
  min-width: 240px;
}
.cost-right {
  flex: 1;
  min-width: 280px;
}
.at-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 13px;
  color: var(--color-muted);
}
.at-filter input,
.at-filter select {
  font-size: 13px;
  padding: 5px 8px;
  /* Borderless filter controls (Ross preference) — see .filter-grid above. */
  border: none;
  border-radius: 0;
  background: var(--mist);
}
.at-filter input {
  width: 92px;
}
.at-filter .btn {
  margin-top: 0;
  padding: 7px 14px;
}
.btn-sec {
  background: var(--color-surface);
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius);
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.repair-add {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 12px;
  font-size: 13px;
  color: var(--color-muted);
}
.repair-add select {
  font-size: 13px;
  padding: 5px 8px;
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.repair-add .btn {
  margin-top: 0;
  padding: 7px 14px;
}
.rep-cost {
  width: 80px;
  text-align: right;
  font-size: 13px;
  padding: 4px 6px;
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
}
.opt-group {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-section);
  font-weight: 700;
  padding-top: 12px;
}
.searchbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: flex-end;
}
.searchbar input {
  padding: 8px 10px;
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  font-size: 14px;
}
.disclaimer {
  color: var(--color-faint);
  font-size: 12px;
  margin-top: 14px;
}
.tm {
  font-size: 0.6em;
  vertical-align: super;
  color: var(--color-good);
  font-weight: 700;
}

/* Marketing / About */
.prose {
  max-width: 680px;
}
.hero-h1 {
  font-weight: 300;
  font-size: clamp(30px, 5vw, 52px);
  letter-spacing: -1px;
  line-height: 1.1;
  color: var(--color-text);
  margin: 28px 0 28px;
  text-transform: none;
}
.hero-h1 .accent {
  color: var(--color-good);
  font-weight: 700;
}
.prose p {
  font-size: 16px;
  margin: 0 0 16px;
}
.figure-example {
  display: grid;
  gap: 8px;
}
.figure-example .mono {
  font-size: 20px;
  font-weight: 600;
  color: var(--color-text);
  margin-right: 8px;
}

.center {
  text-align: center;
}

/* Comparables: seller P/T pills (translucent brand colours so the letter shows through). */
.seller {
  display: inline-block;
  min-width: 20px;
  padding: 2px 7px;
  border-radius: 6px;
  font-weight: 700;
  font-size: 12px;
  text-align: center;
  font-family: var(--font-mono, monospace);
}
.seller-p {
  background: color-mix(in srgb, var(--green) 22%, transparent);
  color: var(--green-deep);
  border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
.seller-t {
  background: color-mix(in srgb, var(--plate) 34%, transparent);
  color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--plate) 60%, transparent);
}
/* Comparables: sortable column headers. */
th.sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
th.sortable:hover {
  color: var(--green-deep);
}
.sort-arrow {
  font-size: 10px;
  color: var(--slate);
}

/* Combined status card: dense two-column label/value grid. */
.kv-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px 28px;
}
.kv {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  border-bottom: 1px solid var(--cloud);
  padding: 7px 0;
}
.kv .lbl {
  color: var(--slate);
}
.kv-val {
  font-weight: 600;
  text-align: right;
}
@media (max-width: 640px) {
  .kv-grid {
    grid-template-columns: 1fr;
  }
}

/* Report header: vehicle line left, actions (Refresh) right. */
.header-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
}
.header-actions {
  flex-shrink: 0;
}
/* Status card: two columns split by section (tax left, mileage/emissions right-aligned). */
.status-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 32px;
}
.status-right {
  text-align: right;
}
.status-right .kv {
  flex-direction: row-reverse;
}
.status-right .kv-val {
  text-align: left;
}
@media (max-width: 640px) {
  .status-cols {
    grid-template-columns: 1fr;
  }
  .status-right {
    text-align: left;
  }
  .status-right .kv {
    flex-direction: row;
  }
}
.adlist {
  margin: 0;
  padding-left: 18px;
}
.adlist li {
  padding: 3px 0;
}

/* Report-history tabs: a reg's previous reports, newest first — a clear tab bar. */
.report-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: flex-end;
  margin: 0 0 16px;
  border-bottom: 2px solid var(--cloud);
}
.report-tabs-lbl {
  color: var(--slate);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 700;
  margin-right: 6px;
  padding-bottom: 9px;
}
.report-tabs .tab {
  position: relative;
  bottom: -2px;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border: 1px solid var(--cloud);
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  background: var(--mist);
  color: var(--slate);
  text-decoration: none;
}
.report-tabs a.tab:hover {
  background: #fff;
  color: var(--ink);
}
.report-tabs .tab.active {
  background: #fff;
  color: var(--ink);
  border-color: var(--cloud);
  border-bottom: 2px solid #fff;
}
.report-tabs .tab.active::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--green);
  border-radius: 8px 8px 0 0;
}

/* Section hub on the home page — choose Pricing Intelligence / Buying Research / Market Radar. */
.hub-hero {
  margin: 8px 0 22px;
}
.hub-hero h1 {
  margin: 0 0 4px;
  font-size: 30px;
}
.hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin: 0 0 26px;
}
.hub-card {
  border: 1px solid var(--cloud);
  border-radius: 14px;
  padding: 22px;
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-decoration: none;
  color: inherit;
  transition:
    box-shadow 0.15s ease,
    transform 0.15s ease,
    border-color 0.15s ease;
}
a.hub-card:hover {
  border-color: var(--green-deep);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}
.hub-card-soon {
  opacity: 0.75;
}
.hub-card .hub-ico {
  font-size: 30px;
  line-height: 1;
}
.hub-card h3 {
  margin: 4px 0 0;
  font-size: 19px;
}
.hub-card .note {
  flex: 1;
  margin: 0 0 8px;
}
.hub-card .hub-go {
  font-weight: 700;
  color: var(--green-deep);
}

/* Report-generation progress bar. */
.progress {
  height: 10px;
  background: var(--mist);
  border: 1px solid var(--cloud);
  border-radius: 999px;
  overflow: hidden;
  margin: 12px 0 6px;
}
.progress-bar {
  height: 100%;
  width: 8%;
  background: var(--green);
  border-radius: 999px;
  transition: width 0.6s ease;
}

/* Click-to-expand pop-out (project convention). Desktop: a small panel anchored below the trigger.
   The trigger's default disclosure triangle is hidden (incl. WebKit/iOS). Mobile override is in the
   media query below — it becomes a full-width bottom sheet so it can never fall off the screen edge. */
.popinfo {
  display: inline-block;
  position: relative;
  vertical-align: middle;
}
.popinfo-trigger {
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.popinfo-trigger::-webkit-details-marker {
  display: none;
}
.popinfo-body {
  position: absolute;
  z-index: 30;
  left: 0;
  top: 100%;
  margin-top: 4px;
  min-width: 180px;
  max-width: 300px;
  white-space: normal;
  text-align: left;
  font-weight: 400;
  background: #fff;
  border: 1px solid var(--cloud);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
  padding: 8px 10px;
}

/* ============================================================================
   Mobile (≈ iPhone Pro, 393px, and narrower). Same HTML re-flows to the screen
   via these rules — no device sniffing. Shared/structural so EVERY current and
   future component inherits the mobile behaviour rather than needing bespoke work.
   The grids (Details, filters, value boxes, hub, cost) already re-flow via
   auto-fit/flex; the main job here is keeping wide DATA TABLES (comparables,
   valuation comparison, MOT history, the auction shortlist/search) inside their
   card — scrolling horizontally — instead of forcing the whole page sideways.
   ============================================================================ */
@media (max-width: 640px) {
  .wrap {
    padding: 16px 12px 48px;
  }
  /* Comparables filter actions: give Refresh/Reset/View-all their own full-width row and let them
     wrap, so the long "View all on AutoTrader" link can't run off the right edge. */
  .filter-grid .filter-actions {
    grid-column: 1 / -1;
    flex-wrap: wrap;
  }
  .filter-grid .filter-actions a {
    flex-basis: 100%;
  }
  /* Any table becomes a width-constrained, horizontally-scrollable block: it fills the card and
     the user swipes sideways to read the rest, so the page itself never overflows. Applies to
     every table on the site (and any added later) with no per-table markup. */
  table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  /* Dense figures read better a touch smaller on a phone. */
  h2 {
    font-size: 20px;
  }
  .vehicle-line {
    font-size: 16px;
  }
  .val-box .amt {
    font-size: 20px;
  }
  /* Navigation collapses into the hamburger: the burger shows, the nav hides until toggled, then
     drops down as a full-width column (links + account + email + log out). */
  .nav-burger {
    display: block;
  }
  .topnav {
    display: none;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    width: 100%;
    margin-top: 10px;
  }
  .nav-toggle:checked ~ .topnav {
    display: flex;
  }
  .topnav a,
  .topnav .navuser {
    padding: 8px 2px;
    width: 100%;
  }
  /* Pop-out becomes a full-width bottom sheet so it's always fully on-screen, never clipped off the
     right edge or inside a horizontally-scrolling table. Raised clear of the mobile browser's bottom
     toolbar (~50px on iOS Chrome) + the home-indicator safe area, or it renders hidden behind them
     and looks like the "see" button does nothing. The trigger stays tappable to close. */
  .popinfo-body {
    position: fixed;
    left: 12px;
    right: 12px;
    top: auto;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    min-width: 0;
    max-width: none;
    width: auto;
    max-height: 60vh;
    overflow: auto;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.24);
  }
}

/* Report action bar (Print / Download PDF / Email PDF). Hidden in print (.no-print). (Ross 2026-06-28 #4) */
.report-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  margin: 0 0 14px;
}
.report-actions .btn-sec {
  font-size: 13px;
}
.report-actions .ra-note {
  color: var(--color-muted);
  font-size: 12px;
}

/* Print stylesheet (Ross 2026-06-28 #4): strip the app chrome and interactive controls so a printed or
   browser-"Save as PDF" report is clean. The server-rendered PDF endpoint emulates print media, so it
   inherits exactly these rules. */
@media print {
  /* App chrome + anything explicitly interactive-only. */
  header.app,
  .topnav,
  .nav-burger,
  .report-actions,
  .report-tabs,
  .filter-grid,
  .searchbar,
  .header-actions,
  #atRefresh,
  #atReset,
  #atStale,
  .hub-go {
    display: none !important;
  }
  /* Flatten the page for paper. */
  body,
  .wrap {
    background: #fff !important;
  }
  .wrap {
    max-width: none;
    margin: 0;
    padding: 0;
  }
  .card {
    break-inside: avoid;
    box-shadow: none;
    border: 1px solid #ddd;
  }
  /* Links print as plain text (no underline/colour), but keep advert ↗ links legible. */
  a {
    color: inherit;
    text-decoration: none;
  }
  /* Don't orphan a card heading at the foot of a page. */
  h2,
  h3 {
    break-after: avoid;
  }
  footer .disclaimer {
    font-size: 10px;
  }
}
