/*
 * Australia Motors design system — core (tokens, base, layout, components).
 * Original work. External stylesheet only: the CSP forbids inline styles.
 * Page-specific rules live in home.css / search.css / detail.css.
 */

/* ── Fonts. Both self-hosted (font-src is 'self' in the CSP — a Google Fonts CDN load would be blocked by
   it anyway, which is also why this is the right call privacy/reliability-wise, not just a CSP workaround).
   Inter (SIL OFL 1.1, /assets/fonts/inter-OFL.txt) is the body/UI face everywhere. Archivo (SIL OFL 1.1,
   /assets/fonts/archivo-OFL.txt) is the brand wordmark's display face only (see --font-brand) — the logo
   text in the header/footer/auth panel, nowhere else; body copy stays on Inter. ── */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/inter-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/inter-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Metric-matched fallback so text does not jump when Inter arrives. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 107.4%;
  ascent-override: 90.2%;
  descent-override: 22.5%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("/assets/fonts/archivo-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("/assets/fonts/archivo-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Design tokens ── */
:root {
  color-scheme: light;

  /* Brand */
  --navy-950: #061224;
  --navy-900: #0b1f3a;
  --navy-800: #102b4f;
  --navy-700: #183b69;
  --navy-600: #24518c;
  --blue-700: #003e99; /* hover/active state for blue-600 (9.8:1 on white) */
  --blue-600: #0052cc; /* Australian blue — primary actions, links on light backgrounds (6.8:1 on white; 2026-10 redesign: deeper, more saturated cobalt — see docs/DESIGN_SYSTEM.md) */
  --blue-500: #2f7bea;
  --blue-300: #8db8f7; /* links and accents on navy */
  --blue-100: #e4eefd;
  --blue-50: #f1f6fe;
  --amber-500: #f5a524; /* limited accent — badges and one highlight per page; text on it is always navy */
  --amber-600: #b56f00;
  --amber-100: #fdf0d5;
  --green-700: #0b6b45;
  --green-100: #e1f3ea;
  --red-700: #b42318;
  --red-100: #fde8e6;

  /* Neutrals (charcoal ink, cool greys) */
  --ink-900: #141b26;
  --ink-700: #2b3644;
  --ink-500: #566172; /* muted text — 6.3:1 on white */
  --ink-400: #667083;
  --line: #dde3ec;
  --line-strong: #c3ccd9;
  --surface: #f5f7fa;
  --surface-2: #eaeff5;
  --bg: #ffffff;

  --focus: #0052cc;

  /* Type */
  --font: "Inter", "Inter Fallback", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Archivo now also carries every page's h1 and the large marketing/display headlines (hero, CTA bands,
     section eyebrow-led headers) — not just the logo wordmark. One distinctive display face used with
     intent, tied back to the brand mark itself, reads as designed; Inter everywhere (the old behaviour)
     read as a template. Functional UI headings (card h2/h3, dashboard section headers, table captions)
     stay on Inter — those are dense, frequent and need to stay quiet, not shout. See docs/BRANDING.md. */
  --font-brand: "Archivo", "Inter", "Inter Fallback", system-ui, sans-serif;
  --fs-xs: 0.8125rem;
  --fs-sm: 0.875rem;
  --fs-md: 1rem;
  --fs-lg: 1.125rem;
  --fs-h3: 1.125rem;
  --fs-h2: clamp(1.375rem, 1.15rem + 0.9vw, 1.875rem);
  --fs-h1: clamp(1.875rem, 1.4rem + 2vw, 2.75rem);
  --fs-display: clamp(2.25rem, 1.5rem + 3.4vw, 3.75rem);

  /* Space (4px base) */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.25rem;
  --s-6: 1.5rem;
  --s-8: 2rem;
  --s-10: 2.5rem;
  --s-12: 3rem;
  --s-16: 4rem;

  /* Shape and depth. Slightly tighter radii than the previous scale (was 8/12/16) — a restrained,
     automotive-serious surface reads more premium than the bubbly, rounded-everywhere "AI template" look. */
  --r-sm: 4px;  /* controls: buttons, inputs, selects, badges */
  --r-md: 6px;  /* cards, panels */
  --r-lg: 8px;  /* large surfaces: search console, modals */
  --r-pill: 999px;
  --shadow-1: 0 1px 2px rgba(11, 31, 58, 0.06), 0 1px 1px rgba(11, 31, 58, 0.04);
  --shadow-2: 0 2px 4px rgba(11, 31, 58, 0.05), 0 12px 28px -12px rgba(11, 31, 58, 0.22);
  --shadow-3: 0 4px 8px rgba(11, 31, 58, 0.06), 0 24px 48px -16px rgba(11, 31, 58, 0.3);

  --gutter: clamp(1rem, 4vw, 2rem);
  --maxw: 1360px;
  --header-h: 4rem;

  /* One control height per size, shared by every button, input, select, chip, tab and pagination link, so
     a field and the button beside it always line up. Never set a control's height with a literal. */
  --control-h: 2.75rem;
  --control-h-sm: 2.25rem;
  --control-h-lg: 3.25rem;
  --control-px: 1.25rem;

  /* Vertical rhythm: one value between page sections, one above and one below every page's content. */
  --section-y: clamp(2.5rem, 5vw, 4rem);
  --page-top: var(--s-8);
  --page-bottom: var(--s-16);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* Motion: 120–250ms, one easing curve everywhere. See docs/DESIGN_SYSTEM.md for when to use which. */
  --dur-fast: 120ms;
  --dur-base: 180ms;
  --dur-slow: 250ms;

  /* Breakpoints (reference only — a media query needs the literal value, custom properties can't appear
     inside one): sm 30rem (480px) · phone-landscape/tablet 40rem (640px) · filters/nav 60rem (960px) ·
     detail/search two-column 64rem (1024px). Always em/rem, never px, so a user's zoomed base font size
     shifts where the layout breaks too. */

  /* Stacking: header/menu 60 · sticky mobile bars 40–50 · drawers/filters 100 · toasts 150 · modals/lightbox
     browser-native (dialog's own top-layer — always above everything else, nothing to set). */
}

/* ── Base ── */
*,
*::before,
*::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 1rem); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-md);
  line-height: 1.6;
  color: var(--ink-900);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.15; letter-spacing: -0.02em; color: var(--navy-900); text-wrap: balance; }
h1 { font-family: var(--font-brand); font-size: var(--fs-h1); font-weight: 800; letter-spacing: -0.03em; line-height: 1.08; }
h2 { font-size: var(--fs-h2); font-weight: 720; }
h3 { font-size: var(--fs-h3); font-weight: 650; letter-spacing: -0.01em; }
/* Marketing/display headlines (hero, CTA bands, the spotlight module) — the one other place Archivo
   appears beyond h1, always applied explicitly via this class, never by cascading onto every h2. */
.display { font-family: var(--font-brand); font-weight: 800; letter-spacing: -0.03em; line-height: 1.04; }
p { margin: 0 0 var(--s-4); text-wrap: pretty; }
a { color: var(--blue-600); text-underline-offset: 0.18em; }
a:hover { color: var(--blue-700); }
img, svg { max-width: 100%; }
img { display: block; height: auto; }
ul, ol { margin: 0; padding: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
::selection { background: var(--blue-100); color: var(--navy-900); }
.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-500); }
.lead { font-size: var(--fs-lg); color: var(--ink-500); max-width: 60ch; }

