/* Shared filter UI: toggle button, badge, and panel container.
   Applied across index.html, app.html, and stats.html so all filter controls
   share the same visual language and responsive behaviour.

   Each page keeps its own scoped selectors for layout specifics (grid columns,
   inner control types), but these base rules enforce the consistent shell. */

/* ── Toggle button ────────────────────────────────────────────────────── */
.filter-toggle-btn,
.pg-filter-toggle-btn,
.filter-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  background: var(--s1);
  border: 1.5px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 600;
  font-family: inherit;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s, box-shadow 0.15s;
}
.filter-toggle-btn:hover,
.pg-filter-toggle-btn:hover,
.filter-button:hover {
  border-color: var(--accent);
  color: var(--strong);
}
.filter-toggle-btn.has-filters,
.filter-toggle-btn.is-active,
.pg-filter-toggle-btn.has-filters,
.filter-button.is-active {
  color: var(--accent-hi);
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 16px -6px var(--accent-glow);
}

/* ── Badge (count on button) ──────────────────────────────────────────── */
.filter-badge,
.pg-filter-badge,
.filter-btn-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 16px;
  padding: 0 5px;
  background: var(--accent);
  color: var(--bg);
  font-size: 0.65rem;
  font-weight: 700;
  border-radius: 999px;
  line-height: 1;
}

/* ── Panel container ──────────────────────────────────────────────────── */
/* app.html and stats.html use .filter-panel; index uses .pg-filter-panel.
   Both are absolutely-positioned dropdowns anchored to their toggle button. */
.filter-panel,
.pg-filter-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 200;
  background: var(--s1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  min-width: 260px;
  max-width: 96vw;
}

/* Mobile filter modal (<=720px). The desktop dropdown behavior falls apart on
   phones -- it collides with the fixed topbar, overflows off-screen, and never
   feels native. So on mobile the open panel becomes a full-viewport modal with
   a sticky header (title + close X), a scrollable body, and a sticky footer
   with the existing action buttons. Same state, same JS wiring, mobile-only
   markup: the .filter-panel-mobile-header + .filter-panel-close row is hidden
   on desktop and rendered as the modal header on mobile. */
@media (max-width: 720px) {
  .filter-panel.open,
  .pg-filter-panel.open,
  .filter-panel--stack.open {
    position: fixed;
    /* Fill the viewport. Using inset:0 + dynamic viewport height so mobile
       browser chrome (iOS URL bar, Android nav bar) hides/shows correctly. */
    inset: 0;
    z-index: 300;  /* above the fixed .topbar which sits at z-index: 200 */
    width: auto;
    min-width: 0;
    max-width: none;
    max-height: none;
    height: 100dvh;
    border: none;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
    background: var(--bg-bot);
    /* Force a scroll container even when content fits in one screen -- gives
       users a consistent affordance and stops iOS from occasionally
       collapsing overflow to visible. touch-action: pan-y locks the gesture
       axis to vertical so accidental horizontal drags don't fight the
       overflow-x: hidden rule below. */
    overflow-y: scroll;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
  }
  /* Force the group into a vertical stack on mobile: each label + its pills
     on their own row, pills wrap within the row. The desktop masonry
     column-count (below) is scoped to >720px so it can't override this. */
  .filter-panel .pg-filter-group,
  .pg-filter-panel .pg-filter-group {
    flex-direction: row;
    flex-wrap: wrap;
    /* Pills distribute across the row width so short groups (STORE 4-up)
       don't cluster on the left with a big empty gap on the right. Short
       trailing rows (e.g. BORKED alone after the tier wrap) stay
       left-aligned since space-between only spreads within a filled row. */
    justify-content: space-between;
  }
  /* .filter-panel--stack (browse page) normally lays groups side-by-side
     via flex-direction: row on desktop. reports.css only overrides that at
     max-width: 560px, so between 561px and 720px the pill groups overflow
     horizontally inside the modal. Force plain block layout in the modal so
     each group gets its own row, headers stick reliably, and touch-scroll
     inside overflow:auto behaves like a normal document scroll -- flex
     containers with overflow behave inconsistently for sticky descendants
     on iOS Safari + Android WebView. */
  .filter-panel--stack.open {
    display: block !important;
  }
  .filter-panel--stack.open > * {
    margin-bottom: 14px;
  }
  /* Guarantee vertical-only scroll: any child that tries to grow horizontally
     (a long pill row that would push past the viewport) gets its own wrap. */
  .filter-panel.open,
  .pg-filter-panel.open,
  .filter-panel--stack.open {
    overflow-x: hidden;
  }
  .filter-panel .pg-filter-group,
  .pg-filter-panel .pg-filter-group,
  .filter-panel--stack .pg-filter-group {
    max-width: 100%;
    min-width: 0;
  }
  /* Body items get inline padding so pills don't sit flush against the edge.
     Header + footer set their own padding so they can stretch full width. */
  .filter-panel.open > *:not(.filter-panel-mobile-header):not(.filter-panel-footer):not(.filter-panel-footer--stack),
  .pg-filter-panel.open > *:not(.filter-panel-mobile-header):not(.filter-panel-footer):not(.filter-panel-footer--stack),
  .filter-panel--stack.open > *:not(.filter-panel-mobile-header):not(.filter-panel-footer):not(.filter-panel-footer--stack) {
    margin-inline: 14px;
  }
  /* Give the first content row (usually "Search titles") a bit of breathing
     room below the sticky mobile header, otherwise the label sits flush
     against the header border. */
  .filter-panel.open .filter-panel-mobile-header + *,
  .pg-filter-panel.open .filter-panel-mobile-header + *,
  .filter-panel--stack.open .filter-panel-mobile-header + * {
    margin-top: 14px;
  }
  /* Mobile-only header: sticky bar at top with "Filters" title + close X.
     .filter-panel-mobile-header is hidden by default (desktop rule below),
     shown as a sticky header when the panel is open on mobile. width:100%
     is explicit so the header is guaranteed to span edge-to-edge even
     inside a flex column parent (.filter-panel--stack.open sets flex on
     the panel; a flex item without width can size to content). */
  .filter-panel.open .filter-panel-mobile-header,
  .pg-filter-panel.open .filter-panel-mobile-header,
  .filter-panel--stack.open .filter-panel-mobile-header {
    display: flex;
    position: sticky;
    top: 0;
    z-index: 2;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    background: var(--s1);
    border-bottom: 1px solid var(--border);
    margin: 0;  /* override the body-inline-padding rule above */
    width: 100%;
    box-sizing: border-box;
    flex-shrink: 0;
  }
  .filter-panel-mobile-title {
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    color: var(--strong);
    /* margin-right: auto pushes the X to the far right without depending
       on justify-content, so even if a stray flex-child slips into the row
       the X stays glued to the right edge. */
    margin-right: auto;
  }
  .filter-panel-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
  }
  .filter-panel-close:hover { border-color: var(--accent); color: var(--accent); }
  /* Footer: sticky at the bottom so Save / Clear stay in reach while the
     body scrolls. Only affects the two panels that ship a footer (home,
     game-page); the index panel has no footer and is unaffected. */
  .filter-panel.open .filter-panel-footer,
  .filter-panel--stack.open .filter-panel-footer--stack {
    position: sticky;
    bottom: 0;
    z-index: 2;
    padding: 12px 16px;
    background: var(--s1);
    border-top: 1px solid var(--border);
    margin: 0;  /* override the body-inline-padding rule above */
  }
}
/* Hide the mobile header on desktop -- markup lives in every panel but only
   renders on viewports below 721px. */
