/* ==========================================================================
   JDM HUNTER - 25+ YEAR CAR FINDER & MARKET TRACKER DESIGN SYSTEM
   Modern Japanese Automotive Enthusiast Aesthetic
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Outfit:wght@300;400;500;600;700;800;900&family=Space+Grotesk:wght@500;700&display=swap');

:root {
  /* --------------------------------------------------------------------
     Color Palette — Light Format

     Three distinct surface tiers, in stacking order:
       --bg-main     the page canvas (cool neutral)
       --bg-surface  elevated panels sitting ON the canvas (cards, sidebar)
       --bg-inset    recessed blocks sitting INSIDE a white panel
                     (price box, spec chips, modal sub-panels)

     bg-inset is load-bearing: without it, elements nested inside a white
     card render white-on-white and the whole layout reads flat.
     -------------------------------------------------------------------- */
  --bg-main: #eff2f7;
  --bg-surface: #ffffff;
  --bg-card: #ffffff;
  --bg-card-hover: #f7f9fc;
  --bg-inset: #f2f5fa;
  --bg-glass: rgba(255, 255, 255, 0.82);
  --bg-overlay: rgba(11, 18, 32, 0.6);

  --border-subtle: #e3e8f0;
  --border-strong: #c5cedd;
  --border-focus: #2563eb;

  /* Text Colors — true ink rather than blue-black, for crisper contrast */
  --text-primary: #0b1220;
  --text-secondary: #515f78;
  --text-muted: #8593a9;
  --text-inverse: #0b1220;

  /* JDM Brand & Status Accents — tuned for legibility as text/borders
     against a white panel (the dark-theme values were too light to read). */
  --accent-red: #d81e46;       /* Type-R / Nismo Red — the signature accent */
  --accent-red-glow: rgba(216, 30, 70, 0.22);
  --accent-blue: #1f4fd8;      /* R34 Bayside Blue */
  --accent-blue-light: #1a41b8;
  --accent-gold: #a55f00;      /* Auction Top Grade Gold */
  --accent-emerald: #067a55;   /* Great Deal Green */
  --accent-cyan: #0f6b86;      /* Turbo Boost Cyan */
  --accent-purple: #6d28d9;    /* Midnight Purple */

  /* Typography */
  --font-main: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-heading: 'Space Grotesk', var(--font-main);
  --font-mono: 'JetBrains Mono', monospace;

  /* Shadows & Radius */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-full: 9999px;

  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06), 0 4px 10px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 4px 10px rgba(15, 23, 42, 0.08), 0 10px 24px rgba(15, 23, 42, 0.1);
  --shadow-lg: 0 8px 16px rgba(15, 23, 42, 0.1), 0 20px 45px rgba(15, 23, 42, 0.16);
  --shadow-glow: 0 0 20px rgba(37, 99, 235, 0.25);

  --transition-fast: 0.15s ease;
  --transition-normal: 0.25s ease;
  --transition-smooth: 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Base Reset */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 16px;
  scroll-behavior: smooth;
  /* `clip`, not `hidden`. overflow-x:hidden makes the element a scroll
     container, which silently disables `position: sticky` on every descendant
     (it was stopping the results/sort bar from sticking). `clip` suppresses
     the same horizontal overflow without creating a scrollport. */
  overflow-x: clip;
}

body {
  background-color: var(--bg-main);
  color: var(--text-primary);
  font-family: var(--font-main);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  overflow-x: clip; /* see note on html above — `hidden` would break sticky */
  display: flex;
  flex-direction: column;
}

/* Utility Links */
a {
  color: var(--accent-blue-light);
  text-decoration: none;
  transition: color var(--transition-fast);
}

a:hover {
  color: #93c5fd;
  text-decoration: underline;
}

button, input, select {
  font-family: inherit;
}

/* ==========================================================================
   MASTHEAD — the dark band (header + hero) that bookends the light
   inventory area with the footer.

   Rather than restyling every child control for the dark background, these
   containers simply REDEFINE the theme tokens for everything inside them.
   Buttons, chips, inputs and pills inherit automatically, so there is one
   place to tune the dark context instead of a parallel set of overrides.
   ========================================================================== */
