/**
 * DealerPro Elite — Inventory listing page styles
 *
 * Source mockup(s):
 *   - mockups/heavy-equipment/mockup-1B-inventory.html
 *   - mockups/cars/mockup-2B-car-inventory.html
 * Loaded conditionally on archive-listing.php / page-inventory.php via wp_enqueue_style.
 *
 * @package DealerPro_Elite
 * @since 2.0.0
 */

/* ─── PAGE HERO (decorative gradient + dot pattern) ───── */
/* Page-hero padding inherits from components.css (.page-hero) so the
   inventory hero matches every other interior page's vertical rhythm.
   This selector adds only the inventory-specific gradient + isolation
   needed for the ::before / ::after pattern overlay below. */
.page-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background:
    linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.5) 100%),
    linear-gradient(135deg, var(--bg-3), var(--bg-1));
  border-bottom: 1px solid var(--border);
}
.page-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 900px 500px at 50% 100%, var(--accent-glow), transparent 70%),
    radial-gradient(ellipse 600px 300px at 0% 0%, var(--cta-soft), transparent 60%);
  z-index: -1;
}
.page-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.015) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.015) 1px, transparent 1px);
  background-size: 56px 56px;
  -webkit-mask-image: radial-gradient(ellipse 60% 80% at 50% 50%, black 30%, transparent 90%);
  mask-image: radial-gradient(ellipse 60% 80% at 50% 50%, black 30%, transparent 90%);
  z-index: -1;
}
/* `.page-hero__inner` wrapper removed — was archive-only and the canonical
   page-hero pattern (every other template) doesn't use it. */
.page-hero__title { margin-bottom: var(--s-4); }
.page-hero__sub {
  font-size: var(--t-md);
  color: var(--text-soft);
  max-width: 560px;
  margin: 0 auto var(--s-6);
  line-height: 1.6;
}
.page-hero__live {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  background: var(--success-soft);
  border: 1px solid rgba(34, 197, 94, 0.3);
  border-radius: var(--r-full);
  padding: 6px 14px;
  font-size: var(--t-xs);
  color: var(--success);
  font-weight: 600;
}
.page-hero__live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 8px var(--success);
  animation: pulse-dot 2s ease-in-out infinite;
}
.page-hero__live strong { color: var(--text); }

/* ─── FILTERS BAR ──────────────────────────────────────── */
.filters {
  padding: var(--s-5) 0;
  /* Static (not sticky) per dealer feedback: sticky bar covered the
     listing cards as the user scrolled, eating ~120px of vertical real
     estate. Plain inline position keeps the bar at the top of the
     inventory section, scrolls away normally. */
}

/* Cards have absolute-positioned badges at top:0 — when the user scrolls
   past the sticky filter bar, those badges briefly render half-hidden
   underneath. scroll-margin-top buffers keyboard scroll-into-view by the
   combined header + filters bar height. */