.visually-hidden,
.hp { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; left: -9999px; }
.skip-link { position: absolute; left: -999px; top: 8px; z-index: 200; background: var(--navy-900); color: #fff; padding: 0.625rem 1rem; border-radius: var(--r-sm); font-weight: 600; }
.skip-link:focus { left: 8px; color: #fff; }

/* Short pages: the footer sits at the bottom of the window, never mid-screen with white below it. */
main { flex: 1 0 auto; }
.container { width: min(var(--maxw), 100% - 2 * var(--gutter)); margin-inline: auto; }
/* The layout already wraps every non-bleed page in a .container; most page templates add their own as well.
   Without this the inner one subtracts the gutter a second time, so page content sat one gutter further in
   than the header and footer on every screen size. A nested container never adds its own gutter. */
.container .container { width: 100%; }
.icon { width: 1.25em; height: 1.25em; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; vertical-align: -0.2em; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── Page sections. Shared by every page that stacks titled bands (home, vehicle detail's "Similar"); these
   used to live in home.css only, so any other page using them rendered an unstyled heading row. ── */
.section { padding: var(--section-y) 0; }
.section--tint { background: var(--surface); }
.section__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: var(--s-3) var(--s-6); margin-bottom: var(--s-5); }
.section__sub { margin: var(--s-1) 0 0; color: var(--ink-500); }
.section__link { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 650; text-decoration: none; }
.section__link:hover { text-decoration: underline; }

/* ── Buttons ── */
.btn,
.button {
  --btn-bg: var(--blue-600);
  --btn-fg: #fff;
  --btn-bd: var(--blue-600);
  --btn-shadow: 0 1px 2px rgba(11, 31, 58, 0.08);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--control-h);
  padding: 0 var(--control-px);
  border: 1px solid var(--btn-bd);
  border-radius: var(--r-sm);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 600;
  font-size: var(--fs-md);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--btn-shadow);
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease), box-shadow 0.15s var(--ease), transform 0.15s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.btn:hover,
.button:hover { --btn-bg: var(--blue-700); --btn-bd: var(--blue-700); --btn-shadow: 0 6px 14px -4px rgba(6, 18, 36, 0.3); color: var(--btn-fg); }
.btn:active,
.button:active { transform: translateY(1px); --btn-shadow: 0 1px 2px rgba(11, 31, 58, 0.08); }
@media (prefers-reduced-motion: no-preference) { .btn:hover, .button:hover { transform: translateY(-1px); } }
.btn--secondary,
.button--secondary { --btn-bg: #fff; --btn-fg: var(--navy-900); --btn-bd: var(--line-strong); }
.btn--secondary:hover,
.button--secondary:hover { --btn-bg: var(--surface); --btn-bd: var(--ink-400); }
.btn--ghost { --btn-bg: transparent; --btn-fg: var(--blue-600); --btn-bd: transparent; padding-inline: 0.75rem; }
.btn--ghost:hover { --btn-bg: var(--blue-50); --btn-fg: var(--blue-700); --btn-bd: transparent; }
.btn--light { --btn-bg: #fff; --btn-fg: var(--navy-900); --btn-bd: #fff; }
.btn--light:hover { --btn-bg: var(--blue-50); --btn-bd: var(--blue-50); --btn-fg: var(--navy-900); }
.btn--outline-light { --btn-bg: transparent; --btn-fg: #fff; --btn-bd: rgba(255, 255, 255, 0.45); }
.btn--outline-light:hover { --btn-bg: rgba(255, 255, 255, 0.1); --btn-bd: #fff; --btn-fg: #fff; }
.btn--amber { --btn-bg: var(--amber-500); --btn-fg: var(--navy-950); --btn-bd: var(--amber-500); }
.btn--amber:hover { --btn-bg: #ffb83f; --btn-bd: #ffb83f; --btn-fg: var(--navy-950); --btn-shadow: 0 8px 18px -4px rgba(181, 111, 0, 0.45); }
.btn--danger,
.button--danger { --btn-bg: var(--red-700); --btn-bd: var(--red-700); }
.btn--danger:hover,
.button--danger:hover { --btn-bg: #8f1b12; --btn-bd: #8f1b12; }
.btn--lg { min-height: var(--control-h-lg); padding: 0 1.75rem; font-size: var(--fs-lg); }
.btn--sm,
.button--small { min-height: var(--control-h-sm); padding: 0 0.875rem; font-size: var(--fs-sm); }
.btn--block { display: flex; width: 100%; }
.btn[disabled],
.btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
button.button { font-family: inherit; }
.link-button { background: none; border: 0; padding: 0.5rem 0; min-height: var(--control-h); font-weight: 600; cursor: pointer; color: inherit; }
.link-button:hover { text-decoration: underline; }
.inline-form { display: inline; margin: 0; }

/* ── Integrity strip: a slim, persistent trust bar above the header (2026-10 redesign). Scrolls away with
   the page — only .site-header itself is sticky — so it never permanently eats vertical space, especially
   on mobile. Every claim here is already true and already stated elsewhere on the site (home.php's .trust
   section, the PPSR link in the safety tips); this is a condensed, global restatement, not new copy. */
.integrity-strip { margin: 0; background: var(--navy-950); color: rgba(255, 255, 255, 0.82); font-size: var(--fs-xs); font-weight: 600; }
.integrity-strip__list { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-6); padding-block: 0.45rem; }
.integrity-strip__item { display: inline-flex; align-items: center; gap: 0.4rem; white-space: nowrap; }
.integrity-strip__item .icon { width: 0.95rem; height: 0.95rem; color: var(--amber-500); flex: none; }
.integrity-strip a { display: inline-flex; align-items: center; gap: 0.4rem; color: rgba(255, 255, 255, 0.82); }
.integrity-strip a:hover { color: #fff; }
.integrity-strip a .icon:last-child { width: 0.75rem; height: 0.75rem; color: inherit; opacity: 0.7; }
@media (max-width: 47.99rem) { .integrity-strip__item:nth-child(n+3) { display: none; } }

/* ── Site header ── */
.site-header { position: sticky; top: 0; z-index: 60; background: var(--navy-900); color: #fff; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.site-header__inner { display: flex; align-items: center; gap: var(--s-6); min-height: var(--header-h); }
/* Brand mark: a bold 3-stroke "M", one stroke carrying the amber accent (Issue E, Direction B — the chosen
   logo direction; see docs/BRANDING.md). Drawn directly on the header/footer/auth-panel's own navy
   background rather than inside a separate coloured badge square — those surfaces are already navy, so a
   second badge behind the mark would just be a navy square on navy, adding nothing. */
.brand { display: inline-flex; align-items: center; gap: 0.625rem; color: #fff; text-decoration: none; font-family: var(--font-brand); font-weight: 800; font-size: 1.1875rem; letter-spacing: -0.01em; }
.brand:hover { color: #fff; }
.brand__mark { position: relative; width: 1.75rem; height: 1.75rem; flex: none; display: grid; place-items: center; }
.brand__mark svg { width: 100%; height: 100%; fill: none; stroke: #fff; stroke-width: 13; stroke-linecap: round; stroke-linejoin: round; }
.brand__mark svg .brand__mark-accent { stroke: var(--amber-500); }
.brand__name b { font-weight: 800; color: var(--blue-300); }
.nav-toggle { margin-left: auto; display: inline-flex; align-items: center; gap: 0.5rem; min-height: var(--control-h); padding: 0 0.75rem; color: #fff; text-decoration: none; font-weight: 600; border-radius: var(--r-sm); background: rgba(255, 255, 255, 0.08); border: 0; cursor: pointer; }
.nav-toggle:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
.site-menu { display: none; position: absolute; inset: var(--header-h) 0 auto 0; background: var(--navy-900); padding: var(--s-4) var(--gutter) var(--s-6); border-bottom: 1px solid rgba(255, 255, 255, 0.12); box-shadow: var(--shadow-3); }
.site-menu:target,
.site-menu.is-open { display: block; }
.site-nav { display: flex; flex-direction: column; gap: var(--s-1); }
.site-nav a,
.site-nav .link-button { display: flex; align-items: center; min-height: var(--control-h); color: #fff; font-weight: 600; text-decoration: none; padding: 0 var(--s-2); border-radius: var(--r-sm); }
.site-nav a:hover,
.site-nav .link-button:hover { background: rgba(255, 255, 255, 0.08); color: #fff; text-decoration: none; }
.site-nav a[aria-current="page"],
.site-nav a[aria-current="true"] { color: var(--blue-300); }
.site-nav .btn { margin-top: var(--s-2); }
.site-nav__account { display: flex; flex-direction: column; gap: var(--s-1); margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid rgba(255, 255, 255, 0.14); }
.badge-count { display: inline-flex; align-items: center; justify-content: center; min-width: 1.25rem; height: 1.25rem; margin-left: 0.4rem; padding: 0 0.3rem; border-radius: var(--r-pill); background: var(--amber-500); color: var(--navy-950); font-size: var(--fs-xs); font-weight: 700; line-height: 1; }

/* ── "Buy" nav dropdown: Cars / Motorbikes / Bicycles, each a first-class destination (partials/nav_buy.php).
   No-JS: .nav-sublist has no [hidden] attribute, so all three links are plain, always-visible nav items —
   app.js adds the collapse/expand behaviour on top, it never gates whether they exist. ── */
.nav-group { position: relative; }
.nav-link--dropdown { display: flex; align-items: center; gap: 0.35rem; }
.nav-caret { width: 0.85em; height: 0.85em; transition: transform var(--dur-fast) var(--ease); }
.nav-link--dropdown[aria-expanded="true"] .nav-caret { transform: rotate(180deg); }
.nav-sublist { list-style: none; margin: 0; padding: 0; }
.nav-sublist[hidden] { display: none; } /* same specificity gotcha as .tabs__panel[hidden] — see app.js's comment on this component */
.nav-sublist a { display: flex; align-items: center; gap: 0.6rem; min-height: 2.5rem; color: rgba(255, 255, 255, 0.82); font-weight: 600; font-size: var(--fs-sm); text-decoration: none; padding: 0 var(--s-2) 0 var(--s-6); border-radius: var(--r-sm); }
.nav-sublist a:hover { background: rgba(255, 255, 255, 0.08); color: #fff; text-decoration: none; }
.nav-sublist a[aria-current="page"] { color: var(--blue-300); }
.nav-sublist .icon { width: 1rem; height: 1rem; flex: none; }
@media (min-width: 60rem) {
  .nav-toggle { display: none; }
  .site-menu { display: flex; position: static; flex: 1; align-items: center; padding: 0; background: none; border: 0; box-shadow: none; }
  .site-nav { flex-direction: row; align-items: center; gap: var(--s-1); }
  .site-nav .btn { margin-top: 0; }
  .site-nav__account { flex-direction: row; align-items: center; gap: var(--s-2); margin: 0 0 0 auto; padding: 0; border: 0; }
  .site-menu { justify-content: space-between; }
  .nav-sublist:not([hidden]) {
    position: absolute; top: 100%; left: 0; z-index: 70; min-width: 11rem; margin-top: 0.4rem;
    padding: var(--s-2); background: var(--navy-800); border: 1px solid rgba(255, 255, 255, 0.14); border-radius: var(--r-md); box-shadow: var(--shadow-3);
  }
  .nav-sublist a { padding-left: var(--s-3); }
}
@media (min-width: 60rem) and (prefers-reduced-motion: no-preference) {
  .nav-sublist:not([hidden]) { animation: tab-in var(--dur-base) var(--ease); }
}

/* ── Footer ── */
.site-footer { background: var(--navy-950); color: rgba(255, 255, 255, 0.72); margin-top: var(--s-16); padding: var(--s-12) 0 var(--s-8); font-size: var(--fs-sm); }
.site-footer a { color: rgba(255, 255, 255, 0.86); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer-grid { display: grid; gap: var(--s-8); grid-template-columns: 1fr 1fr; }
.footer-grid h2 { font-size: var(--fs-sm); font-weight: 650; color: #fff; letter-spacing: 0.02em; margin-bottom: var(--s-3); }
.footer-grid ul { list-style: none; display: grid; gap: var(--s-2); }
.footer-about { grid-column: 1 / -1; max-width: 34ch; }
.footer-about p { margin-top: var(--s-3); }
.footer-legal { margin-top: var(--s-10); padding-top: var(--s-6); border-top: 1px solid rgba(255, 255, 255, 0.12); display: grid; gap: var(--s-2); font-size: var(--fs-xs); color: rgba(255, 255, 255, 0.6); }
.footer-legal p { margin: 0; max-width: 90ch; }
.footer-legal a { text-decoration: underline; text-underline-offset: 0.18em; }
@media (min-width: 48rem) { .footer-grid { grid-template-columns: 2fr 1fr 1fr 1fr; } .footer-about { grid-column: auto; } }

/* ── Forms ── */
/* .sfield is the labelled <select> from partials/select. It used to be styled only by home.css and
   search.css, so on every other form (sell wizard, dealer apply/staff) its label and spacing were unstyled
   and fields touched each other. It is a normal form field everywhere; the two compact search contexts
   below space their fields with a grid gap instead. */
.field,
.sfield { margin: var(--s-4) 0; }
.search-panel .sfield,
.filters .sfield { margin: 0; }
.field label,
.sfield label,
.label { display: block; font-weight: 600; font-size: var(--fs-sm); margin-bottom: var(--s-2); color: var(--ink-900); }
/* The native file input, dressed as a secondary button (its button part is ::file-selector-button). */
input[type="file"] { max-width: 100%; font-size: var(--fs-sm); color: var(--ink-500); }
input[type="file"]::file-selector-button { min-height: var(--control-h); margin-right: var(--s-3); padding: 0 var(--control-px); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: #fff; color: var(--navy-900); font: inherit; font-weight: 600; cursor: pointer; }
input[type="file"]::file-selector-button:hover { background: var(--surface); border-color: var(--ink-400); }
.hint { margin: var(--s-2) 0; color: var(--ink-500); font-size: var(--fs-sm); }
.hint .icon { width: 1rem; height: 1rem; margin-right: 0.25rem; }
.field .hint { margin: 0 0 var(--s-2); color: var(--ink-500); font-size: var(--fs-sm); }
.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="tel"],
.field input[type="number"],
.field input[type="date"],
.field input[type="month"],
.field input[type="url"],
.field input[type="search"],
.input,
.select {
  width: 100%;
  min-height: var(--control-h);
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: #fff;
  color: var(--ink-900);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
/* Date/time inputs carry browser chrome that makes them taller than a text input at the same min-height. */
input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] { height: var(--control-h); }
.input::placeholder { color: var(--ink-400); }
.field input:hover,
.input:hover,
.select:hover { border-color: var(--ink-400); }
.field input:focus,
.input:focus,
.select:focus { outline: none; border-color: var(--blue-600); box-shadow: 0 0 0 3px rgba(0, 82, 204, 0.25); }
.select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23566172' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  cursor: pointer;
}
.select:disabled { background-color: var(--surface); color: var(--ink-400); cursor: not-allowed; }

/* Searchable Make/Brand + Model combobox — a premium view layer over the real <select> app.js wraps (see
   its own comment for why that's safe); shares .input's exact look so it's indistinguishable from any other
   text field until you start typing. */
.combobox { position: relative; }
.combobox__input {
  padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23566172' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='m20 20-4.2-4.2'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
}
.combobox__input:disabled { background-color: var(--surface); color: var(--ink-400); cursor: not-allowed; }
.combobox__clear {
  position: absolute; top: 50%; right: 0.5rem; translate: 0 -50%; z-index: 1;
  display: grid; place-items: center; width: 1.75rem; height: 1.75rem; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-500); cursor: pointer;
}
.combobox__clear:hover { background: var(--surface-2); color: var(--ink-900); }
.combobox__clear .icon { width: 0.9rem; height: 0.9rem; }
/* The clear button sits where the search-glass icon is; app.js toggles this class so the two never overlap. */
.combobox.has-value .combobox__input { background-image: none; }
.combobox__listbox {
  position: absolute; top: calc(100% + 0.3rem); left: 0; right: 0; z-index: 20;
  max-height: 16rem; overflow-y: auto; margin: 0; padding: 0.3rem; list-style: none;
  background: #fff; border: 1px solid var(--line-strong); border-radius: var(--r-lg); box-shadow: var(--shadow-3);
}
.combobox__option { padding: 0.55rem 0.75rem; border-radius: var(--r-sm); font-size: var(--fs-sm); color: var(--ink-900); cursor: pointer; }
.combobox__option.is-active { background: var(--blue-50); color: var(--blue-700); }
.combobox__option[aria-selected="true"] { font-weight: 650; }
.combobox__empty { padding: 0.65rem 0.75rem; font-size: var(--fs-sm); color: var(--ink-500); }
@media (prefers-reduced-motion: no-preference) {
  .combobox__listbox:not([hidden]) { animation: tab-in var(--dur-base) var(--ease); }
}
@media (max-width: 30rem) {
  /* A touch keyboard eats half the viewport — cap the listbox shorter so at least a couple of results plus
     the "no match" hint stay visible above it on a small phone. */
  .combobox__listbox { max-height: 11rem; }
}
.field--invalid input { border-color: var(--red-700); }
.field .error { display: flex; gap: var(--s-2); color: var(--red-700); margin: var(--s-2) 0 0; font-size: var(--fs-sm); font-weight: 500; }
.req { color: var(--red-700); }
label.check,
.check { display: flex; gap: 0.625rem; align-items: flex-start; font-weight: 400; cursor: pointer; }
.check input { margin: 0.2rem 0 0; width: 1.125rem; height: 1.125rem; flex: none; accent-color: var(--blue-600); }
.checklist { list-style: none; display: grid; gap: 0.125rem; margin: 0; padding: 0; }
.checklist .check { align-items: center; min-height: var(--control-h-sm); padding: 0.125rem 0; }
.checklist .check input { margin: 0; }
.check__count { font-size: var(--fs-xs); font-weight: 600; color: var(--ink-500); font-variant-numeric: tabular-nums; }

/* ── Cards, alerts, badges, chips ── */
.card { background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--s-6); margin-top: var(--s-8); box-shadow: var(--shadow-1); }
.card--narrow { max-width: 32.5rem; margin-inline: auto; }
.card h1 { font-size: 1.625rem; margin-bottom: var(--s-2); }
.card h2 { font-size: 1.25rem; margin: var(--s-8) 0 var(--s-2); }
.card > :first-child { margin-top: 0; }
.card > :last-child, .card > form > :last-child { margin-bottom: 0; }

/* ── Social sign-in (login/register) ── */
.oauth-row { display: flex; flex-direction: column; gap: var(--s-3); margin: var(--s-5) 0; }
.oauth-btn { width: 100%; }
.oauth-consent { font-size: var(--fs-xs); color: var(--ink-500); margin: 0 0 var(--s-6); text-align: center; }
.auth-divider { display: flex; align-items: center; gap: var(--s-3); margin: var(--s-6) 0; color: var(--ink-400); font-size: var(--fs-sm); }
.auth-divider::before,
.auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.alert { border-radius: var(--r-md); padding: var(--s-3) var(--s-4); margin: var(--s-4) 0; border: 1px solid; font-size: var(--fs-sm); }
.alert p { margin: 0; }
.alert--error { background: var(--red-100); border-color: #f0b3ad; color: #7a1a12; }
.alert--success { background: var(--green-100); border-color: #a3d4bb; color: #0a4d31; }
.alert--info { background: var(--blue-50); border-color: #bcd3f6; color: var(--navy-800); }
.alert ul { margin: var(--s-2) 0 0 var(--s-5); }
.notice-bar { border-bottom: 1px solid var(--line); background: var(--green-100); color: #0a4d31; font-size: var(--fs-sm); }
.notice-bar .container { padding-block: var(--s-3); }

.badge { display: inline-flex; align-items: center; gap: 0.3rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-pill); padding: 0.2rem 0.6rem; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; color: var(--ink-700); line-height: 1.4; }
.badge--featured { background: var(--amber-500); border-color: var(--amber-500); color: var(--navy-950); }
.badge--new { background: var(--navy-900); border-color: var(--navy-900); color: #fff; }
.badge--reduced { background: var(--green-100); border-color: #a3d4bb; color: #0a4d31; }
.badge--urgent { background: var(--red-100); border-color: #f0b3ad; color: #7a1a12; }
.badge--verified { background: var(--green-100); border-color: #a3d4bb; color: #0a4d31; }
.badge--sold { background: var(--ink-900); border-color: var(--ink-900); color: #fff; }
.chip { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--control-h-sm); padding: 0 0.875rem; border-radius: var(--r-pill); background: var(--blue-50); border: 1px solid #cfe0fa; color: var(--navy-800); font-size: var(--fs-sm); font-weight: 550; text-decoration: none; transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
a.chip:hover { background: var(--blue-100); color: var(--navy-900); }
.chip .icon { width: 0.95em; height: 0.95em; }
.session-list { list-style: none; padding: 0; margin: 0 0 var(--s-4); }
.session-list li { display: flex; justify-content: space-between; gap: var(--s-4); align-items: center; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
.link-list { padding-left: var(--s-5); }

/* ── Breadcrumb, pagination ── */
.breadcrumb { padding: var(--s-4) 0 var(--s-2); font-size: var(--fs-sm); color: var(--ink-500); }
.breadcrumb ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; }
.breadcrumb li { display: inline-flex; align-items: center; gap: 0.5rem; }
.breadcrumb li + li::before { content: ""; width: 0.4rem; height: 0.4rem; border-right: 1.5px solid var(--ink-400); border-top: 1.5px solid var(--ink-400); transform: rotate(45deg); margin-right: 0.15rem; }
.breadcrumb a { color: var(--ink-500); text-decoration: none; }
.breadcrumb a:hover { color: var(--blue-700); text-decoration: underline; }
.breadcrumb [aria-current] { color: var(--ink-900); font-weight: 550; }
/* Phones: one line — a "back" link to the parent instead of the full trail. */
@media (max-width: 39.99rem) {
  .breadcrumb li { display: none; }
  .breadcrumb li:nth-last-child(2) { display: inline-flex; }
  .breadcrumb li:nth-last-child(2)::before { transform: rotate(-135deg); margin: 0 0 0 0.25rem; }
  .breadcrumb li:nth-last-child(2) a { font-weight: 600; color: var(--blue-700); }
}

.pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); margin: var(--s-10) 0 0; list-style: none; }
.pagination a,
.pagination span { display: inline-flex; align-items: center; justify-content: center; min-width: var(--control-h); min-height: var(--control-h); padding: 0 0.75rem; border-radius: var(--r-md); border: 1px solid var(--line); background: #fff; color: var(--ink-900); font-weight: 600; text-decoration: none; font-variant-numeric: tabular-nums; }
.pagination a:hover { border-color: var(--blue-600); color: var(--blue-700); }
.pagination [aria-current="page"] { background: var(--navy-900); border-color: var(--navy-900); color: #fff; }
.pagination .is-gap { border-color: transparent; background: none; min-width: 1.5rem; padding: 0; }
.pagination .is-disabled { color: var(--ink-400); background: var(--surface); }

/* ── Stats strip: a row of numbered tiles (admin dashboard; buyer dashboard, where a tile also links
   somewhere — li:has(a) hands the box styling to the link so it's the whole tile that's clickable). The
   icon moves into its own accent-tinted circle above the number — the thing that actually differentiates
   "a marketplace account summary" from "four identical grey boxes with a tiny icon inline." ── */
.stats { list-style: none; display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); margin: var(--s-6) 0; }
.stats li,
.stats a { position: relative; display: flex; flex-direction: column; gap: 0.6rem; padding: var(--s-4); border: 1px solid var(--line); border-radius: var(--r-md); background: #fff; overflow: hidden; }
.stats li:has(a) { padding: 0; border: 0; background: none; }
.stats a { color: inherit; text-decoration: none; height: 100%; transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease); }
.stats a:hover { border-color: var(--blue-300); box-shadow: var(--shadow-2); color: inherit; }
@media (prefers-reduced-motion: no-preference) { .stats a:hover { transform: translateY(-2px); } }
.stats__label { order: -1; font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; color: var(--ink-500); display: flex; align-items: center; gap: 0.5rem; }
.stats__label .icon { display: grid; place-items: center; width: 2rem; height: 2rem; padding: 0.4rem; box-sizing: border-box; border-radius: var(--r-sm); background: var(--blue-50); color: var(--blue-600); }
.stats__num { font-family: var(--font-brand); font-size: 2rem; font-weight: 800; letter-spacing: -0.02em; color: var(--navy-900); font-variant-numeric: tabular-nums; line-height: 1; }

/* ── Numbered steps list (homepage "how selling works" + the guest /sell landing page). Dark-on-navy by
   default; .steps--light (sell.css) overrides colours only for a light-background placement — the base
   list-style/layout rules below must stay here (not in a page-specific stylesheet) because both home.php
   and sell/landing.php use this component but don't both load home.css: without `list-style: none` here,
   the browser's native "1." marker rendered next to the manual .steps__n circle, i.e. "1. 1 / 2. 2 / 3. 3".
   The heading tag inside each step is NOT fixed: home.php nests it under its own "Sell..." <h2>, so its
   steps are correctly <h3>; sell/landing.php's steps are the first heading-level content after its <h1>
   (no intervening <h2> on that page), so its own steps are correctly <h2> — same component, same look,
   styled by class rather than by tag so the right heading level never needs the wrong visual treatment. ── */
.steps { list-style: none; display: grid; gap: var(--s-5); }
.steps li { display: flex; gap: var(--s-4); align-items: flex-start; padding: var(--s-4) var(--s-5); background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: var(--r-lg); }
.steps__n { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; flex: none; border-radius: 50%; background: var(--amber-500); color: var(--navy-950); font-weight: 750; }
.steps h2, .steps h3 { color: #fff; font-size: var(--fs-md); margin-bottom: 0.15rem; }
.steps p { margin: 0; color: rgba(255, 255, 255, 0.72); font-size: var(--fs-sm); }

/* ── Tables ── */
.table-wrap { overflow-x: auto; margin-top: var(--s-4); }
/* On a phone a wide table scrolls sideways inside its wrapper instead of squeezing every cell to two words per line. */
@media (max-width: 39.99rem) { .table-wrap > .table { min-width: 36rem; } }
.table { width: 100%; border-collapse: collapse; }
.table th,
.table td { text-align: left; padding: var(--s-3); border-bottom: 1px solid var(--line); font-size: var(--fs-sm); vertical-align: top; }
.table th { color: var(--ink-500); font-weight: 600; }
.table caption { text-align: left; font-weight: 650; padding-bottom: var(--s-3); }
.table__actions { white-space: nowrap; }
.table__actions form { margin: 0; }
.table--zebra tbody tr:nth-child(even) { background: var(--surface); }
.table--compact th,
.table--compact td { padding: var(--s-2) var(--s-3); }
.table tbody tr:last-child td { border-bottom: 0; }

/* ── Dash list: a bordered row with media/title/meta/actions — one definition shared by every screen that
   lists "things with a status and some actions" (seller dashboard, admin reservations, account reservations,
   moderation queues, the dev mail-preview index). Lives here, not in a single page's own CSS file, because
   each page loads app.css plus exactly one other page-scoped file — a component only one of those pages
   actually owned left every other page that referenced it (by class name, in good faith) silently
   unstyled. ── */
.dash-list { list-style: none; display: flex; flex-direction: column; gap: var(--s-3); }
.dash-item { display: grid; grid-template-columns: 5rem 1fr; gap: var(--s-4); align-items: center; padding: var(--s-3); border: 1px solid var(--line); border-radius: var(--r-md); background: #fff; }
/* Rows with no cover photo to show (admin/account reservation lists have no listing image in their own
   query) — without this, the grid's first 5rem track silently swallows .dash-item__body as if it were the
   media slot, wrapping the title to a near-unreadable column. */
.dash-item--compact { grid-template-columns: 1fr; }
.dash-item__media { width: 5rem; aspect-ratio: 4 / 3; border-radius: var(--r-sm); overflow: hidden; background: var(--surface-2); display: grid; place-items: center; }
.dash-item__media img { width: 100%; height: 100%; object-fit: cover; }
.dash-item__noimg { color: var(--ink-400); }
.dash-item__title { margin: 0 0 0.25rem; font-weight: 650; }
a.dash-item__title { color: var(--ink-900); text-decoration: none; }
a.dash-item__title:hover { color: var(--blue-700); }
.dash-item__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin: 0; font-size: var(--fs-sm); }
.dash-item__reason { display: flex; align-items: center; gap: 0.3rem; color: var(--red-700); }
.dash-item__actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }
.dash-item__actions form { margin: 0; }
/* The "Extend"/"Reduce price" inline reveal — a lighter-weight disclosure than the Reserve drawer (no
   multi-field buyer picker, just one or two fields), so it stays a <details> rather than a second dialog. */
.dash-item__reduce { position: relative; }
.dash-item__reduce[open] > summary { margin-bottom: var(--s-2); }
.dash-item__reduce .field-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s-2); padding: var(--s-3); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); }
.dash-item__reduce .field-row .input,
.dash-item__reduce .field-row .select { min-width: 10rem; width: auto; }
.dash-item__reduce .field { margin: 0; flex: 1 1 10rem; }
@media (min-width: 40rem) {
  .dash-item { grid-template-columns: 5rem 1fr auto; }
  .dash-item--compact { grid-template-columns: 1fr auto; }
  /* One right-aligned row of equal-height actions. (Was a stretched column: buttons wrapped in a <form>
     never stretched, so every row showed a ragged stack of different-width buttons.) */
  .dash-item__actions { grid-column: auto; justify-content: flex-end; max-width: 34rem; }
  /* a live listing has six actions: from 72rem there is room for them on one line */
  @media (min-width: 72rem) { .dash-item__actions { max-width: 46rem; } }
  .dash-item__reduce[open] { flex-basis: 100%; }
}

/* ── Detail list: label/value pairs for a single record's admin detail view (reservation detail today;
   generic enough for the next one). A plain <dl> has no styling of its own in any browser worth matching,
   so this was rendering as default UA text before. ── */
.detail-list { display: grid; grid-template-columns: 1fr; gap: 0; margin: var(--s-5) 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.detail-list dt,
.detail-list dd { padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); }
.detail-list dt { font-weight: 600; font-size: var(--fs-sm); color: var(--ink-500); background: var(--surface); }
.detail-list dd { margin: 0; }
.detail-list dt:last-of-type,
.detail-list dd:last-of-type { border-bottom: 0; }
@media (min-width: 36rem) {
  .detail-list { grid-template-columns: 14rem 1fr; }
  .detail-list dt { border-right: 1px solid var(--line); }
}

/* ── Choice row: a radio "card" for picking who a reservation is for (member / existing lead / walk-in).
   The fields it reveals sit in a shared panel directly under the chosen option, not just more stacked
   fields indistinguishable from the next radio's own fields. One, two or three revealed inputs must all
   look right, so the panel is a plain padded box, not a fused/attached input stack. ── */
.choice-row { margin: var(--s-4) 0; border: 1px solid var(--line-strong); border-radius: var(--r-md); overflow: hidden; transition: border-color 0.15s var(--ease); }
.choice-row:has(input:checked) { border-color: var(--blue-600); }
.choice { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-3); font-weight: 600; font-size: var(--fs-sm); cursor: pointer; background: var(--surface); }
.choice:has(input:checked) { background: var(--blue-50); color: var(--navy-900); }
.choice input[type="radio"] { width: 1.125rem; height: 1.125rem; accent-color: var(--blue-600); flex: none; }
.choice-row .input { border: 0; border-radius: 0; border-top: 1px solid var(--line); }
.choice-row .input:focus { box-shadow: inset 0 0 0 2px rgba(0, 82, 204, 0.25); }

/* ── Homepage category tabs — deliberately NOT styled like the hero's search-intent picker (no icons, no
   pill/border treatment, inline with its own section heading instead of a separate full-width bar) so it
   reads as "which content is showing below" rather than a second copy of the same search control. The hero
   picker sets search intent; this switches which discovery content (body types/featured/popular makes/just
   listed) is currently shown — same underlying .tabs mechanism, a clearly different job and a clearly
   different look. ── */
.browse-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s-3) var(--s-6); margin-bottom: var(--s-2); }
.browse-head h2 { font-family: var(--font); font-weight: 720; font-size: var(--fs-h2); } /* not Archivo here — this is a content switcher, not a marketing headline */
.tabs--quiet .tabs__list { border-bottom: 0; flex: none; gap: var(--s-5); }
.tabs--quiet .tabs__tab { min-height: auto; padding: 0.3rem 0; margin: 0; font-size: var(--fs-sm); font-weight: 600; color: var(--ink-500); border-bottom: 2px solid transparent; }
.tabs--quiet .tabs__tab:hover { color: var(--ink-900); }
.tabs--quiet .tabs__tab[aria-selected="true"] { color: var(--navy-900); border-bottom-color: var(--amber-500); font-weight: 700; }

/* ── Tabs: same-page panel switching (see partials/tabs.php). A page-to-page switcher that looks the same
   is .category-switch, further up — same visual language, different job. ── */
.tabs__list { display: flex; gap: var(--s-1); border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.tabs__list::-webkit-scrollbar { display: none; }
.tabs__tab { flex: none; display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--control-h); padding: 0 var(--s-1); margin: 0 var(--s-3) -1px 0; border: 0; border-bottom: 2px solid transparent; background: none; font: inherit; font-size: var(--fs-sm); font-weight: 650; color: var(--ink-500); cursor: pointer; white-space: nowrap; transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.tabs__tab:hover { color: var(--ink-900); }
.tabs__tab[aria-selected="true"] { color: var(--blue-700); border-bottom-color: var(--blue-600); }
.tabs__tab .badge-count { margin-left: 0.2rem; background: var(--surface-2); color: var(--ink-700); }
.tabs__tab[aria-selected="true"] .badge-count { background: var(--blue-100); color: var(--blue-700); }
.tabs__panel { padding-top: var(--s-6); }
.tabs__panel[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .tabs__panel:not([hidden]) { animation: tab-in var(--dur-base) var(--ease); }
}
@keyframes tab-in { from { opacity: 0; transform: translateY(4px); } }

/* ── Vehicle card (used on home, search, detail). Image-led and commercially mature: the photo carries the
   card (no border fighting it for attention — definition comes from shadow + the image's own edge), a
   bottom scrim keeps badges/photo-count legible on any image without a solid dark pill, and the image
   itself lifts slightly on hover so the card feels like a real listing, not a static tile. ── */
.vcard { position: relative; display: flex; flex-direction: column; background: #fff; border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-1); transition: box-shadow 0.2s var(--ease), transform 0.2s var(--ease); }
.vcard:hover { box-shadow: var(--shadow-3); }
@media (prefers-reduced-motion: no-preference) { .vcard:hover { transform: translateY(-3px); } }
.vcard:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; }
.vcard__media { position: relative; aspect-ratio: 16 / 10; background: var(--surface-2); overflow: hidden; } /* 2026-10: was 4/3 — 16:10 matches the Stitch redesign spec and shows more width/less height, standard for automotive listing photography */
.vcard__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s var(--ease); }
.vcard__noimage { display: grid; place-items: center; width: 100%; height: 100%; color: var(--ink-400); }
.vcard__noimage .icon { width: 2rem; height: 2rem; }
@media (prefers-reduced-motion: no-preference) { .vcard:hover .vcard__media img { transform: scale(1.045); } }
.vcard__media::after { content: ""; position: absolute; inset: auto 0 0 0; height: 55%; background: linear-gradient(to top, rgba(6, 18, 36, 0.5), rgba(6, 18, 36, 0) 70%); pointer-events: none; }
.vcard__badges { position: absolute; top: var(--s-3); left: var(--s-3); z-index: 1; display: flex; flex-wrap: wrap; gap: var(--s-1); max-width: calc(100% - 1.5rem); }
.vcard__count { position: absolute; right: var(--s-3); bottom: var(--s-3); z-index: 1; display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.2rem 0.6rem; border-radius: var(--r-pill); background: rgba(6, 18, 36, 0.55); backdrop-filter: blur(3px); color: #fff; font-size: var(--fs-xs); font-weight: 600; }
.vcard__save { position: absolute; top: var(--s-3); right: var(--s-3); margin: 0; }

/* A round, translucent icon button — the "save" heart on a card image, and reused wherever a bare toggle is
   needed. z-index: 2 because .vcard__title a::after (below) lays a z-index: 1 full-card click target over
   the whole card for a larger tap target — without this, that overlay silently eats every click meant for
   the heart button, in every real browser, not just a strict-mode test harness (found exactly this way). */
.icon-toggle { position: absolute; top: var(--s-3); right: var(--s-3); z-index: 2; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.92); color: var(--ink-700); cursor: pointer; box-shadow: var(--shadow-1); transition: background-color 0.15s var(--ease), color 0.15s var(--ease), transform 0.15s var(--ease); text-decoration: none; }
.icon-toggle:hover { background: #fff; color: var(--red-700); }
.icon-toggle:active { transform: scale(0.94); }
.icon-toggle .icon { width: 1.15rem; height: 1.15rem; fill: none; stroke-width: 2; }
.icon-toggle.is-active { color: var(--red-700); }
.icon-toggle.is-active .icon { fill: currentColor; }

/* An active saved/compared state on an ordinary secondary button. */
.btn--secondary.is-active { color: var(--blue-700); border-color: var(--blue-300); background: var(--blue-50); }
.btn--secondary.is-active .icon { fill: currentColor; }
.vcard__body { display: flex; flex-direction: column; gap: 0.3rem; padding: var(--s-4); flex: 1; }
.vcard__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.125rem var(--s-2); margin: 0; }
.price { font-size: 1.5625rem; font-weight: 800; letter-spacing: -0.03em; color: var(--navy-900); font-variant-numeric: tabular-nums; line-height: 1.1; }
.price-note { font-size: var(--fs-xs); font-weight: 600; color: var(--ink-500); }
.price-was { font-size: var(--fs-sm); color: var(--ink-500); text-decoration: line-through; font-variant-numeric: tabular-nums; }
.price-drop { font-size: var(--fs-xs); font-weight: 650; color: var(--green-700); }
.vcard__title { margin: 0.1rem 0 0.2rem; font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.012em; line-height: 1.3; color: var(--ink-700); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vcard__title a { color: inherit; text-decoration: none; }
.vcard__title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.vcard__title a:hover { color: var(--blue-700); }
.vcard__title a:focus-visible { outline: none; }
.specs { list-style: none; display: flex; flex-wrap: wrap; gap: 0.25rem 0; margin: 0; font-size: var(--fs-sm); color: var(--ink-500); }
.specs li { display: inline-flex; align-items: center; }
.specs li + li::before { content: ""; width: 3px; height: 3px; border-radius: 50%; background: var(--ink-400); margin: 0 0.5rem; }
.vcard__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; margin: auto 0 0; padding-top: 0.6rem; border-top: 1px solid var(--line); font-size: var(--fs-xs); color: var(--ink-500); }
.vcard__meta span { display: inline-flex; align-items: center; gap: 0.3rem; }
.vcard__meta .icon { width: 1em; height: 1em; }
.verified-tick { color: var(--green-700); }

.vgrid { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); list-style: none; }
.vgrid > li { display: flex; min-width: 0; }
.vgrid > li > .vcard { flex: 1 1 auto; min-width: 0; }
/* On phones, home-page card sections scroll sideways instead of stacking twenty tall cards. */
@media (max-width: 39.99rem) {
  .vgrid--rail { display: flex; gap: var(--s-4); overflow-x: auto; scroll-snap-type: x proximity; scroll-padding-inline: var(--gutter); margin-inline: calc(-1 * var(--gutter)); padding: var(--s-1) var(--gutter) var(--s-4); scrollbar-width: none; }
  .vgrid--rail::-webkit-scrollbar { display: none; }
  .vgrid--rail > li { flex: 0 0 min(82%, 18rem); scroll-snap-align: start; }
}

/* ── Empty / error / loading states ── */
.state { text-align: center; max-width: 34rem; margin: var(--s-12) auto; padding: var(--s-8) var(--s-4); }
.state__icon { display: grid; place-items: center; width: 4rem; height: 4rem; margin: 0 auto var(--s-4); border-radius: 50%; background: var(--blue-50); color: var(--blue-600); }
.state__icon .icon { width: 1.75rem; height: 1.75rem; }
.state h1,
.state h2 { margin-bottom: var(--s-3); }
.state p { color: var(--ink-500); }
.state__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-3); margin-top: var(--s-5); }
.skeleton { position: relative; overflow: hidden; background: var(--surface-2); border-radius: var(--r-sm); min-height: 1rem; }
@media (prefers-reduced-motion: no-preference) {
  .skeleton::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent); animation: shimmer 1.4s infinite; }
  @keyframes shimmer { to { transform: translateX(100%); } }
}

/* ── Prose: plain-text, user/staff-authored long-form copy (listing descriptions, CMS pages) — shared across
   the vehicle detail page, moderation review and the static/legal pages ── */
.prose { white-space: pre-line; max-width: 68ch; color: var(--ink-700); }
/* Structured CMS pages (help, terms, privacy…): real headings and paragraphs instead of one pre-line block. */
.prose--structured { white-space: normal; }
.prose--structured p { white-space: pre-line; margin: 0 0 var(--s-4); }
.prose--structured h2 { font-size: 1.25rem; margin: var(--s-10) 0 var(--s-3); padding-top: var(--s-6); border-top: 1px solid var(--line); }
.prose--structured h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.prose--structured h3 { font-size: var(--fs-md); margin: var(--s-6) 0 var(--s-1); color: var(--ink-900); }
.state--error { margin-block: var(--section-y); }
.state__code { margin: 0 0 var(--s-2); font-family: var(--font-brand); font-size: 3.5rem; font-weight: 800; line-height: 1; letter-spacing: -0.03em; color: var(--blue-600); }
.state--error h1 { font-size: var(--fs-h2); margin-bottom: var(--s-2); }
.state__ref { margin-top: var(--s-6); font-size: var(--fs-xs); }

/* ── Account-type pick (individual/dealer) — step 0 of registration, plain links (works with JS off). Bigger
   and more descriptive than .category-pick below: a once-ever decision with real consequences, not a
   frequent 3-way toggle. ── */
.card--intent { padding: var(--s-8) var(--s-6); }
.intent-pick { display: grid; gap: var(--s-3); margin-top: var(--s-6); }
.intent-pick__option { display: flex; align-items: center; gap: var(--s-4); padding: var(--s-5); border: 1.5px solid var(--line); border-radius: var(--r-lg); text-decoration: none; color: var(--ink-900); transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease); }
.intent-pick__option:hover { border-color: var(--blue-600); background: var(--blue-50); color: var(--ink-900); box-shadow: var(--shadow-1); }
.intent-pick__icon { display: grid; place-items: center; width: 3rem; height: 3rem; flex: none; border-radius: var(--r-md); background: var(--navy-900); color: #fff; }
.intent-pick__icon .icon { width: 1.5rem; height: 1.5rem; }
.intent-pick__body { display: flex; flex-direction: column; gap: 0.15rem; flex: 1; min-width: 0; }
.intent-pick__title { font-weight: 700; font-size: 1.0625rem; letter-spacing: -0.01em; }
.intent-pick__desc { font-size: var(--fs-sm); color: var(--ink-500); }
.intent-pick__arrow { width: 1.25rem; height: 1.25rem; flex: none; color: var(--ink-400); }
.intent-pick__option:hover .intent-pick__arrow { color: var(--blue-600); }

/* ── Category pick (car/motorbike/bicycle radios) — the sell wizard's first step and the homepage hero ── */
.category-pick { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-3); border: 0; padding: 0; margin: 0 0 var(--s-6); }
.category-pick__option { display: flex; flex-direction: column; align-items: center; gap: var(--s-2); padding: var(--s-4) var(--s-2); border: 1.5px solid var(--line); border-radius: var(--r-md); cursor: pointer; text-align: center; transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease); }
.category-pick__option:has(input:checked) { border-color: var(--blue-600); background: var(--blue-50); }
.category-pick__option:has(input:focus-visible) { outline: 2px solid var(--blue-600); outline-offset: 2px; }
.category-pick__option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.category-pick__icon .icon { width: 1.75rem; height: 1.75rem; color: var(--ink-500); }
.category-pick__option:has(input:checked) .category-pick__icon .icon { color: var(--blue-600); }
.category-pick__label { font-size: var(--fs-sm); font-weight: 600; color: var(--ink-700); }
/* Compact: inline icon + label, for a tight space like the search panel instead of a full wizard step.
   Grouped in one shared pill container (2026-10 redesign, Stitch direction) — the selected option lifts to
   a white/bordered surface inside it, reading as one segmented control rather than 3 separate buttons. */
.category-pick--compact { display: inline-flex; grid-template-columns: none; gap: 0.2rem; margin: 0 0 var(--s-3); padding: 0.3rem; background: var(--surface); border-radius: var(--r-md); }
.category-pick--compact .category-pick__option { flex-direction: row; padding: 0.55rem var(--s-4); border: 0; border-radius: var(--r-sm); }
.category-pick--compact .category-pick__option:has(input:checked) { background: #fff; box-shadow: var(--shadow-1); }
.category-pick--compact .category-pick__icon .icon { width: 1.25rem; height: 1.25rem; }

/* ── Category switch (car/motorbike/bicycle) — shared across search and dealer bulk import ── */
.category-switch { display: flex; gap: var(--s-2); margin: var(--s-3) 0 var(--s-5); border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.category-switch::-webkit-scrollbar { display: none; }
.category-switch a { flex: none; }
.category-switch a { display: inline-flex; align-items: center; gap: var(--s-2); padding: var(--s-3) var(--s-1); margin-bottom: -1px; border-bottom: 2px solid transparent; font-size: var(--fs-sm); font-weight: 600; color: var(--ink-500); text-decoration: none; transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.category-switch a .icon { width: 1.1rem; height: 1.1rem; }
.category-switch a:hover { color: var(--ink-900); }
.category-switch a.is-active { color: var(--blue-700); border-bottom-color: var(--blue-600); }

/* ── Modal (centered <dialog>) and drawer (edge-anchored <dialog>) — see partials/modal.php and app.js's
   openDialog()/closeDialog(). Both are the browser's native top-layer, so they're always above everything
   else with no z-index bookkeeping; ::backdrop is the dim-behind layer. The lightbox (detail.css) is a
   .modal variant, not a separate pattern. ── */
.modal,
.drawer { border: 0; box-shadow: var(--shadow-3); color: var(--ink-900); background: #fff; }
.modal::backdrop,
.drawer::backdrop { background: rgba(6, 18, 36, 0.5); }
.modal { padding: 0; border-radius: var(--r-lg); max-width: 30rem; width: calc(100% - 2rem); max-height: calc(100% - 2rem); }
.modal__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-5) var(--s-5) var(--s-4); border-bottom: 1px solid var(--line); }
.modal__head h2 { font-size: var(--fs-lg); }
.modal__close { flex: none; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border: 0; border-radius: 50%; background: none; color: var(--ink-500); cursor: pointer; }
.modal__close:hover { background: var(--surface); color: var(--ink-900); }
.modal__body { padding: var(--s-5); overflow-y: auto; }
.modal__foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s-3); padding: var(--s-4) var(--s-5); border-top: 1px solid var(--line); background: var(--surface); border-radius: 0 0 var(--r-lg) var(--r-lg); }
.modal__foot .btn,
.modal__foot .button { flex: 1 1 auto; }
.modal--danger .modal__head { color: var(--red-700); }

/* The drawer slides in from the right on desktop, from the bottom on phones — a mobile "sheet" feels native, a
   side panel does not. Position: fixed inset values (not transform) so safe-area-inset-* still apply. */
/* display is deliberately only ever set for dialog[open] — the native <dialog> UA stylesheet already does
   `dialog:not([open]) { display: none }`, and an unconditional `.drawer { display: flex }` here would be an
   author-origin rule that outranks that UA rule regardless of selector specificity, permanently laying the
   drawer out (position: fixed, full viewport width) and intercepting clicks even while "closed". */
.drawer { position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: 100%; max-height: min(85vh, 100%); border-radius: var(--r-lg) var(--r-lg) 0 0; flex-direction: column; }
.drawer[open] { display: flex; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-4) var(--gutter); border-bottom: 1px solid var(--line); flex: none; }
.drawer__head h2 { font-size: var(--fs-lg); }
.drawer__close { flex: none; display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border: 0; border-radius: 50%; background: none; color: var(--ink-900); cursor: pointer; }
.drawer__close:hover { background: var(--surface); }
.drawer__body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: var(--s-2) var(--gutter) calc(var(--s-4) + env(safe-area-inset-bottom)); }
@media (min-width: 48rem) {
  .drawer { inset: 0 0 0 auto; width: min(26rem, 100%); max-width: 26rem; max-height: 100%; border-radius: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  dialog.modal[open] { animation: modal-in var(--dur-slow) var(--ease); }
  dialog.modal[open]::backdrop { animation: fade-in var(--dur-slow) var(--ease); }
  dialog.drawer[open] { animation: sheet-in var(--dur-slow) var(--ease); }
  dialog.drawer[open]::backdrop { animation: fade-in var(--dur-slow) var(--ease); }
}
@media (min-width: 48rem) and (prefers-reduced-motion: no-preference) { dialog.drawer[open] { animation-name: drawer-in; } }
@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } }
@keyframes sheet-in { from { transform: translateY(100%); } }
@keyframes drawer-in { from { transform: translateX(100%); } }
@keyframes fade-in { from { opacity: 0; } }

/* ── Toast notifications: a transient, dismissible confirmation (favourited, saved, sent). Built once by
   app.js's toast() helper; no toast anywhere blocks input or needs a click to make progress. ── */
.toast-region { position: fixed; z-index: 150; left: 50%; bottom: calc(var(--s-6) + env(safe-area-inset-bottom)); transform: translateX(-50%); display: flex; flex-direction: column-reverse; gap: var(--s-2); width: min(92vw, 26rem); pointer-events: none; }
.toast { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-4); border-radius: var(--r-md); background: var(--navy-950); color: #fff; font-size: var(--fs-sm); font-weight: 600; box-shadow: var(--shadow-3); pointer-events: auto; }
.toast .icon { flex: none; color: var(--blue-300); }
.toast--success .icon { color: #7fe2b4; }
.toast--error { background: var(--red-700); }
.toast--error .icon { color: #ffd4cf; }
.toast__close { margin-left: auto; flex: none; display: grid; place-items: center; width: 1.75rem; height: 1.75rem; border: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.14); color: #fff; cursor: pointer; }
.toast__close:hover { background: rgba(255, 255, 255, 0.24); }
@media (min-width: 48rem) { .toast-region { left: auto; right: var(--s-6); bottom: var(--s-6); transform: none; } }
@media (prefers-reduced-motion: no-preference) {
  .toast { animation: toast-in var(--dur-base) var(--ease); }
  .toast.is-leaving { animation: toast-out var(--dur-fast) var(--ease) forwards; }
}
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(4px); } }

/* ── Auth screens (login/register/forgot/reset/…) — partials/auth_side_panel.php. A two-column shell on a
   wide viewport (brand/trust panel + the existing form, untouched), contained within the normal page
   container rather than full-bleed (simpler, no negative-margin viewport-edge arithmetic to get wrong). The
   panel is decorative, aria-hidden, and simply not rendered in the layout flow below 60rem so a phone stays
   focused on the one task. ── */
.auth-shell { display: flex; flex-direction: column; }
/* Sign-in / register card: the primary button spans the card and the links below it are evenly spaced. */
.auth-shell .card form button[type="submit"].btn { width: 100%; }
.auth-shell .card > p.muted, .auth-shell .card form + p { margin: var(--s-4) 0 0; }
.auth-shell .card > p.muted + p.muted { margin-top: var(--s-2); }
.auth-shell__form { display: flex; align-items: center; justify-content: center; flex: 1; padding: var(--s-8) 0; }
.auth-shell .card--narrow { margin-top: 0; width: 100%; box-shadow: 0 24px 48px -20px rgba(6, 18, 36, 0.25), 0 2px 6px rgba(6, 18, 36, 0.06); border-top: 3px solid var(--blue-600); }
.auth-panel { display: none; }
@media (min-width: 60rem) {
  .auth-shell { flex-direction: row; align-items: stretch; gap: var(--s-12); margin-block: var(--s-8); min-height: calc(100vh - var(--header-h) - 2 * var(--s-8)); }
  .auth-panel {
    position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: center; gap: var(--s-8); flex: 1 1 40%;
    background: linear-gradient(165deg, var(--navy-950) 0%, var(--navy-900) 55%, var(--navy-800) 100%); color: #fff; border-radius: var(--r-lg); padding: var(--s-12);
  }
  .auth-panel::before { content: ""; position: absolute; inset: 0; background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.07) 1px, transparent 0); background-size: 28px 28px; mask-image: radial-gradient(circle at 30% 20%, rgba(0, 0, 0, 0.9), transparent 70%); pointer-events: none; }
  .auth-panel > * { position: relative; }
  .auth-panel__lockup { display: flex; align-items: center; gap: var(--s-4); pointer-events: none; text-decoration: none; }
  .auth-panel__mark { width: 2.25rem; height: 2.25rem; flex: none; fill: none; stroke: #fff; stroke-width: 13; stroke-linecap: round; stroke-linejoin: round; }
  .auth-panel__mark .auth-panel__mark-accent { stroke: var(--amber-500); }
  .auth-panel__wordmark { display: flex; flex-direction: column; font-family: var(--font-brand); line-height: 1.1; }
  .auth-panel__wordmark span { font-size: 1.25rem; font-weight: 800; color: #fff; letter-spacing: -0.01em; }
  .auth-panel__wordmark b { font-size: 0.8125rem; font-weight: 650; color: var(--blue-300); letter-spacing: 0.08em; text-transform: uppercase; }
  .auth-panel__lead { margin: 0; font-size: var(--fs-lg); color: rgba(255, 255, 255, 0.82); max-width: 26ch; }
  .auth-panel__points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-6); }
  .auth-panel__points li { display: flex; gap: var(--s-4); align-items: flex-start; }
  .auth-panel__points h2 { font-size: var(--fs-md); font-weight: 650; letter-spacing: -0.01em; margin-bottom: 0.15rem; color: #fff; }
  .auth-panel__points p { margin: 0; font-size: var(--fs-sm); color: rgba(255, 255, 255, 0.72); }
  .auth-panel__icon { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; flex: none; border-radius: var(--r-md); background: rgba(255, 255, 255, 0.12); color: #fff; }
  .auth-shell__form { flex: 1 1 60%; padding: var(--s-8) 0; }
}
.hero-plain { padding: var(--s-16) 0 var(--s-8); }
@media (max-width: 30rem) { .card { padding: var(--s-4); } .session-list li { flex-direction: column; align-items: flex-start; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }

/* ── Account area (My account, dealer console, notifications): one column width, one tab bar, one rhythm.
   Global on purpose — see account.css. ── */
.account-page { padding: var(--page-top) 0 var(--page-bottom); max-width: 60rem; }
.account-page h1 { margin-bottom: var(--s-2); }
/* Same full-width grid as the .stats row directly above it, so the two blocks share their left and right
   edges; tiles in a row are always equal height, whether or not a label wraps. */
.account-hub { list-style: none; display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr)); margin: var(--s-6) 0; }
.account-hub a { display: flex; align-items: center; gap: var(--s-3); height: 100%; min-height: var(--control-h-lg); padding: var(--s-3) var(--s-4); border: 1px solid var(--line); border-radius: var(--r-md); background: #fff; text-decoration: none; color: var(--ink-900); line-height: 1.3; transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease); }
.account-hub a:hover { border-color: var(--blue-300); box-shadow: var(--shadow-2); color: var(--ink-900); }
.account-hub .icon { width: 1.25rem; height: 1.25rem; color: var(--blue-600); flex: none; }
.account-hub span { font-weight: 620; }

.ss-list { list-style: none; display: grid; gap: var(--s-3); margin-top: var(--s-6); }
.ss-item { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); padding: var(--s-4); border: 1px solid var(--line); border-radius: var(--r-md); background: #fff; }
.ss-item__body { flex: 1 1 16rem; min-width: 0; }
.ss-item__name { margin: 0 0 0.25rem; font-weight: 650; }
.ss-item__name a { color: var(--ink-900); text-decoration: none; }
.ss-item__name a:hover { color: var(--blue-700); }
.ss-item__meta { margin: 0; font-size: var(--fs-sm); color: var(--ink-500); }
.ss-item__actions { display: flex; align-items: center; gap: var(--s-3); flex: none; }
.ss-item__actions form { margin: 0; }

/* Dashboard preview sections (account/index.php) */
.dash-section { margin-top: var(--s-10); }
.dash-section__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-4); }
.dash-section__head h2 { margin: 0; }
.dash-section__head a { font-size: var(--fs-sm); font-weight: 600; }
.ss-list--compact,
.conv-list--compact { margin-top: 0; }
.vgrid--compact { grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr)); }
.account-page .console-nav, .console-nav { margin-top: var(--s-4); }
.account-page h2 { margin-top: var(--s-8); margin-bottom: var(--s-2); font-size: 1.25rem; }
.account-page form > .btn, .account-page .table-wrap + .btn { margin-top: var(--s-4); }
.account-page .card h2:first-child, .account-page .dash-section__head h2 { margin-top: 0; }
/* A form field never stretches the full 60rem column. */
.account-page .field, .account-page .sfield { max-width: 30rem; }
.account-page .field-row { max-width: 44rem; }
.account-page .field-row .field, .account-page .field-row .sfield { max-width: none; }

/* ── Admin shell: a permission-aware sidebar beside every admin and moderation page (partials/admin_nav).
   The page's own children all sit in the second column; the nav spans every row of the first. Below 64rem the
   sidebar is a collapsed menu above the page. Global: admin pages load different page stylesheets. ── */
.admin-page, .mod-page { padding: var(--page-top) 0 var(--page-bottom); }
.admin-nav { margin-bottom: var(--s-6); }
.admin-nav__menu { border: 1px solid var(--line); border-radius: var(--r-md); background: #fff; }
.admin-nav__menu > summary { display: flex; align-items: center; min-height: var(--control-h); padding: 0 var(--s-4); font-weight: 650; cursor: pointer; }
.admin-nav__list { list-style: none; padding: 0 var(--s-2) var(--s-2); }
.admin-nav__group { margin: var(--s-2) 0 var(--s-1); padding: 0 var(--s-4); font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-500); }
.admin-nav__list a { display: flex; align-items: center; gap: var(--s-3); min-height: var(--control-h-sm); padding: 0 var(--s-2); border-radius: var(--r-sm); color: var(--ink-700); font-size: var(--fs-sm); font-weight: 600; text-decoration: none; }
.admin-nav__list a .icon { width: 1rem; height: 1rem; color: var(--ink-500); }
.admin-nav__list a:hover { background: var(--surface); color: var(--ink-900); }
.admin-nav__list a[aria-current] { background: var(--blue-50); color: var(--blue-700); }
.admin-nav__list a[aria-current] .icon { color: var(--blue-600); }
@media (min-width: 64rem) {
  .admin-page:has(> .admin-nav), .mod-page:has(> .admin-nav) { display: grid; grid-template-columns: 14rem minmax(0, 1fr); column-gap: var(--s-8); align-content: start; max-width: none; }
  .admin-page > *, .mod-page > * { grid-column: 2; min-width: 0; }
  .admin-page > .admin-nav, .mod-page > .admin-nav { grid-column: 1; grid-row: 1 / span 200; position: sticky; top: calc(var(--header-h) + var(--s-4)); align-self: start; margin: 0; max-height: calc(100vh - var(--header-h) - var(--s-8)); overflow-y: auto; }
  /* always expanded on desktop, whatever the <details> state: the summary is hidden and the content forced visible */
  .admin-nav__menu > summary { display: none; }
  .admin-nav__menu { padding-top: var(--s-2); }
  .admin-nav__menu::details-content { content-visibility: visible; display: block; block-size: auto; }
  .admin-page > .card .field, .admin-page > .card .sfield, .admin-page > form .field, .admin-page > form .sfield { max-width: 34rem; }
  .admin-page > .lead { max-width: 60ch; }
}


/* ── Guides on marketplace pages (partials/guide_links) and seller guidance in the sell wizard ── */
.guide-teasers { margin: var(--s-10) 0 0; padding: var(--s-5) var(--s-6); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); }
.guide-teasers h2 { font-size: 1.125rem; margin: 0 0 var(--s-3); }
.guide-teasers ul { list-style: none; display: grid; gap: var(--s-2); margin: 0; padding: 0; }
.guide-teasers a { display: inline-flex; align-items: flex-start; gap: var(--s-2); font-weight: 600; }
.guide-teasers .icon { flex: none; width: 1.1rem; height: 1.1rem; margin-top: 0.2em; color: var(--ink-400); }
@media (min-width: 48rem) { .guide-teasers ul { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--s-2) var(--s-6); } }
.sell-tips { margin: var(--s-5) 0; padding: var(--s-4) var(--s-5); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); }
.sell-tips summary { font-weight: 700; cursor: pointer; }
.sell-tips ul { margin: var(--s-3) 0 0; padding-left: 1.25em; display: grid; gap: var(--s-2); font-size: var(--fs-sm); line-height: 1.55; }
.sell-tips p { margin: var(--s-3) 0 0; font-size: var(--fs-sm); }