.app-header,
.hero-section,
.app-footer {
  --bg-surface: #161c27;
  --bg-card: #161c27;
  --bg-card-hover: #1e2532;
  --bg-inset: #1b2230;
  --border-subtle: #29313f;
  --border-strong: #3c4657;

  --text-primary: #f6f8fb;
  --text-secondary: #9dabc0;
  --text-muted: #75839a;

  /* Accents step back up to their luminous values — the light-theme ones
     are too dark to read against ink. */
  --accent-red: #ff2e5c;
  --accent-red-glow: rgba(255, 46, 92, 0.35);
  --accent-gold: #f7b13f;
  --accent-emerald: #34d399;
  --accent-cyan: #22d3ee;
  --accent-blue-light: #7da6ff;
}

/* Top App Header */
.app-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(11, 15, 22, 0.86);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow: 0 8px 28px rgba(6, 9, 15, 0.28);
  padding: 0.75rem 1.5rem;
}

.header-container {
  max-width: 1600px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.brand-logo {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
}

.logo-badge {
  background: linear-gradient(135deg, var(--accent-red), #9f1239);
  color: #fff;
  font-weight: 800;
  font-size: 1rem;
  padding: 0.35rem 0.65rem;
  border-radius: var(--radius-sm);
  letter-spacing: 1px;
  box-shadow: 0 0 12px var(--accent-red-glow);
}

.logo-text {
  display: flex;
  flex-direction: column;
}

.logo-title {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--text-primary);
  line-height: 1.1;
}

.logo-tagline {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--accent-gold);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

.logo-tagline-link {
  color: inherit;
  text-decoration: none;
}

.logo-tagline-link:hover {
  text-decoration: underline;
}

/* Header Actions & Rate Controls */
.header-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.currency-control {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--bg-inset);
  border: 1px solid var(--border-subtle);
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-full);
  font-size: 0.8rem;
  color: var(--text-secondary);
}

.currency-rate-input {
  background: transparent;
  border: none;
  color: var(--accent-emerald);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.85rem;
  width: 55px;
  outline: none;
  text-align: right;
}

.header-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--bg-inset);
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
  padding: 0.45rem 0.9rem;
  border-radius: var(--radius-md);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--transition-fast);
}

.header-btn:hover {
  background: var(--bg-card-hover);
  border-color: var(--border-strong);
}

.header-btn.btn-accent {
  background: var(--accent-red);
  border-color: var(--accent-red);
  color: #fff;
}

.header-btn.btn-accent:hover {
  background: #be123c;
  box-shadow: 0 0 15px var(--accent-red-glow);
}

.badge-counter {
  background: var(--accent-red);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 800;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-full);
  margin-left: 0.25rem;
}

/* Hero Section */
.hero-section {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(ellipse 760px 420px at 10% -15%, rgba(255, 46, 92, 0.26), transparent 64%),
    radial-gradient(ellipse 640px 380px at 86% 10%, rgba(56, 96, 220, 0.20), transparent 62%),
    #0b0f16;
  border-bottom: 2px solid var(--accent-red);
  /* Top padding used to be 3.25rem to clear the ticker bar that sat between
     the header and the hero. With that bar gone the hero butts straight onto
     the header, and 52px top against 32px bottom read as a big empty band. */
  /* Asymmetric on purpose now: the top edge merges into the dark header so
     it needs little clearance, while the bottom edge carries the red border
     and the content below it. */
  padding: 1.25rem 1.5rem 2rem;
}

/* Blueprint grid — a nod to the technical/spec-sheet side of the hobby.
   Faded out toward the bottom so it never competes with the search bar. */
.hero-section::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.038) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.038) 1px, transparent 1px);
  background-size: 68px 68px;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 88%);
  mask-image: linear-gradient(180deg, #000 0%, transparent 88%);
  pointer-events: none;
}

/* 獵手 watermark, tucked behind the car illustration as depth rather than
   competing with it for the same space. */