.inventory-grid > .card-wrap,
.inventory-grid > .card { scroll-margin-top: calc(var(--header-h) + 80px); }
.filters__wrap {
  background: rgba(17, 17, 17, 0.92);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: var(--s-5) var(--s-6);
  box-shadow: var(--shadow-md);
}
.filters__main {
  /* Flex with wrap so any number of filters (varies by vertical) fits gracefully.
     Search keeps a wider basis; dropdowns share the rest. Mockup-1B layout
     stays in a single row at desktop widths. */
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  align-items: center;
}
.filters__main .filter-search {
  flex: 2 1 240px;
  min-width: 200px;
}
.filters__main .filter-select {
  flex: 1 1 140px;
  min-width: 140px;
}
.filter-search {
  position: relative;
  display: flex;
  align-items: center;
}
.filter-search svg {
  position: absolute;
  left: var(--s-4);
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  pointer-events: none;
}
.filter-search input {
  width: 100%;
  background: var(--bg-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  padding: 12px 16px 12px 44px;
  font-size: var(--t-sm);
  color: var(--text);
  transition: var(--transition);
}
.filter-search input:focus-visible {
  /* Solid 2px accent outline meets WCAG 1.4.11 (3:1 against bg). The
     previous `--accent-soft` (alpha 0.10) box-shadow was ~0.5:1 — failed.
     Switched to `:focus-visible` so mouse-clicks don't show a ring. */
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
  background: var(--bg-2);
}
.filter-search input::placeholder { color: var(--text-muted); }

.filter-select {
  position: relative;
}
.filter-select select {
  width: 100%;
  background: var(--bg-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  padding: 12px 36px 12px 16px;
  font-size: var(--t-sm);
  color: var(--text);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: var(--transition);
}
.filter-select select:hover {
  border-color: var(--accent-border);
  background: var(--bg-2);
}
.filter-select select:focus-visible {
  /* Solid outline — see filter-search note above. */
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
  background: var(--bg-2);
}
.filter-select::after {
  content: '';
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  rotate: 45deg;
  pointer-events: none;
  margin-top: -3px;
}

/* Active filter chips row */
.filters__active {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) 0 0;
  flex-wrap: wrap;
}
.filters__active-lbl {
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: var(--text-muted);
  font-weight: 600;
}
.filters__clear {
  margin-left: auto;
  /* Touch-target: was text-only ~16px tall. WCAG 2.5.5 requires 44×44 on
     mobile primary actions; using inline-flex + min-height keeps the
     visual underline-link feel at desktop while unlocking thumb-tap on
     phones. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--s-3);
  font-size: var(--t-xs);
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  background: none;
  cursor: pointer;
  font-weight: 600;
  border: 0;
  border-radius: var(--r-sm);
}
.filters__clear:hover { color: var(--cta); }

/* Mobile filter toggle */
.filters__mobile-trigger { display: none; }

@media (max-width: 1024px) {
  .filters { padding: var(--s-4) 0; }
  /* Switch to grid here — the parent uses display:flex by default which
     ignored grid-template-columns and produced unpredictable wrap. */
  .filters__main { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
  .filter-search { grid-column: 1 / -1; }
  .filters__main .filter-search,
  .filters__main .filter-select { flex: none; min-width: 0; width: 100%; }
}

/* ─── MOBILE FILTER TOGGLE + BOTTOM-SHEET DRAWER ─────────
 * Hidden by default, visible only under 720px. Tap opens
 * .filters__main as a slide-up bottom-sheet over the page. */
.filters__mobile-toggle {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  background: var(--bg-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-full);
  color: var(--text);
  font-size: var(--t-sm);
  font-weight: 600;
  cursor: pointer;
  margin: var(--s-3) auto;
  position: relative;
  touch-action: manipulation;
}
.filters__mobile-toggle svg {
  width: 16px;
  height: 16px;
}
.filters__mobile-toggle-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: var(--accent);
  color: var(--accent-fg, #111827);
  border-radius: var(--r-full);
  font-size: 11px;
  font-weight: 700;
  margin-left: 4px;
}
@media (max-width: 720px) {
  .filters__mobile-toggle { display: inline-flex; }
  .filters {
    position: fixed;
    inset: 0;
    z-index: 95;
    background: rgba(0, 0, 0, 0.65);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    padding: 0;
    visibility: hidden;
    opacity: 0;
    transition: opacity 240ms ease, visibility 240ms ease;
  }
  .filters.is-open {
    visibility: visible;
    opacity: 1;
  }
  .filters .shell {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    max-height: 90dvh;
    overflow-y: auto;
    background: var(--bg-1);
    border-top-left-radius: var(--r-lg);
    border-top-right-radius: var(--r-lg);
    transform: translateY(100%);
    transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1);
    padding: var(--s-5) var(--s-4) calc(var(--s-5) + env(safe-area-inset-bottom, 0px));
    overscroll-behavior: contain;
  }
  .filters.is-open .shell {
    transform: translateY(0);
  }
  .filters .shell::before {
    /* Drag-handle indicator at top of sheet — affordance signal. */
    content: '';
    display: block;
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: var(--border-strong);
    margin: 0 auto var(--s-4);
  }
  .filters__close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 36px;
    height: 36px;
    border-radius: var(--r-full);
    background: var(--bg-2);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--text);
  }
}
@media (prefers-reduced-motion: reduce) {
  .filters,
  .filters .shell { transition: none; }
}
@media (max-width: 720px) {
  .filters {
    position: static;
    top: auto;
  }
}
@media (max-width: 540px) {
  /* Stack every filter on phone — used to hide 5 of 6 with a "More filters"
     toggle that was never rendered, leaving brand/year/price/hours/sort
     unreachable on mobile. Showing them all (one per row, 44px tall each)
     is the lower-risk fix until a proper drawer toggle ships. */
  .filters__main { flex-direction: column; }
  .filters__main .filter-search,
  .filters__main .filter-select {
    flex: 1 1 100%;
    min-width: 0;
    width: 100%;
  }
  .filter-select select {
    min-height: 44px;
  }
}

