/* ============================================================
   NEONBET · Games view (dedicated lobby)  (redesign-v2 · FIX-4)
   ------------------------------------------------------------
   Mobile-first dedicated games page: header + count, category
   poster cards, search + sort + filters, 2-col game grid.
   Driven by the LIVE data layer — rails/filters use the admin
   CATEGORIES and GAMES; providers derived from GAMES. Game launch
   reuses openGameIframe. No backend/API/category changes.
   Injected as #nb-games (sibling of #nb-home, view-switched by nav).
   ============================================================ */

#nb-games { position: relative; z-index: 1; display: none; }
#nb-games.is-active { display: block; }
#nb-games .container { width: 100%; max-width: var(--container-max); margin: 0 auto; padding: 0 var(--space-5); }
@media (min-width: 768px) { #nb-games .container { padding: 0 var(--space-8); } }

/* Hero */
#nb-games .lobby-hero { padding: var(--space-6) 0 var(--space-2); }
#nb-games .lobby-hero h1 { margin: 0; font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 400; letter-spacing: 0.02em; text-transform: uppercase; color: var(--text-primary); }
#nb-games .lobby-hero p { color: var(--text-secondary); margin: var(--space-2) 0 0; font-size: var(--text-base); }

/* Category tab row — one compact horizontal line of neon icon+label tabs
   (replaces the poster-card wall). Never wraps; scrolls horizontally when it
   can't fit — always on phones, only if needed on desktop. Lives inside
   #nb-games .container so its edges sit on the shared site grid (Header /
   grid / Footer). The old poster PNGs (img/categories/*) are unused here. */
#nb-games .cat-strip {
  display: flex; flex-wrap: nowrap; align-items: stretch;
  gap: 6px;
  padding: var(--space-5) 0 var(--space-3);
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  /* Plan E (2026-08-01): touch-action / -webkit-overflow-scrolling /
     overscroll-behavior-x removed — see the note above .rail in home.css. This
     strip and .rail were the only two x-scrollers carrying them, and the only
     two that would not finger-pan on iPhone. */
}
#nb-games .cat-strip::-webkit-scrollbar { display: none; }
#nb-games .cat-tab {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
  height: 38px; padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  font-family: var(--font-sans); font-weight: 600; font-size: 0.85rem;
  line-height: 1; letter-spacing: 0.01em; white-space: nowrap; cursor: pointer;
  -webkit-appearance: none; appearance: none; -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
/* Neon icon — restrained by default; brighter glow on hover, strongest on
   active. One CSS color + drop-shadow() lights the whole coherent SVG set. */
#nb-games .cat-tab .cat-tab-ic { flex: 0 0 auto; width: 16px; height: 16px; display: inline-flex;
  color: var(--neon-cyan); filter: drop-shadow(0 0 4px rgba(0, 229, 255, 0.45));
  transition: filter var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }
#nb-games .cat-tab .cat-tab-ic svg { width: 16px; height: 16px; display: block; }
#nb-games .cat-tab .cat-tab-label { line-height: 1; }
#nb-games .cat-tab:hover { color: var(--text-primary); border-color: var(--neon-cyan); box-shadow: 0 0 0 1px rgba(0, 229, 255, 0.25); }
#nb-games .cat-tab:hover .cat-tab-ic { filter: drop-shadow(0 0 7px rgba(0, 229, 255, 0.75)); }
#nb-games .cat-tab:focus-visible { outline: none; color: var(--text-primary); border-color: var(--neon-cyan); box-shadow: 0 0 0 3px rgba(0, 229, 255, 0.35); }
#nb-games .cat-tab.is-active { color: #fff; border-color: var(--neon-cyan);
  background: linear-gradient(135deg, rgba(0, 229, 255, 0.16), rgba(139, 92, 255, 0.16));
  box-shadow: 0 0 0 1px var(--neon-cyan), 0 6px 20px rgba(0, 229, 255, 0.22); }
#nb-games .cat-tab.is-active .cat-tab-ic { filter: drop-shadow(0 0 9px rgba(0, 229, 255, 0.95)); }

/* "Show all games" — teaser-limit reveal button under the grid */
#nb-games .load-more { display: flex; justify-content: center; margin-top: var(--space-8); }
/* Expanded-mode sentinel: parks under the grid and auto-loads the next
   +15 batch when it nears the viewport; removed once the list is done. */