.hero-section::after {
  content: '獵手';
  position: absolute;
  right: 3%;
  top: 46%;
  transform: translateY(-50%);
  z-index: -1;
  font-size: clamp(8rem, 13vw, 13rem);
  font-weight: 900;
  line-height: 0.8;
  color: rgba(255, 255, 255, 0.022);
  letter-spacing: -0.04em;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Featured-car spotlight — a real dealer photo of a real listing, faded
   into the hero on its left edge so it reads as part of the masthead
   rather than a pasted-on rectangle. */
.hero-feature {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: min(46vw, 620px);
  aspect-ratio: 16 / 10;
  border: none;
  padding: 0;
  background: none;
  cursor: pointer;
  z-index: 0;
  overflow: hidden;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  -webkit-mask-image: linear-gradient(100deg, transparent 0%, #000 34%, #000 100%);
  mask-image: linear-gradient(100deg, transparent 0%, #000 34%, #000 100%);
  opacity: 1;
  transition: opacity 0.38s ease;
}

/* Crossfade between rotating featured cars */
.hero-feature.is-swapping {
  opacity: 0;
}

.hero-feature-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.02);
  transition: transform var(--transition-smooth);
}

.hero-feature:hover .hero-feature-img {
  transform: scale(1.06);
}

/* Caption sits over the photo's lower-right, on its own scrim so it stays
   readable regardless of how light or busy the dealer photo is. */
.hero-feature-meta {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 28%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  padding: 1.5rem 1.5rem 1.15rem;
  text-align: left;
  background: linear-gradient(0deg,
    rgba(8, 11, 17, 0.95) 0%,
    rgba(8, 11, 17, 0.86) 55%,
    transparent 100%);
}

.hero-feature-label {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-red);
}

.hero-feature-title {
  font-family: var(--font-heading);
  font-size: 1.02rem;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.3px;
  line-height: 1.2;
}

.hero-feature-price {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--accent-emerald);
}

/* Narrower than this there's no room to sit the photo beside the headline,
   so it drops into the flow as a full-width card between the headline and
   the search bar instead of being hidden. */
@media (max-width: 1080px) {
  .hero-container {
    display: flex;
    flex-direction: column;
  }

  .hero-headline { order: 1; }
  .hero-feature { order: 2; }
  .search-bar-wrapper { order: 3; }
  .quick-pills-bar { order: 4; }

  .hero-feature {
    /* Must stay a positioned ancestor: .hero-feature-meta is absolute, and
       with this static the caption anchored to .hero-container instead and
       landed on top of the search bar and quick pills. */
    position: relative;
    transform: none;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-subtle);
    margin-bottom: 0.25rem;
    /* The left-edge fade only makes sense when it bleeds off the masthead;
       as a standalone card it should be a clean rectangle. */
    -webkit-mask-image: none;
    mask-image: none;
  }

  .hero-feature-meta {
    left: 0;
    padding: 2rem 1.1rem 0.95rem;
  }
}

.hero-container {
  max-width: 1600px;
  margin: 0 auto;
  position: relative;
}

.hero-headline {
  margin-bottom: 1.4rem;
}

/* Editorial eyebrow above the headline */
.hero-eyebrow {
  /* Block-level flex, not inline-flex: as an inline box it sat in a line box
     whose strut is sized by the headline font, adding ~9px of dead space
     above it that read as a gap under the header. */
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: #ff6b88;
  margin-bottom: 1.05rem;
}

.hero-eyebrow::before {
  content: '';
  width: 30px;
  height: 2px;
  background: var(--accent-red);
  flex-shrink: 0;
}

.hero-eyebrow-ja {
  color: var(--accent-gold);
  letter-spacing: 0.1em;
  white-space: nowrap;
}

.hero-title {
  font-family: var(--font-heading);
  font-size: clamp(2.3rem, 5vw, 4.15rem);
  font-weight: 700;
  letter-spacing: -0.045em;
  color: var(--text-primary);
  line-height: 1.02;
  max-width: 17ch;
}

.hero-title span {
  color: var(--accent-red);
}

/* Quick Search Hero Bar */
.search-bar-wrapper {
  margin-top: 1.25rem;
  display: flex;
  gap: 0.75rem;
  max-width: 900px;
}

.search-input-group {
  position: relative;
  flex: 1;
}

.search-icon {
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  font-size: 1rem;
  pointer-events: none;
}

