/* ═════════════════════════════════════════════════════════════════ */
/* DMD HUB — Shared list-page design tokens                           */
/* ─────────────────────────────────────────────────────────────────── */
/* Used by every public browse / list page on the HUB so they share   */
/* one visual language. First adopters: /signature-tracks/ (the       */
/* reference) and /gpx/. Future adopters: every other category list   */
/* page (videos, photos, products, profiles, etc.). Each page wraps   */
/* its markup in <div class="hub-list-page">…</div> and pulls this    */
/* file in once; per-page accents live in a tiny inline <style>       */
/* block via the *--<page> modifier convention (see overlay-badge).   */
/*                                                                    */
/* Companion file: /account/dashboard/locations/assets/locations-ui.css */
/* — that one owns the .loc-page-hero / .loc-hero-btn primitives,     */
/* which we re-use rather than duplicate.                             */
/* ═════════════════════════════════════════════════════════════════ */

/* ─── Page wrapper ──────────────────────────────────────────────── */
/* Site-wide body bg is #2a2d35 (set in head.php's inline <style>).
   Matching that here means the page sits flush with the global nav
   chrome — no visible too-dark band below the navbar, no lighter
   gray strip below the page content. Cards on top of this bg are
   #1b1d23 (darker) so they still pop. */
.hub-list-page {
  background: #2b2d35;
  min-height: 60vh;
  /* Top padding clears the site's position-absolute navbar (~80px
     tall) — without it the hero H1 disappears under the menu. The
     Signature Track single page uses the same clearance via
     `padding: 120px 0 36px` on .sig-hero-inner; matching it keeps
     list + detail pages visually aligned. */
  padding: 96px 0 60px;
}
.hub-list-page .container { max-width: 1280px; }

/* Override the .container.py-4 padding-top baked into existing
   markup — the page wrapper now owns the top spacing so the inner
   container shouldn't add MORE padding on top of the nav clearance. */
.hub-list-page .container.py-4 {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* ─── Filter bar ────────────────────────────────────────────────── */
/* Gradient panel matching the .sig-card chrome on the detail pages.
   NOT sticky — we deliberately don't use position:sticky here. The
   user disliked it on the signature-tracks page because it fights
   the hero; the filter bar feels heavier when it follows you down
   the page than when it just sits in the header. Future pages that
   want sticky behaviour can opt in via their own modifier. */
.hub-list-filters {
  background: linear-gradient(180deg, #1e222b 0%, #181b22 100%);
  border: 1px solid #2b3140;
  border-radius: 12px;
  padding: 14px 18px;
  margin-bottom: 18px;
}
.hub-list-filters .form-label {
  color: #cbd5e1;
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 4px;
}
.hub-list-filters .form-control,
.hub-list-filters .form-select {
  background: linear-gradient(180deg, #21252f 0%, #1a1d25 100%);
  border: 1px solid #374151;
  color: #e5e7eb;
  border-radius: 8px;
  font-size: 14px;
}
.hub-list-filters .form-control:focus,
.hub-list-filters .form-select:focus {
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59,130,246,0.15);
}

/* Force a SINGLE clean dropdown chevron. Without this the page shows
   multiple stacked chevrons because:
     1. The browser draws its native <select> arrow
     2. Bootstrap's .form-select stamps an SVG arrow via background-image
     3. theme.min.css overlays another one of its own
   `appearance: none` kills #1, then we override the background to
   paint exactly one chevron ourselves (an inline SVG with a light
   stroke that reads on the dark filter-bar gradient). The 2.25rem
   right padding leaves room for the icon so option labels don't bump
   into it on long values. Applies to BOTH real <select> elements AND
   our custom Bootstrap-dropdown buttons styled as .form-select (the
   GPX multiselect checklists use that pattern). */
.hub-list-filters .form-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23cbd5e1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E"), linear-gradient(180deg, #21252f 0%, #1a1d25 100%);
  background-repeat: no-repeat, no-repeat;
  background-position: right 0.75rem center, 0 0;
  background-size: 14px, auto;
  padding-right: 2.25rem;
}

/* ─── Tag chip strip ────────────────────────────────────────────── */
/* Clickable filter pills under the filter bar. Active chip uses the
   gold accent so it ties to the gold corner badges used elsewhere
   on each page (Signature Track medal, GPX badge tint, etc.). */
.hub-list-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 20px 0;
}
.hub-list-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid #2b3140;
  background: rgba(148,163,184,0.08);
  color: #cbd5e1;
  font-size: 12px;
  text-decoration: none;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.hub-list-tag:hover {
  background: rgba(148,163,184,0.16);
  color: #f3f4f6;
  border-color: rgba(148,163,184,0.4);
}
.hub-list-tag.active {
  background: rgba(251,191,36,0.18);
  color: #fde68a;
  border-color: rgba(251,191,36,0.5);
}