#nb-games .gv-sentinel { display: flex; justify-content: center; padding: var(--space-6) 0 var(--space-4); }
#nb-games .gv-loader { width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--border-subtle); border-top-color: var(--neon-cyan); animation: gv-spin 0.9s linear infinite; }
@keyframes gv-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { #nb-games .gv-loader { animation: none; } }

/* Toolbar */
#nb-games .lobby-toolbar { position: sticky; top: calc(var(--nav-height-mobile) + env(safe-area-inset-top)); z-index: 10; background: var(--bg-base); padding: var(--space-3) 0; margin-top: var(--space-2); }
@media (min-width: 1200px) { #nb-games .lobby-toolbar { top: calc(var(--nav-height) + env(safe-area-inset-top)); } }
#nb-games .lobby-toolbar-inner { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap; }
#nb-games .lobby-search { position: relative; flex: 1 1 100%; }
@media (min-width: 560px) { #nb-games .lobby-search { flex: 1 1 240px; } }
#nb-games .lobby-search input { height: 44px; width: 100%; padding: 0 var(--space-4) 0 44px; background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); color: var(--text-primary); font-family: var(--font-sans); font-size: var(--text-base); }
#nb-games .lobby-search input:focus { outline: none; border-color: var(--neon-cyan); box-shadow: 0 0 0 3px rgba(0,229,255,0.14); }
#nb-games .lobby-search svg { position: absolute; top: 50%; left: 14px; transform: translateY(-50%); width: 18px; height: 18px; color: var(--text-muted); pointer-events: none; }
#nb-games .sort-select { height: 44px; padding: 0 var(--space-3); background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); color: var(--text-primary); font-family: var(--font-sans); font-size: var(--text-sm); }
#nb-games .filter-toggle { height: 44px; padding: 0 var(--space-4); display: inline-flex; align-items: center; gap: 8px; background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); color: var(--text-primary); font-family: var(--font-display); font-size: var(--text-xs); letter-spacing: 0.04em; text-transform: uppercase; cursor: pointer; }
#nb-games .filter-toggle:hover { border-color: var(--neon-cyan); }
#nb-games .filter-toggle svg { width: 16px; height: 16px; }
#nb-games .filter-toggle .fcount { background: var(--neon-magenta); color: #fff; border-radius: var(--radius-pill); font-family: var(--font-mono); font-size: 0.6rem; padding: 1px 6px; }

/* Count */
#nb-games .lobby-count { font-size: var(--text-sm); color: var(--text-secondary); margin: var(--space-2) 0 var(--space-4); }
#nb-games .lobby-count strong { color: var(--text-primary); font-family: var(--font-mono); }

/* Grid */
#nb-games .games-grid { display: grid; gap: var(--space-3); grid-template-columns: repeat(2, 1fr); padding-bottom: var(--space-20); }
@media (min-width: 600px)  { #nb-games .games-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-4); } }
@media (min-width: 900px)  { #nb-games .games-grid { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1280px) { #nb-games .games-grid { grid-template-columns: repeat(5, 1fr); } }
#nb-games .games-empty { grid-column: 1 / -1; padding: var(--space-12) var(--space-5); text-align: center; color: var(--text-muted); }

/* Filter drawer */
.gv-filter-scrim { position: fixed; inset: 0; background: var(--bg-overlay); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); opacity: 0; pointer-events: none; z-index: calc(var(--z-drawer)); transition: opacity 200ms var(--ease-out); }
.gv-filter-scrim.is-open { opacity: 1; pointer-events: auto; }
/* SINGLE SCROLL OWNER.
   The drawer itself scrolls; nothing inside it does. A nested scroller on
   .gv-filter-body was proven on a real iPhone not to scroll at all — the
   gesture reached the right row, nothing called preventDefault, nothing
   overlaid the list and the element reported scrollHeight > clientHeight, yet
   scrollTop never moved. transform, the body scroll lock, the row element type
   and touch-action were each ruled out on device, so the nested-scroller
   architecture itself is what iOS would not drive. This is the plainest thing
   WebKit is guaranteed to scroll: one overflow-y:auto box with its header and
   footer held in place by position:sticky.
   Height still comes from the dynamic viewport (100dvh, with 100vh as the
   fallback) so the drawer tracks the viewport actually on screen. */
.gv-filter { position: fixed; top: 0; left: 0; height: 100vh; height: 100dvh; max-height: 100dvh; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain; touch-action: pan-y; width: min(340px, 86vw); z-index: calc(var(--z-drawer) + 1); background: var(--bg-base); border-right: 1px solid var(--border-subtle); box-shadow: 16px 0 60px rgba(0,0,0,0.55); transform: translateX(-100%); transition: transform 260ms var(--ease-out); display: flex; flex-direction: column; }
.gv-filter.is-open { transform: translateX(0); }
.gv-filter[hidden] { display: none; }
/* Head and foot ride along with the drawer's own scroll, pinned by sticky
   rather than by being flex rails around a nested scroller. They need an
   opaque background of their own (var(--bg-base), the drawer's colour) so the
   rows passing underneath do not show through. The head also clears the notch,
   since the drawer starts at the true top of the viewport. */
.gv-filter-head { flex: 0 0 auto; position: sticky; top: 0; z-index: 2; background: var(--bg-base); display: flex; align-items: center; justify-content: space-between; padding: var(--space-5); padding-top: calc(var(--space-5) + env(safe-area-inset-top)); border-bottom: 1px solid var(--border-subtle); }
.gv-filter-head h3 { margin: 0; font-family: var(--font-display); font-size: var(--text-lg); font-weight: 400; }
.gv-filter-close { width: 36px; height: 36px; border-radius: var(--radius-md); display: inline-flex; align-items: center; justify-content: center; background: var(--bg-surface); border: 1px solid var(--border-subtle); color: var(--text-secondary); cursor: pointer; }
/* Plain document flow — NOT a scroller. It grows to its natural height and the
   drawer above scrolls it. Do not reintroduce overflow/height limits here:
   that nested-scroller shape is exactly what iOS refused to drive. */
.gv-filter-body { flex: none; min-height: auto; overflow: visible; padding: var(--space-5); }
.gv-filter-section { margin-bottom: var(--space-6); }
.gv-filter-section h4 { font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); margin: 0 0 var(--space-3); }
.gv-opt { display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: 8px 10px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text-primary); font-family: var(--font-sans); font-size: var(--text-sm); text-align: left; cursor: pointer; min-height: 38px; transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }
.gv-opt:hover { background: rgba(255,255,255,0.04); }
.gv-opt.is-active { background: rgba(0,229,255,0.12); color: var(--neon-cyan); font-weight: 600; }
.gv-opt input { accent-color: var(--neon-cyan); width: 16px; height: 16px; }
.gv-opt .gv-c { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); }
/* margin-top:auto keeps CLEAR/SHOW at the bottom when the list is short enough
   not to fill the drawer; sticky pins it while the list is long. It stays in
   normal flow, so at the end of the scroll the last provider sits above it. */
.gv-filter-foot { flex: 0 0 auto; position: sticky; bottom: 0; z-index: 2; margin-top: auto; background: var(--bg-base); padding: var(--space-4) var(--space-5) calc(var(--space-5) + env(safe-area-inset-bottom)); border-top: 1px solid var(--border-subtle); display: flex; gap: var(--space-3); }
.gv-filter-foot .btn { flex: 1; }
@media (min-width: 1024px) { .gv-filter, .gv-filter-scrim { /* sidebar handled inline; keep drawer for simplicity on all sizes */ } }

/* ============================================================
   Games-grid card standardization (this page only)
   ------------------------------------------------------------
   The card design lives on the shared, unscoped `.game-card`
   (css/pages/home.css) used by home rails, this grid, AND the
   Game Details similar rail — all 5/6. games.css loads after
   home.css, so these `#nb-games .games-grid` selectors (higher
   specificity + later order) restyle ONLY this grid; the home
   rails and similar rail keep 5/6 untouched. Markup, object-fit,
   object-position, badges, fav, hover/Play overlay and launch
   behaviour are all inherited unchanged.
   ============================================================ */

/* Square 1:1 cover. object-fit:cover (home.css) already fits every
   source — portrait or landscape — into the box without stretching. */
#nb-games .games-grid .game-card { aspect-ratio: 1 / 1; }