.main-search-input {
  width: 100%;
  background: var(--bg-surface);
  border: 1px solid var(--border-strong);
  color: var(--text-primary);
  padding: 0.8rem 1rem 0.8rem 2.8rem;
  border-radius: var(--radius-md);
  font-size: 1rem;
  outline: none;
  transition: all var(--transition-fast);
}

.main-search-input::placeholder {
  color: var(--text-muted);
}

.main-search-input:focus {
  border-color: var(--accent-red);
  box-shadow: 0 0 0 3px var(--accent-red-glow);
  background: var(--bg-inset);
}

/* Quick Filter Pills Bar */
.quick-pills-bar {
  margin-top: 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 0.5rem;
}

/* A lot that failed to sell and came back under a different lot number/
   date (worker/lot-hold.js works out the count). Amber rather than red: it
   is a fact worth knowing, not a warning that something is wrong with the
   car. Shared between the admin and members lot tables (js/lot-list.js). */
.relist-flag {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  color: #9a6a00;
  background: rgba(230, 160, 20, 0.16);
  border-radius: var(--radius-full, 999px);
  padding: 0.1rem 0.5rem;
  margin-left: 0.35rem;
  white-space: nowrap;
}

.pill-label {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  margin-right: 0.25rem;
}

.quick-pill {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-full);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: all var(--transition-fast);
}

.quick-pill:hover {
  background: var(--bg-card-hover);
  border-color: var(--border-strong);
  color: var(--text-primary);
}

.quick-pill.active {
  background: var(--accent-red);
  border-color: var(--accent-red);
  color: #fff;
  box-shadow: 0 4px 16px var(--accent-red-glow);
}

.quick-pill.pill-special {
  border-color: rgba(245, 158, 11, 0.4);
  color: var(--accent-gold);
}

.quick-pill.pill-special.active {
  background: var(--accent-gold);
  color: var(--text-inverse);
  box-shadow: 0 0 12px rgba(245, 158, 11, 0.4);
}

/* Main Layout Grid (Sidebar Filters + Vehicle Listings) */
.main-content-layout {
  max-width: 1600px;
  margin: 1.5rem auto;
  padding: 0 1.5rem 3rem;
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 1.75rem;
  flex: 1;
  width: 100%;
}

/* Grid items default to min-width: auto (their content's min-content
   size), so a wide child like the table view can force this whole grid —
   and with it the page's layout viewport on mobile — wider than the
   screen. min-width: 0 lets the track actually shrink and hand overflow
   to .cars-table-container's own scrollbar instead. */
.filter-sidebar,
.results-section {
  min-width: 0;
}

/* Filter Sidebar */
.filter-sidebar {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
  height: fit-content;
  position: sticky;
  top: 5rem;
  box-shadow: var(--shadow-sm);
  /* fit-content had no ceiling: on a screen short enough — or once enough
     filter groups exist, which is exactly what happened when Color and
     Steering were added — the sidebar grew taller than the viewport. A
     sticky element does not scroll internally on its own, so the filters
     past the bottom edge became genuinely unreachable, not just hidden.
     max-height leaves the same 5rem clearance at top and bottom that `top`
     already reserves above it; overflow-y turns the excess into the
     sidebar's own scrollbar instead of clipping it. */
  /* Bottom clearance is 1.5rem, not matched to the 5rem top offset — that
     number was never functional, just breathing room, and the box already
     reads as contained via its own border and scrollbar. */
  max-height: calc(100vh - 5rem - 1.5rem);
  overflow-y: auto;
}

.filter-toggle-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: none;
  border: none;
  padding: 0;
  cursor: default;
  color: inherit;
  text-align: left;
}

.filter-toggle-chevron {
  display: none;
  transition: transform var(--transition-fast);
  color: var(--text-muted);
}

.filter-body {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.filter-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: 1.25rem;
}

.filter-title {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-primary);
}

.reset-filters-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 0.75rem;
  cursor: pointer;
  font-weight: 600;
}

.reset-filters-btn:hover {
  color: var(--accent-red);
}

.filter-group {
  margin-bottom: 1rem;
}