.filter-panel-mobile-header { display: none; }

/* ── Responsive ───────────────────────────────────────────────────────── */
/* Grow the panel with the viewport so pill rows stop wrapping into a tall
   column on wide monitors. Cap only via the earlier 96vw so the panel
   never hits the screen edge. Steps are chosen to hit common laptop
   widths: 1440 (14" MacBook Air/Pro) and 1728 (16" MacBook) get the widest
   variants so the pills fit on one or two rows instead of running long
   vertically. */
@media (min-width: 721px) {
  .filter-panel:not(.filter-panel--stack),
  .pg-filter-panel {
    min-width: 480px;
  }
}
@media (min-width: 900px) {
  .filter-panel:not(.filter-panel--stack),
  .pg-filter-panel {
    min-width: 680px;
  }
}
@media (min-width: 1200px) {
  .filter-panel:not(.filter-panel--stack),
  .pg-filter-panel {
    min-width: 920px;
  }
}
@media (min-width: 1440px) {
  .filter-panel:not(.filter-panel--stack),
  .pg-filter-panel {
    min-width: 1120px;
  }
}
@media (min-width: 1700px) {
  .filter-panel:not(.filter-panel--stack),
  .pg-filter-panel {
    min-width: 1320px;
  }
}

/* Stats page: per-dimension dropdown panels are narrow by design (single dim).
   Override back to a sensible compact width and use 2-column on desktop. */
.filter-dropdown .filter-panel {
  min-width: 220px;
  max-width: 420px;
}
@media (min-width: 721px) {
  .filter-dropdown.is-open .filter-panel {
    column-count: 2;
    column-gap: 0;
    min-width: 340px;
  }
  .filter-panel-summary { column-span: all; }
}

/* ── Pill filter group ────────────────────────────────────────────────────── */
/* Shared across index.html, app.html (home), and stats.html. A group is a
   label row followed by a horizontal row of pills that wraps on overflow. */
.pg-filter-group {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.pg-filter-group-label {
  flex-basis: 100%;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--strong);
  margin-top: 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.pg-filter {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  background: var(--card);
  border: 1.5px solid var(--border);
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  border-radius: 999px;
  white-space: nowrap;
  font-family: inherit;
  transition: border-color 0.15s, color 0.15s, background 0.15s, box-shadow 0.15s;
}
.pg-filter:hover { border-color: var(--accent); color: var(--strong); }
/* Active chip is flat -- solid accent fill, no glow. Earlier version had
   a 12px accent-color halo (box-shadow) that made adjacent chips read as
   one blurry blob instead of distinct selections. */
.pg-filter--active {
  border-color: var(--accent);
  color: #0a0c10;
  background: var(--accent);
  box-shadow: none;
}
.pg-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--border);
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 800;
}
.pg-filter--active .pg-filter-count {
  background: rgba(10,12,16,0.22);
  color: #0a0c10;
}