/* ─── Card grid ─────────────────────────────────────────────────── */
/* Each card is a clickable container wrapping the cover photo + body.
   Gradient bg + border match every other card on the site so the
   grid feels native to the dashboard family.
   USAGE — two patterns supported:
     1) Simple cards: `<a class="hub-card-link" href="…">…</a>`
        (entire card is one anchor; OK when there are no other links inside)
     2) Cards with inner links (e.g. an author profile link): use a
        `<div class="hub-card-link">` wrapper containing one
        `<a class="hub-card-link-stretched" href="…">` overlay PLUS the
        inner link given `.hub-card-author-link` (or any element with
        `position:relative; z-index:2;`). Avoids nested `<a>` tags,
        which the HTML parser auto-closes — invalid markup, content
        gets re-parented, layout breaks. */
.hub-card-link {
  display: block;
  position: relative; /* anchor point for .hub-card-link-stretched */
  background: linear-gradient(180deg, #1e222b 0%, #181b22 100%);
  border: 1px solid #2b3140;
  border-radius: 12px;
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  transition: transform 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
  height: 100%;
}
.hub-card-link:hover {
  transform: translateY(-2px);
  border-color: #6366f1;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  color: inherit;
}

/* Stretched-link overlay — used inside `<div class="hub-card-link">`
   to make the whole card clickable without nesting <a> tags. Sits at
   z-index 1 so inner links (.hub-card-author-link etc.) can rise to
   z-index 2 and intercept their own clicks. */
.hub-card-link-stretched {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* No visible chrome — pure click target. Screen readers still get
     the aria-label set per-card. */
  text-indent: -9999px;
  overflow: hidden;
}

/* Inner author / profile link — keeps the styled link visible AND
   clickable on top of the .hub-card-link-stretched overlay. Use this
   instead of inline styles so future link colours stay consistent. */
.hub-card-author-link {
  position: relative;
  z-index: 2;
  color: #a8b5ff;
  font-weight: 600;
  text-decoration: none;
}
.hub-card-author-link:hover {
  color: #fbbf24;
  text-decoration: underline;
}

/* Cover image (16:9). Per-page modifier classes can override the
   aspect-ratio if a different shape is wanted (e.g. portrait product
   cards). Place ribbons / corner badges inside .hub-card-cover so
   they sit above the image. */
.hub-card-cover {
  position: relative;
  background: #15171c;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.hub-card-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 250ms ease;
}
.hub-card-link:hover .hub-card-cover img { transform: scale(1.04); }

/* Placeholder when there's no cover photo for a card. Per-page
   modifiers can override the icon colour via a child selector. */
.hub-card-cover-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #1b1d23 0%, #2e3239 100%);
}
.hub-card-cover-placeholder i {
  font-size: 3rem;
  color: #fbbf24;
  opacity: 0.5;
}

/* Base overlay badge — the corner pill that sits on top of the
   cover image. Position + sizing + shadow are shared; the COLOR is
   per-page via a *--<page> modifier added in each page's own inline
   <style>. Reserve top-left for primary status badges; pages that
   need a second badge can stack at top-right. Example modifiers:
     .hub-card-overlay-badge--signature  (gold)
     .hub-card-overlay-badge--video      (red)
     .hub-card-overlay-badge--photo      (blue)
   Modifier files MUST set background + color; the base only handles
   layout. */
.hub-card-overlay-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  font-weight: 700;
  font-size: 11px;
  padding: 3px 9px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  /* Defaults — readable until a modifier overrides. Neutral gray so
     the unstyled state still looks intentional, not broken. */
  background: rgba(148,163,184,0.95);
  color: #1b1d23;
}
.hub-card-overlay-badge i { vertical-align: -1px; }

/* ─── Card body ─────────────────────────────────────────────────── */
.hub-card-body { padding: 14px 16px 16px; }
.hub-card-title {
  color: #f3f4f6;
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.25;
  margin-bottom: 6px;
  /* Clamp to 2 lines so long titles don't blow the card height
     in the grid (uneven rows look broken on desktop). */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Meta row — country pill + length + off-road% etc. Mixed format:
   .pill is a coloured chip (country / category), plain <span> is for
   numeric facts that don't need a pill background. */
.hub-card-meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  color: #9ca3af;
  font-size: 12.5px;
  margin-bottom: 8px;
}
.hub-card-meta-row .pill {
  background: rgba(99,102,241,0.18);
  color: #c7d2fe;
  border: 1px solid rgba(99,102,241,0.35);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 600;
}
/* Optional emerald variant for "verified" / nature pills (e.g.
   off-road percentage on GPX). Use sparingly — too many colours
   in the meta row reads as noise. */