/* "More Filters" — Chassis/Model, Drivetrain, Color and Steering, closed
   until asked for. Unlike the outer .filter-toggle-btn (decorative on
   desktop, where the whole sidebar is always open), this one is a real
   control on every screen size, so it gets its own rule rather than
   inheriting the outer button's `cursor: default`.

   Reusing .filter-toggle-chevron for the arrow seemed like the visually
   consistent move, but that class is `display: none` by default — correct
   for the outer toggle, which really is decorative on desktop, wrong here,
   where this chevron needs to be visible on every screen size. Missing that
   override was why this rendered as bare, unstyled text with nothing
   suggesting it was clickable — a background chip on top of fixing the
   chevron, so it doesn't read as just another section label like
   Manufacturer or Model Year above it. */
.more-filters-group {
  border-top: 1px solid var(--border-subtle);
  padding-top: 0.9rem;
  margin-top: 0.4rem;
}

.more-filters-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 0.55rem 0.75rem;
  cursor: pointer;
  color: var(--text-secondary);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  text-align: left;
}

.more-filters-toggle:hover {
  color: var(--text-primary);
  border-color: var(--border-strong);
}

.more-filters-toggle .filter-toggle-chevron {
  display: inline-block;
  margin-left: auto;
  font-size: 0.9rem;
  transition: transform var(--transition-fast);
}

.more-filters-toggle[aria-expanded="true"] .filter-toggle-chevron {
  transform: rotate(180deg);
}

.more-filters-body {
  padding-top: 1.15rem;
}

.more-filters-body .filter-group:last-child {
  margin-bottom: 0;
}

.filter-label {
  display: block;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-secondary);
  margin-bottom: 0.45rem;
}

.filter-select, .filter-input {
  width: 100%;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  color: var(--text-primary);
  padding: 0.55rem 0.75rem;
  border-radius: var(--radius-md);
  font-size: 0.85rem;
  outline: none;
  transition: border-color var(--transition-fast);
}

.filter-select:focus, .filter-input:focus {
  border-color: var(--accent-blue);
}

/* Button Group Toggles (e.g. Transmissions) */
.toggle-group {
  display: flex;
  gap: 0.35rem;
}

.toggle-opt-btn {
  flex: 1;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  padding: 0.45rem 0.5rem;
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: all var(--transition-fast);
}

.toggle-opt-btn.active {
  background: var(--accent-blue);
  border-color: var(--accent-blue);
  color: #fff;
}

/* Range Slider */
.slider-group {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.slider-val-row {
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  font-family: var(--font-mono);
  color: var(--accent-emerald);
}

.range-input {
  width: 100%;
  accent-color: var(--accent-blue);
  cursor: pointer;
}

.filter-sublabel {
  font-size: 0.7rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* --------------------------------------------------------------------------
   Dual-handle range slider
   A single visual track carrying both the min and max handle. There is no
   native two-thumb range input, so two <input type="range"> elements are
   stacked in the same box with transparent tracks; only their thumbs receive
   pointer events, letting each handle be grabbed independently while the
   painted track and fill below them read as one control.
   -------------------------------------------------------------------------- */
.dual-range {
  position: relative;
  height: 34px;
  display: flex;
  align-items: center;
}

.dual-range-track,
.dual-range-fill {
  position: absolute;
  height: 5px;
  border-radius: 999px;
  pointer-events: none;
}

.dual-range-track {
  left: 0;
  right: 0;
  background: var(--bg-inset);
  border: 1px solid var(--border-subtle);
}

/* Positioned from JS (updatePriceSliderDisplay) to span the selected range. */
.dual-range-fill {
  background: var(--accent-blue);
  left: 0;
  right: 0;
}

.dual-range .range-input {
  position: absolute;
  left: 0;
  width: 100%;
  margin: 0;
  background: none;
  /* Both inputs stay interactive, and which one is on top is decided in JS
     from where the pointer is (see selectNearestThumb in app.js).

     This used to be `pointer-events: none` here with `auto` on the thumb
     pseudo-element, so that the full-width track of the upper input could not
     swallow clicks meant for the thumb beneath it. That is the widely-repeated
     recipe for a dual range, and it puts the whole control's usability on one
     bet: that the engine honours pointer-events on ::-webkit-slider-thumb. If
     it does not, the input is inert and NEITHER thumb can be grabbed — which
     matches the report of the slider being dead on Mac.

     Deciding the stacking order from the pointer position instead reaches the
     same result without betting on that behaviour at all. Nothing here changes
     how the control looks. */
  pointer-events: auto;
  -webkit-appearance: none;
  appearance: none;
}

.dual-range .range-input::-webkit-slider-runnable-track {
  background: transparent;
  border: none;
  height: 34px;
}

.dual-range .range-input::-moz-range-track {
  background: transparent;
  border: none;
  height: 34px;
}

.dual-range .range-input::-webkit-slider-thumb {
  pointer-events: auto;
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--bg-card);
  border: 2px solid var(--accent-blue);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: grab;
  margin-top: 8px; /* centres the thumb on the 34px track */
}

.dual-range .range-input::-moz-range-thumb {
  pointer-events: auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--bg-card);
  border: 2px solid var(--accent-blue);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: grab;
}