/* ─── INVENTORY WRAPPER ────────────────────────────────── */
.inventory-wrap {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: var(--s-8);
  margin-top: var(--s-6);
}
@media (max-width: 720px) {
  .inventory-wrap { padding: var(--s-6); }
}

/* ─── AJAX error banner (filters.js inserts this into .inventory-wrap
   on fetch failure or 15s timeout). Stays visible until the user
   clicks Retry or selects another filter (which re-fetches and clears). */
.inventory-error {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  /* Tokenized error tint — picks up brand --cta value automatically when
     dealer overrides the brand palette. Was hardcoded #dc2626 alphas. */
  background: color-mix(in srgb, var(--cta) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--cta) 35%, transparent);
  border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  color: var(--text);
  font-size: var(--t-sm);
}
.inventory-error p { margin: 0; color: var(--text); }
@media (max-width: 540px) {
  .inventory-error { flex-direction: column; align-items: stretch; text-align: center; }
}

/* ─── RESULTS HEADER ───────────────────────────────────── */
.results-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--s-8) 0 var(--s-5);
  flex-wrap: wrap;
  gap: var(--s-3);
}
.results-count {
  font-size: var(--t-sm);
  color: var(--text-soft);
}
.results-count strong {
  color: var(--text);
  font-weight: 700;
}
.results-actions {
  display: flex;
  gap: var(--s-2);
  align-items: center;
}
.view-toggle {
  display: flex;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 3px;
}
.view-toggle__btn {
  /* 44px min for WCAG 2.5.5 touch target. Desktop visual stays compact via
     padding; height is enforced via min-height on touch devices. */
  padding: 6px 12px;
  min-height: 44px;
  border-radius: var(--r-xs);
  font-size: var(--t-xs);
  color: var(--text-muted);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  transition: var(--transition);
}
.view-toggle__btn:hover { color: var(--text); }
.view-toggle__btn--active {
  background: var(--accent);
  color: var(--accent-fg);
}
.view-toggle__btn svg { width: 14px; height: 14px; }
.saved-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 8px 14px;
  min-height: 44px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-size: var(--t-xs);
  color: var(--text-soft);
  font-weight: 600;
  transition: var(--transition);
}
.saved-link:hover {
  border-color: var(--cta);
  color: var(--cta);
}
.saved-link svg {
  width: 14px;
  height: 14px;
  fill: var(--cta);
}
.saved-link__count {
  background: var(--cta);
  color: var(--cta-fg);
  border-radius: var(--r-full);
  padding: 2px 8px;
  font-size: 10px;
}

/* Inventory grid block lives below — was previously declared twice with
   conflicting column rules. The second declaration (lines below) wins via
   source order, so this earlier block was always overridden. Removed to
   avoid confusion when reading the file. */