.hub-card-meta-row .pill--success {
  background: rgba(34,197,94,0.18);
  color: #bbf7d0;
  border-color: rgba(34,197,94,0.35);
}

.hub-card-summary {
  color: rgba(255,255,255,0.75);
  font-size: 13px;
  line-height: 1.45;
  margin-bottom: 10px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Stats row — icon + number triples at the foot of each card.
   Separated by a top border so the visual weight reads "footer". */
.hub-card-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  color: rgba(255,255,255,0.78);
  font-size: 12.5px;
  border-top: 1px solid #2b3140;
  padding-top: 10px;
}
.hub-card-stats span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.hub-card-stats i { font-size: 14px; }

/* ─── Pagination ────────────────────────────────────────────────── */
/* Text links with hover state, matches the dark theme. Active page
   = solid indigo. The disabled class suppresses pointer events so
   the prev/next chevrons can render flat at page ends. */
.hub-list-pager {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 28px;
  flex-wrap: wrap;
}
.hub-list-pager a,
.hub-list-pager span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 38px;
  padding: 0 12px;
  border-radius: 8px;
  border: 1px solid #2b3140;
  background: rgba(148,163,184,0.06);
  color: #cbd5e1;
  text-decoration: none;
  font-size: 14px;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.hub-list-pager a:hover {
  background: rgba(148,163,184,0.16);
  color: #f3f4f6;
  border-color: rgba(148,163,184,0.4);
}
.hub-list-pager .active {
  background: linear-gradient(180deg, #3b82f6 0%, #2563eb 100%);
  border-color: #3b82f6;
  color: #fff;
  box-shadow: 0 3px 10px rgba(59,130,246,0.35);
}
.hub-list-pager .disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* ─── Empty state ───────────────────────────────────────────────── */
/* Rendered when the result set is fully empty (no items match the
   filters). Pages can add an inline <p> + button below the heading
   to direct the user — see signature-tracks for the canonical layout. */
.hub-list-empty {
  background: linear-gradient(180deg, #1e222b 0%, #181b22 100%);
  border: 1px solid #2b3140;
  border-radius: 12px;
  padding: 60px 30px;
  text-align: center;
  color: #cbd5e1;
}
.hub-list-empty i {
  font-size: 3rem;
  color: #fbbf24;
  opacity: 0.6;
}
.hub-list-empty h5 {
  color: #f3f4f6;
  margin: 14px 0 8px;
}

/* ─── Filler / CTA cards ────────────────────────────────────────── */
/* When the result row is mostly empty (1 or 2 cards on a 3-col
   desktop layout), each page can render filler CTA cards in the
   trailing slots so the row doesn't read as dead air. Dashed gold
   border distinguishes them from real result cards. Use this base
   class on the <a> wrapper; each page picks its own icon + copy. */
.hub-card-filler {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 280px;
  padding: 28px 22px;
  background: linear-gradient(180deg, #1e222b 0%, #14171d 100%);
  border: 1px dashed rgba(251,191,36,0.35);
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  transition: transform 120ms ease, border-color 120ms ease;
}
.hub-card-filler:hover {
  transform: translateY(-2px);
  border-color: rgba(251,191,36,0.55);
  color: inherit;
}
.hub-card-filler-icon {
  margin-bottom: 12px;
  font-size: 2.2rem;
  color: #fbbf24;
}
.hub-card-filler-title {
  color: #fff;
  font-weight: 700;
  font-size: 1.1rem;
  margin-bottom: 8px;
}
.hub-card-filler-desc {
  color: rgba(255,255,255,0.72);
  font-size: 0.9rem;
  line-height: 1.5;
  flex-grow: 1;
}
.hub-card-filler-cta {
  margin-top: 12px;
  color: #fbbf24;
  font-weight: 600;
  font-size: 0.9rem;
}

/* ─── Results-header line ──────────────────────────────────────── */
/* Small utility for the "N results matching filters" line that sits
   between the filter bar and the card grid. Optional — pages that
   render their own custom header can ignore this class. */
.hub-list-results-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
  color: #9ca3af;
  font-size: 14px;
}
.hub-list-results-line strong { color: #f3f4f6; }