/* These two must stay as separate rules, however tempting it is to comma them
   together. A selector LIST containing a pseudo-element the engine does not
   recognise invalidates the WHOLE rule, so pairing the -webkit- and -moz-
   thumbs meant Chrome threw the rule away over the Firefox half and Firefox
   threw it away over the Chrome half. It was written as one rule and was
   therefore dead everywhere, on Mac and PC alike — the grab cursor and the
   green active border have never once appeared. */
.dual-range .range-input::-webkit-slider-thumb:active {
  cursor: grabbing;
  border-color: var(--accent-emerald);
}

.dual-range .range-input::-moz-range-thumb:active {
  cursor: grabbing;
  border-color: var(--accent-emerald);
}

.dual-range .range-input:focus-visible::-webkit-slider-thumb {
  outline: 2px solid var(--accent-emerald);
  outline-offset: 2px;
}

/* Year Range Filter */
.year-range-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.year-range-row .filter-select {
  flex: 1;
}

.year-range-sep {
  font-size: 0.75rem;
  color: var(--text-muted);
  flex-shrink: 0;
}

/* 25-Year Rule Checkbox Callout */
.rule-check-box {
  background: rgba(37, 99, 235, 0.1);
  border: 1px solid rgba(37, 99, 235, 0.3);
  border-radius: var(--radius-md);
  padding: 0.75rem;
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  cursor: pointer;
}

.rule-check-box input {
  margin-top: 0.2rem;
  accent-color: var(--accent-blue);
}

.rule-check-text {
  font-size: 0.8rem;
  color: var(--text-primary);
  line-height: 1.3;
}

.rule-check-sub {
  display: block;
  font-size: 0.7rem;
  color: var(--accent-gold);
  font-weight: 600;
  margin-top: 0.2rem;
}

/* Listings Results Area */
.results-section {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.results-header-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-md);
  /* This bar carries the Sort control, which otherwise sits ~1900px down the
     page and reads as "there is no sorting". Sticking it to the top keeps
     sorting reachable the whole time you are scrolling the results. */
  position: sticky;
  top: 0.5rem;
  z-index: 20;
  box-shadow: var(--shadow-md, 0 4px 16px rgba(0, 0, 0, 0.12));
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.results-count-label-short {
  display: none;
}

.results-count-label {
  color: var(--text-secondary);
  font-size: 0.9rem;
}

.results-count-info {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.results-number {
  font-family: var(--font-mono);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--accent-emerald);
}

.results-sort-controls {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.sort-label {
  font-size: 0.8rem;
  color: var(--text-muted);
  font-weight: 600;
}

.view-toggle-btns {
  display: flex;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.view-btn {
  background: var(--bg-card);
  border: none;
  color: var(--text-muted);
  padding: 0.4rem 0.65rem;
  cursor: pointer;
}

.view-btn.active {
  background: var(--accent-blue);
  color: #fff;
}

/* Cars Grid */
.cars-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  gap: 1.5rem;
}

/* Empty State */
.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  padding: 4rem 2rem;
  background: var(--bg-surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
}

.empty-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
}