/* Empty-state styles consolidated to components.css so they also apply on
   search.php (no inventory.css there) and any other page that uses the
   pattern. Without the move, the SVG icon ballooned to full viewport width
   on search results because `.empty-state__icon svg { width:44px }` was
   missing. */

/* ─── PAGINATION ───────────────────────────────────────── */
.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-8) 0 var(--s-6);
}
.page-btn {
  /* WCAG 2.5.5 minimum 44×44 touch target. */
  min-width: 44px;
  height: 44px;
  padding: 0 var(--s-3);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--text-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition);
  cursor: pointer;
}
.page-btn:hover {
  background: var(--bg-2);
  border-color: var(--accent-border);
  color: var(--text);
}
.page-btn--active {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}
.page-btn--active:hover {
  background: var(--accent-dark);
  color: var(--accent-fg);
}
.page-btn--disabled {
  opacity: 0.3;
  pointer-events: none;
}
.page-dots {
  padding: 0 var(--s-2);
  color: var(--text-muted);
  letter-spacing: 2px;
}
.page-summary {
  font-size: var(--t-sm);
  color: var(--text-muted);
  text-align: center;
  margin-bottom: var(--s-3);
}

/* Bottom-cta styles consolidated to components.css. Inventory adds vertical
   margin so the CTA breathes between the grid and footer. */
.bottom-cta {
  margin: var(--s-12) 0;
}


/* ─── INVENTORY GRID ─────────────────────────────────── */
.inventory-wrap {
  padding: var(--s-8) 0;
}
.inventory-grid {
  display: grid;
  /* `auto-fill` with `minmax(280px, 1fr)` keeps a single lone card from
     stretching across 1/3 of the row (it would otherwise pin left and
     leave 2 empty cells visible). At 3+ cards the layout still fills
     three columns at desktop widths. */
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--s-6);
  margin-top: var(--s-6);
  position: relative;
  /* Snappier feel — 200ms felt sluggish on page changes. 80ms is barely
     perceptible but still smooths the skeleton swap. */
  transition: opacity 80ms ease;
}
/* iPad-landscape (1024px) has plenty of width for 3 columns: 3 × ~310px
   + 2 × 24px gap = 978px, well within 1024-shellpad. Previously 1024px
   collapsed to 2-col which wasted ~30% of the viewport. v2.0.59: drop the
   breakpoint to 900px so iPad-landscape stays 3-col and tablets in the
   720-900 range get 2-col. */
@media (max-width: 900px) {
  .inventory-grid { grid-template-columns: repeat(2, 1fr); gap: var(--s-5); }
}
@media (max-width: 720px) {
  .inventory-grid { grid-template-columns: 1fr; gap: var(--s-4); }
}

/* AJAX filter loading state — JS injects `.card-skeleton-wrap` placeholders
   into the grid + flips `.is-loading` on the grid wrapper. The previous
   pattern dimmed real cards to 40% + showed a centered spinner; that left
   stale ghost content visible while the fetch was in flight and felt
   sluggish. Skeletons (defined in components.css) replace stale cards
   entirely and provide stronger perceived progress.

   Behavior:
     - Real `.card-wrap` items hide via display:none during load
     - Injected `.card-skeleton-wrap` siblings sit in their grid slots
     - Pointer events disabled on the grid so users can't click ghost
       skeletons (they have no href)
     - aria-busy="true" set by JS — assistive tech announces the loading
       state without us needing a visual spinner */
.inventory-grid.is-loading {
  pointer-events: none;
}
.inventory-grid.is-loading > .card-wrap:not(.card-skeleton-wrap) {
  display: none;
}

/* Empty-state target (when previous filter returned 0 results and user is
   changing filters again) — no skeletons here because a single empty-state
   layout doesn't map to a grid. Simple opacity fade signals the load. */
.empty-state.is-loading {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--transition);
}