.empty-title {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.5rem;
}

.empty-desc {
  color: var(--text-secondary);
  font-size: 0.9rem;
  max-width: 480px;
  margin: 0 auto 1.5rem;
}

/* App Footer */
.app-footer {
  margin-top: auto;
  background: #0b0f16;
  border-top: 2px solid var(--accent-red);
  padding: 2.25rem 1.5rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* The model links. A quiet row above the legal text rather than a second
   navigation bar — they are there to be followed, by a crawler and by anybody
   who already knows which car they want, not to compete with the search. */
.footer-models {
  max-width: 1600px;
  margin: 0 auto 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1rem;
  font-size: 0.8rem;
}

.footer-models-label {
  color: var(--text-muted);
  opacity: 0.75;
  margin-right: 0.25rem;
}

.footer-models a {
  color: var(--text-secondary);
  text-decoration: none;
}

.footer-models a:hover {
  color: var(--accent-cyan);
  text-decoration: underline;
}

.footer-legal {
  display: block;
  margin-top: 0.35rem;
}

.footer-legal a {
  color: var(--text-muted);
  text-decoration: none;
}

.footer-legal a:hover { text-decoration: underline; }

.footer-container {
  max-width: 1600px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}

.footer-compliance {
  max-width: 750px;
  line-height: 1.4;
}

.footer-powered-by {
  font-size: 0.7rem;
  color: var(--text-muted);
  opacity: 0.7;
  white-space: nowrap;
}

.footer-contact {
  font-size: 0.8rem;
  white-space: nowrap;
}

.footer-contact a {
  color: var(--accent-cyan);
  text-decoration: none;
  font-weight: 600;
}

.footer-contact a:hover {
  text-decoration: underline;
}

/* Responsive Media Queries */
@media (max-width: 1080px) {
  .main-content-layout {
    grid-template-columns: 1fr;
  }

  .filter-sidebar {
    position: static;
  }

  /* Stacked above the results at this width — collapse it so the inventory
     is what you see first, not 600px of controls.

     Collapsed, this should read as ONE tappable bar. Previously the panel kept
     its full padding and header rule, so it rendered as a 118px white box that
     was mostly empty, with the chevron marooned 175px from the word "Filters"
     and butted straight against "Reset All". */
  .filter-sidebar {
    padding: 0;
    overflow: hidden;
  }

  .filter-header {
    padding: 0 1rem 0 0;
    margin: 0;
    border-bottom: none;
    gap: 0.5rem;
  }

  .filter-toggle-btn {
    cursor: pointer;
    flex: 1;
    min-height: 52px;
    padding-left: 1.25rem;
  }

  .filter-toggle-chevron {
    display: inline;
    margin-left: auto;
    padding-left: 0.75rem;
  }

  /* There is nothing to reset while the panel is shut, and at 47x15px it was
     far too small to hit anyway. */
  .filter-sidebar:not(.filters-open) #reset-filters-btn {
    display: none;
  }

  .filter-sidebar.filters-open #reset-filters-btn {
    min-height: 44px;
    padding: 0 0.25rem;
  }

  .filter-sidebar:not(.filters-open) .filter-body {
    display: none;
  }

  /* The rule only belongs there once something sits below it. */
  .filter-sidebar.filters-open .filter-header {
    border-bottom: 1px solid var(--border-subtle);
  }

  .filter-sidebar.filters-open .filter-body {
    padding: 1.25rem;
  }

  .filter-sidebar.filters-open .filter-toggle-chevron {
    transform: rotate(180deg);
  }
}

@media (max-width: 768px) {
  .header-container {
    flex-direction: column;
    align-items: stretch;
  }

  .header-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }

  /* The call button is a conversion CTA, not a utility icon — give it its
     own full-width row so it stays legible instead of getting squeezed in
     among the icon-only buttons below. */
  .header-contact-btn {
    order: -1;
    flex: 1 1 100%;
    justify-content: center;
    font-size: 1rem;
    padding: 0.65rem 1rem;
  }

  .hero-title {
    font-size: 1.65rem;
    text-align: center;
    /* Drop the 17ch measure here. That cap is for desktop, where it stops the
       headline running under the featured-car photo; on a phone it made the
       title a 291px column inside a 327px container, so it sat visibly
       narrower and left-of-centre against the full-width search bar and card
       below it. Full width + centred text reads as one aligned stack. */
    max-width: none;
    margin-inline: 0;
  }

  .hero-eyebrow {
    justify-content: center;
  }

  .hero-section {
    padding-top: 1.25rem;
    padding-bottom: 1.25rem;
  }

  .cars-grid {
    grid-template-columns: 1fr;
  }


  /* Two sticky bars (header + this one) were eating 412px of an 812px phone
     screen — 51% of the viewport permanently unavailable for cars. The header
     is the taller and least-needed while browsing, so it scrolls away here;
     the results bar stays stuck because it carries Sort. */
  .app-header {
    position: static;
  }

  /* Phone header carries only the brand and the one conversion CTA. The FX
     widget is reference data nobody sets on a phone (prices already render in
     USD), and the alert button was competing with Contact Us for the same tap.
     Both stay on desktop. */
  .currency-control,
  #alert-signup-btn {
    display: none;
  }

  .results-header-bar {
    padding: 0.5rem 0.75rem;
    gap: 0.5rem;
  }

  .results-sort-controls {
    flex-wrap: wrap;
    row-gap: 0.5rem;
    flex: 1;
    justify-content: flex-end;
  }

  /* The select's own labels ("Price: Low to High") already say what it does. */
  .sort-label {
    display: none;
  }

  /* The grid is a single column at this width, so a grid/table switch has
     nothing to switch between. */
  .view-toggle-btns {
    display: none;
  }

  .results-count-info {
    flex-wrap: nowrap;
    align-items: baseline;
    gap: 0.35rem;
  }

  /* "904 Japanese Cars Available" + the freshness stamp wrapped to two lines;
     "904 cars · Updated 2h ago" says the same thing in one. */
  .results-count-label {
    display: none;
  }

  .results-count-label-short {
    display: inline;
    color: var(--text-secondary);
    font-size: 0.9rem;
  }

  .slider-val-row {
    flex-wrap: wrap;
    row-gap: 0.2rem;
  }

  .year-range-row {
    flex-wrap: wrap;
  }

  .year-range-row .filter-select {
    min-width: 100px;
  }

  .toggle-group {
    flex-wrap: wrap;
  }

  .toggle-opt-btn {
    flex: 1 1 30%;
  }
}

/* Compact header on phones: icon-only action buttons so the header never
   forces horizontal scroll on narrow screens. The call button is excluded —
   it keeps its number visible since it's a conversion CTA, not a utility. */
@media (max-width: 560px) {
  /* Keep the eyebrow on one line on narrow screens */
  .hero-eyebrow {
    font-size: 0.58rem;
    letter-spacing: 0.14em;
    gap: 0.45rem;
  }

  .hero-eyebrow::before {
    width: 18px;
  }

  .header-btn:not(.header-contact-btn) .btn-text {
    display: none;
  }

  /* Icon-only at this width, so the box must be sized deliberately — these
     were rendering ~33-41px wide, under the 44px minimum touch target and
     easy to mis-tap. */
  .header-btn:not(.header-contact-btn) {
    padding: 0.5rem;
    gap: 0;
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
    font-size: 1.05rem;
  }

  .currency-control {
    font-size: 0.8rem;
    padding: 0.3rem 0.5rem;
  }

  .logo-tagline {
    font-size: 0.68rem;
  }

  /* The action row was wrapping onto a 4th line (currency + 4 icon buttons
     exceeded 327px), making the header 256px — a third of a phone screen.
     "Refresh Inventory" is the one control a buyer never needs: the catalog
     already refreshes on load and every 15 minutes. Dropping it here lets
     the rest fit one row. It stays available on desktop. */
  #live-scan-btn {
    display: none;
  }

  .currency-control {
    padding: 0.3rem 0.45rem;
    gap: 0.3rem;
  }

  .currency-rate-input {
    width: 42px;
  }

  /* Was a 77x14 tap target inside the tagline. */
  .logo-tagline-link {
    display: inline-block;
    padding: 0.25rem 0;
  }
}
