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

:root {
  --bg0: #1b2838;
  --bg1: #2a475e;
  --bg2: #1e3a5f;
  --bg3: #17212b;
  --text0: #c6d4df;
  --text1: #8f98a0;
  --text2: #4c6b8a;
  --accent: #1a9fff;
  --accent2: #66c0f4;
  --border: #3d5068;
  --r: 6px;
}

body {
  background: var(--bg0);
  color: var(--text0);
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  min-height: 100vh;
}

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 36px 20px 60px;
}

/* Header */
header { text-align: center; margin-bottom: 36px; }
header h1 {
  font-size: 26px;
  font-weight: 600;
  color: var(--accent2);
  letter-spacing: 0.4px;
}
header p { color: var(--text1); margin-top: 6px; font-size: 13px; }

/* Card */
.card {
  background: var(--bg1);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 22px 24px;
  margin-bottom: 18px;
}
.card h2 { font-size: 13px; font-weight: 600; color: var(--text1); text-transform: uppercase; letter-spacing: 0.6px; margin-bottom: 6px; }
.card-subtitle { font-size: 13px; color: var(--text2); margin-bottom: 14px; line-height: 1.5; }

/* User inputs */
#user-inputs { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }

.user-row { display: flex; gap: 8px; align-items: center; }
.user-row input {
  flex: 1;
  min-width: 0;
  padding: 9px 12px;
  background: var(--bg0);
  border: 1px solid var(--border);
  border-radius: var(--r);
  color: var(--text0);
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s;
}
.user-row input:focus { border-color: var(--accent); }
.user-row input::placeholder { color: var(--text2); }

.btn {
  padding: 9px 18px;
  border: none;
  border-radius: var(--r);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.btn-remove {
  flex-shrink: 0;
  width: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text1);
  font-size: 17px;
  line-height: 30px;
  text-align: center;
  border-radius: var(--r);
  cursor: pointer;
}
.btn-remove:hover { background: rgba(200,60,60,0.2); border-color: #cc4040; color: #ff8888; }

.actions { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-ghost {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text0);
}
.btn-ghost:hover { background: var(--bg0); }

.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover { background: #1490e8; }
.btn-primary:disabled { background: var(--bg2); color: var(--text2); cursor: not-allowed; }

/* Alerts */
.alert {
  padding: 12px 16px;
  border-radius: var(--r);
  margin-bottom: 16px;
  font-size: 13px;
  line-height: 1.5;
}
.alert-error {
  background: rgba(200,50,50,0.12);
  border: 1px solid rgba(200,50,50,0.35);
  color: #ff8888;
}
.alert-warn {
  background: rgba(228,168,46,0.1);
  border: 1px solid rgba(228,168,46,0.3);
  color: #e4c46e;
}

/* Results */
.results-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.results-header h2 { font-size: 16px; font-weight: 600; color: var(--text0); }
.results-meta { font-size: 12px; color: var(--text1); }

/* Progress */
.progress-wrap { margin-bottom: 14px; }
.progress-text { font-size: 12px; color: var(--text1); margin-bottom: 6px; }
.progress-bar-bg {
  background: var(--bg3);
  border-radius: 999px;
  height: 3px;
  overflow: hidden;
}
.progress-bar {
  height: 100%;
  background: var(--accent);
  transition: width 0.25s ease;
  border-radius: 999px;
}

/* Table */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--r);
}

table { width: 100%; border-collapse: collapse; }

thead th {
  background: var(--bg3);
  color: var(--text1);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 9px 14px;
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
thead th.sortable { cursor: pointer; }
thead th.sortable:hover { color: var(--text0); }
thead th.active { color: var(--accent2); }
.th-inner { display: flex; align-items: center; gap: 5px; }
.sort-icon { font-size: 10px; opacity: 0.5; }
thead th.active .sort-icon { opacity: 1; }

tbody tr { border-bottom: 1px solid rgba(61,80,104,0.4); }
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: rgba(42,71,94,0.45); }

tbody td { padding: 9px 14px; vertical-align: middle; }

/* Thumbnail cell */
.td-thumb { width: 128px; padding: 0; }
.game-thumb { display: block; width: 120px; height: 45px; object-fit: cover; border-radius: 2px; }

/* Game name cell */
.td-name { min-width: 200px; }
.td-name a { color: var(--text0); text-decoration: none; font-weight: 500; }
.td-name a:hover { color: var(--accent2); }

/* Score cell */
.td-score { min-width: 100px; }
.score-num {
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
}
.score-label { font-size: 11px; color: var(--text1); margin-top: 2px; }

/* HLTB cells */
.td-hltb { min-width: 80px; font-variant-numeric: tabular-nums; }

.dim { color: var(--text2); }

/* Game groups */
.game-group { margin-bottom: 32px; }
.group-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.group-title { font-size: 15px; font-weight: 600; color: var(--text0); }
.group-meta { font-size: 12px; color: var(--text1); }
.group-random-btn {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r);
  width: 28px;
  height: 26px;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  transition: border-color 0.15s;
}
.group-random-btn:hover { border-color: var(--accent); }
.slot-link { color: var(--accent2); text-decoration: none; }

/* Skeleton shimmer */
@keyframes shimmer {
  0%   { background-position: -300px 0; }
  100% { background-position:  300px 0; }
}
.sk {
  display: inline-block;
  width: 52px;
  height: 14px;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--bg1) 25%, #3a5870 50%, var(--bg1) 75%);
  background-size: 600px 100%;
  animation: shimmer 1.4s linear infinite;
  vertical-align: middle;
}
.sk.sm { width: 32px; height: 13px; }

/* Spinner */
@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
  display: inline-block;
  width: 15px; height: 15px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
  vertical-align: middle;
  margin-right: 7px;
}

/* Family member sub-rows */
.player-slot { display: flex; flex-direction: column; gap: 6px; }
.family-row { display: flex; gap: 8px; align-items: center; padding-left: 40px; }
.btn-add-family {
  flex-shrink: 0;
  padding: 0 10px;
  height: 32px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text2);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  border-radius: var(--r);
  cursor: pointer;
}
.btn-add-family:hover { background: rgba(26,159,255,0.12); border-color: var(--accent); color: var(--accent); }
.family-hint {
  display: none;
  font-size: 12px;
  color: var(--text2);
  padding-left: 40px;
  font-style: italic;
}
.player-slot:has(.family-row) .family-hint { display: block; }

/*
 * Accounts bar / recent searches — shared by the comparison page and Library
 * Explorer (rendering logic lives in public/accountsBar.js). One chip per
 * resolved Steam account: avatar, persona name, online/in-game status dot,
 * a per-account count, an optional private-profile badge, and a refresh icon.
 */
.accounts-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
/* Comparison page only — clusters a slot's account chip(s) under a "Player N" /
   "N accounts merged" label, since (unlike the Library Explorer) a search can compare
   several separate slots, each possibly itself a multi-account Steam Family merge. Each
   slot gets its own bounding box on its own row (flex-basis 100%) rather than flowing
   inline with the next slot's chips — a shared border is what actually tells apart
   "these chips are merged into one library" (inside one box) from "these are being
   compared" (separate boxes), since the two can otherwise look like the same flat row of
   chips with a small label sprinkled in between. */
.slot-accounts {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  flex: 1 1 100%;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--bg2);
}
.slot-label { font-size: 12px; font-weight: 600; color: var(--text1); }
.account-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 6px 5px 5px;
  background: var(--bg3); border: 1px solid var(--border); border-radius: 999px;
  color: var(--text0);
}
.account-identity {
  display: flex; align-items: center; gap: 8px;
  color: var(--text0); text-decoration: none;
}
a.account-identity:hover .account-name { color: var(--accent2); }
.account-refresh-btn {
  flex-shrink: 0; width: 20px; height: 20px; padding: 0;
  background: transparent; border: 1px solid var(--border); border-radius: 50%;
  color: var(--text2); font-size: 11px; line-height: 1; cursor: pointer;
}
.account-refresh-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.account-refresh-btn:disabled { cursor: default; opacity: 0.6; }
.account-avatar-wrap { position: relative; flex-shrink: 0; width: 28px; height: 28px; }
.account-avatar { width: 28px; height: 28px; border-radius: 50%; display: block; }
.account-status {
  position: absolute; right: -1px; bottom: -1px; width: 9px; height: 9px;
  border-radius: 50%; border: 2px solid var(--bg3);
}
.account-status-offline { background: var(--text2); }
.account-status-online  { background: #57cbde; }
.account-status-ingame  { background: #a3cf4e; }
.account-meta { display: flex; flex-direction: column; line-height: 1.25; }
.account-name { font-size: 13px; font-weight: 500; }
.account-count { font-size: 11px; color: var(--text2); }
.account-private {
  font-size: 11px; font-weight: 500;
  padding: 2px 7px; border-radius: 999px;
  background: rgba(228,168,46,0.1); border: 1px solid rgba(228,168,46,0.3); color: #e4c46e;
}

/* Recent searches bar — locally-remembered past searches, shown above the accounts bar */
.recents-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
.recents-label { font-size: 12px; color: var(--text2); }
.recent-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 4px;
  background: transparent; border: 1px solid var(--border); border-radius: 999px;
}
.recent-chip-btn {
  display: flex; align-items: center; gap: 6px;
  background: transparent; border: none; padding: 0 2px; cursor: pointer;
  color: var(--text1); font-size: 12px;
}
.recent-chip-btn:hover { color: var(--accent2); }
.recent-chip-avatar { width: 18px; height: 18px; border-radius: 50%; display: block; }
.recent-chip-remove {
  flex-shrink: 0; width: 16px; height: 16px; padding: 0;
  background: transparent; border: none; border-radius: 50%;
  color: var(--text2); font-size: 12px; line-height: 1; cursor: pointer;
}
.recent-chip-remove:hover { color: #cc5050; }
.recents-clear { font-size: 12px; color: var(--text2); background: none; border: none; cursor: pointer; padding: 0; }
.recents-clear:hover { color: var(--accent2); }

/*
 * "Look up any game" widget — shared by the comparison page and Library Explorer
 * (public/gameSearch.js). A text input plus a dropdown of name-search matches; picking one
 * opens the shared side panel (panel.js) for that game regardless of library/wishlist status.
 */
.game-search-wrap { position: relative; }
.game-search-wrap > input {
  width: 100%;
  padding: 9px 12px;
  background: var(--bg0);
  border: 1px solid var(--border);
  border-radius: var(--r);
  color: var(--text0);
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s;
}
.game-search-wrap > input:focus { border-color: var(--accent); }
.game-search-wrap > input::placeholder { color: var(--text2); }
.game-search-results {
  position: absolute; z-index: 5; top: calc(100% + 4px); left: 0; right: 0;
  max-height: 280px; overflow-y: auto;
  background: var(--bg3); border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.game-search-result {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 10px; background: transparent; border: none; cursor: pointer;
  color: var(--text0); font-size: 13px; text-align: left;
}
.game-search-result:hover, .game-search-result:focus-visible, .game-search-result.active { background: var(--bg1); }
.game-search-thumb { width: 46px; height: 22px; object-fit: cover; border-radius: 3px; flex-shrink: 0; }
.game-search-thumb--empty { background: var(--bg0); }
.game-search-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* How it works */
.how-it-works { margin-bottom: 18px; }
.how-steps {
  list-style: none;
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
}
.how-steps li {
  counter-increment: step;
  display: flex;
  gap: 12px;
  align-items: baseline;
  font-size: 13px;
  color: var(--text1);
  line-height: 1.5;
}
.how-steps li::before {
  content: counter(step);
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--bg2);
  border: 1px solid var(--border);
  color: var(--accent2);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.how-steps li strong { color: var(--text0); }

/* Filter panel */
.filter-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.filter-header h2 { margin-bottom: 0; }
.filter-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  margin-left: 6px;
  vertical-align: middle;
}
.btn-sm { padding: 5px 10px; font-size: 12px; }
.filter-dims { display: flex; flex-wrap: wrap; gap: 16px; }
.filter-dim { flex: 1 1 160px; }
.filter-dim-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--text1);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
}
.filter-opts {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 160px;
  overflow-y: auto;
}
.filter-opt {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  cursor: pointer;
  line-height: 1.4;
  user-select: none;
}
.filter-opt input[type="checkbox"] { cursor: pointer; accent-color: var(--accent); flex-shrink: 0; }
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: rgba(26,159,255,0.15);
  border: 1px solid rgba(26,159,255,0.4);
  color: var(--accent);
  font-size: 12px;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 12px;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.filter-chip:hover { background: rgba(26,159,255,0.28); }
.filter-chip-x { font-size: 14px; line-height: 1; opacity: 0.7; }
.filter-search {
  width: 100%;
  box-sizing: border-box;
  padding: 4px 8px;
  margin-bottom: 6px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r);
  color: var(--text0);
  font-size: 12px;
}
.filter-search:focus { outline: none; border-color: var(--accent); }
.filter-name-row { margin-bottom: 12px; }
.filter-name-input { font-size: 14px; padding: 6px 10px; }

/* Clickable rows */
tbody tr.game-row { cursor: pointer; }
tbody tr.game-row.active { background: rgba(26,159,255,0.08) !important; }

/* Side panel backdrop */
.panel-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s;
}
.panel-backdrop.open { opacity: 1; pointer-events: auto; }

/* Side panel drawer */
.game-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 380px;
  max-width: 100vw;
  background: var(--bg1);
  border-left: 1px solid var(--border);
  z-index: 101;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.25s ease;
  overflow: hidden;
}
.game-panel.open { transform: translateX(0); box-shadow: -8px 0 32px rgba(0,0,0,0.4); }

@media (min-width: 1400px) {
  .game-panel { width: min(480px, 30vw); }
}

@media (max-width: 768px) {
  /* Lightbox fills the full screen — swipe handles navigation */
  .lb-img { max-width: 100vw; max-height: 100%; border-radius: 0; }
  .lb-btn  { width: 40px; height: 52px; font-size: 26px; }
  .lb-prev { left: 4px; }
  .lb-next { right: 4px; }

  .container { padding: 18px 14px 40px; }
  header { margin-bottom: 20px; }
  header h1 { font-size: 20px; }
  .card { padding: 14px 16px; }
  .game-group { margin-bottom: 20px; }
  .btn-remove { width: 44px; height: 44px; line-height: 42px; }
  .panel-nav-btn { width: 44px; height: 44px; }
  .panel-close { width: 36px; height: 36px; line-height: 36px; font-size: 20px; }
  .td-name { min-width: 140px; }
  .td-score { min-width: 70px; }
  .td-hltb { min-width: 60px; }
  .family-row { padding-left: 20px; }
  .family-hint { padding-left: 20px; }
  .game-panel { width: 100vw; }
  /* Prevent iOS Safari from zooming on input focus */
  .user-row input, .filter-search, .filter-name-input { font-size: 16px; }
  /* Move the Steam Family button below the input+remove row */
  .user-row { flex-wrap: wrap; }
  .user-row .btn-remove { order: 1; }
  .user-row .btn-add-family { order: 2; flex-basis: 100%; }
}

.panel-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 28px; height: 28px;
  border: none;
  border-radius: 50%;
  background: rgba(0,0,0,0.5);
  color: var(--text0);
  font-size: 18px;
  line-height: 28px;
  text-align: center;
  cursor: pointer;
  z-index: 1;
  padding: 0;
}
.panel-close:hover { background: rgba(0,0,0,0.75); }

/* Rendered as the first child of the scrollable #panel-body (see renderPanelBody in
   panel.js) rather than a fixed sibling outside it, so it scrolls away with the rest of
   the content instead of permanently occupying space above the sticky title bar. The
   negative side margins cancel .panel-body's own side padding so the hero still bleeds
   edge-to-edge; no top margin/padding needed since .panel-body has none of its own
   (that padding lives on .panel-header-sticky below, see its comment). */
.panel-hero { margin: 0 -20px; background: var(--bg3); }
.panel-hero-main {
  position: relative;
  width: 100%;
  aspect-ratio: 460 / 215;
  overflow: hidden;
}
/* The hero's height otherwise scales purely off panel width via the aspect-ratio above —
   fine in portrait, where width is the panel's scarce dimension, but on landscape mobile
   (or any other short viewport) width is plentiful and height is scarce instead: a
   full-width panel there produces a hero tall enough to dominate the whole viewport
   before any real content, including the sticky title bar, comes into view. Keyed on
   height rather than width/orientation so it also catches a landscape phone whose width
   happens to be wide enough to already dodge the max-width:768px mobile rule. `max-height`
   simply overrides the aspect-ratio's computed height; `object-fit: cover` on the image
   itself means it crops tighter rather than distorting. */
@media (max-height: 500px) {
  .panel-hero-main { max-height: 30vh; }
}
.panel-hero-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: zoom-in;
}
.panel-hero-img:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
}
.panel-hero-img.loading {
  background: linear-gradient(90deg, var(--bg1) 25%, #3a5870 50%, var(--bg1) 75%);
  background-size: 600px 100%;
  animation: shimmer 1.4s linear infinite;
}
/* A dead upstream image (broken banner guess, broken video poster, …) — keep the hero's
   footprint and background instead of collapsing it, so the play button/nav/click target
   for whatever still works (the video, the full-res shot) stay usable. */
.panel-hero-img--broken { background: var(--bg3); }
.panel-hero-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(0,0,0,0.45);
  border: none;
  color: #fff;
  font-size: 26px;
  line-height: 1;
  width: 32px;
  height: 48px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, background 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}
.panel-hero-main:hover .panel-hero-btn { opacity: 1; }
.panel-hero-btn:hover:not(:disabled) { background: rgba(26,159,255,0.5); }
.panel-hero-btn:disabled { opacity: 0 !important; }
.panel-hero-prev { left: 0; border-radius: 0 4px 4px 0; }
.panel-hero-next { right: 0; border-radius: 4px 0 0 4px; }
.panel-hero-main.is-video::before {
  content: '▶';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3rem;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,0,0,0.85);
  pointer-events: none;
  z-index: 1;
}

/* Filmstrip */
.panel-filmstrip {
  display: flex;
  gap: 3px;
  padding: 3px;
  overflow-x: auto;
  background: var(--bg1);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.panel-film-item {
  position: relative;
  flex-shrink: 0;
  cursor: pointer;
  display: inline-flex;
  border: none;
  padding: 0;
  background: none;
}
.panel-film-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 2px; }
.panel-film-item.is-video::after {
  content: '▶';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: #fff;
  text-shadow: 0 1px 4px rgba(0,0,0,0.85);
  pointer-events: none;
}
.panel-film-thumb {
  width: 88px;
  height: 50px;
  object-fit: cover;
  border-radius: 2px;
  border: 2px solid transparent;
  opacity: 0.5;
  transition: opacity 0.15s, border-color 0.15s;
  display: block;
}
.panel-film-item:hover .panel-film-thumb { opacity: 0.8; }
.panel-film-item.active .panel-film-thumb { opacity: 1; border-color: var(--accent); }
.panel-film-thumb--broken { background: var(--bg3); }

/* Sticky to the bottom of the panel on both desktop and mobile now (previously sat
   between the hero and the body, which meant reaching it on desktop required
   scrolling back up past the hero every time) — one behavior instead of two, and it
   keeps prev/next/random reachable without the trip. `.game-panel` is `position:
   fixed`, so this `position: absolute` pins to its bottom edge without needing any
   DOM change. `:empty` hides it entirely for standalone lookups (no group/list to
   page through) rather than showing an empty floating bar. */
.panel-nav {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  background: var(--bg1);
  box-shadow: 0 -4px 16px rgba(0,0,0,0.35);
  min-height: 40px;
}
.panel-nav:empty { display: none; }
/* Extra bottom padding only when a nav bar is actually present, so its last section
   never sits underneath the floating bar. */
.panel-nav:not(:empty) ~ .panel-body { padding-bottom: 76px; }
.panel-nav-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text1);
  width: 36px;
  height: 32px;
  border-radius: var(--r);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  transition: border-color 0.15s, color 0.15s;
}
.panel-nav-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent2); }
.panel-nav-btn:disabled { opacity: 0.3; cursor: default; }
.panel-nav-reroll { font-size: 14px; margin-left: 4px; position: relative; }
/* Only the reroll button gets a key hint — prev/next's ↑/↓ icon already IS the key,
   so labeling it again would be redundant; 🎲 isn't a keyboard glyph, so it needs one. */
.panel-nav-kbd {
  position: absolute; bottom: -1px; right: 1px; font-size: 8px; line-height: 1.3;
  color: var(--text2); background: var(--bg3); border-radius: 2px; padding: 0 2px;
}
.panel-nav-pos {
  font-size: 12px;
  color: var(--text1);
  user-select: none;
  flex: 1;
  text-align: center;
}

.panel-body {
  flex: 1;
  overflow-y: auto;
  padding: 0 20px 20px;
}

/* Wraps just the title row (title/release date/icon-links) so it stays visible while
   the hero, glance strip, description, HLTB breakdown, owners and tag cloud all scroll
   underneath — the hero and glance grid used to be exempt from scrolling too (see the
   .panel-hero comment above), which left too little of a short/mobile screen for actual
   content. `position: sticky` rather than pulling this out of `.panel-body` into its own
   flex sibling in the HTML: same visual effect, zero markup changes to index.html/library.html.
   The background matches `.game-panel`'s own (`--bg1`) so there's no seam once scrolled.
   `.panel-body`'s own top padding moved here (negative margin cancels it, padding
   re-adds it) — a sticky child inside a padded scroll container otherwise leaves
   that padding's worth of scrolled content peeking through above it before the
   sticky region "catches", since `top: 0` sticks flush with the padding edge, not
   the border edge. */
.panel-header-sticky {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg1);
  margin: 0 -20px;
  padding: 16px 20px 12px;
}

.panel-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.panel-icon-links { display: flex; gap: 6px; flex-shrink: 0; margin-top: 1px; }
.panel-icon-link {
  width: 26px;
  height: 26px;
  border-radius: var(--r);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text1);
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.panel-icon-link:hover { border-color: var(--accent); color: var(--accent2); }

.panel-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--text0);
  line-height: 1.35;
}

.panel-refresh-btn {
  flex-shrink: 0;
  margin-top: 1px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text1);
  width: 26px;
  height: 26px;
  border-radius: var(--r);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: border-color 0.15s, color 0.15s;
}
.panel-refresh-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent2); }
.panel-refresh-btn:disabled { opacity: 0.6; cursor: default; }
.panel-refresh-btn.is-refreshing { animation: spin 0.75s linear infinite; }

.panel-release {
  font-size: 12px;
  color: var(--text2);
}

.panel-desc {
  font-size: 12px;
  color: var(--text1);
  line-height: 1.5;
  margin-bottom: 18px;
}

.panel-section { margin-bottom: 18px; }
.panel-section--meta { margin-bottom: 12px; }
.panel-section-title {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text2);
  margin-bottom: 7px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.panel-section--meta .panel-section-title { margin-bottom: 5px; }
.panel-section-title a {
  font-size: inherit;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}
.panel-section-title a:hover { color: var(--accent2); border-bottom-color: var(--accent2); }
.panel-no-data { font-size: 12px; color: var(--text1); }
.panel-no-data a { color: var(--text1); text-decoration: none; border-bottom: 1px solid transparent; transition: color 0.15s, border-color 0.15s; }
.panel-no-data a:hover { color: var(--accent2); border-bottom-color: var(--accent2); }

/* Shared with the Library Explorer's ProtonDB table column (public/library.js) — same
   colored pill both places, not just the side panel. */
.proton-badge { display: inline-block; padding: 4px 12px; border-radius: 999px; font-size: 13px; font-weight: 700; color: #fff; line-height: 1.4; }

/* Glance strip: a fixed 2×2 grid (SteamDB+Metacritic, then HLTB+Linux/Deck) instead of
   a horizontally-scrolling row — a scrollable strip here would risk the exact
   swipe-vs-scroll conflict already fixed once for the hero filmstrip (see
   initPanelSwipe/initHeroSwipe in panel.js). Every chip shares one template — a
   value, then a one-line caption — built in glanceChip()/glanceGrid() (panel.js). */
/* No margin-top here — the 12px gap above the grid comes from .panel-header-sticky's own
   padding-bottom instead (that box's edge IS the top of this gap), so margin-bottom below
   is set to match it rather than stacking a second top margin on top of that padding,
   which used to make the gap above the grid nearly 3x the (near-zero) gap below it. */
.panel-glance { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.panel-glance-chip {
  display: flex; align-items: center; padding: 8px 10px;
  border-radius: var(--r); background: var(--bg0); border: 1px solid var(--border);
  text-decoration: none; cursor: pointer; min-width: 0;
  transition: border-color 0.15s;
}
.panel-glance-chip--static { cursor: default; }
.panel-glance-chip--sk { padding: 8px 10px; }
a.panel-glance-chip:hover, a.panel-glance-chip:focus-visible { border-color: var(--accent); outline: none; }
.panel-glance-sub { display: flex; flex-direction: column; line-height: 1.25; gap: 1px; min-width: 0; }
.panel-glance-num { font-size: 17px; font-weight: 700; color: var(--text0); font-variant-numeric: tabular-nums; }
.panel-glance-val { font-size: 11px; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-glance-val b { color: var(--text1); font-weight: 600; }

.panel-hltb { display: flex; flex-wrap: wrap; gap: 24px 24px; row-gap: 14px; }
.panel-hltb-label { font-size: 11px; color: var(--text2); margin-bottom: 3px; }
.panel-hltb-val { font-size: 20px; font-weight: 600; color: var(--text0); }

.panel-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.panel-tag {
  background: rgba(61,80,104,0.5);
  border: 1px solid var(--border);
  color: var(--text1);
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 3px;
}
.panel-tag-btn {
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.panel-tag-btn:hover { border-color: var(--accent); color: var(--accent2); }
.panel-tag-btn.active { background: rgba(26,159,255,0.15); border-color: rgba(26,159,255,0.4); color: var(--accent); }
.panel-tag-playtime { color: var(--text2); }

/* Tags/genres/categories/developer-publisher merged into one cloud (tagCloud() in
   panel.js) instead of four near-identical "uppercase title + pill row" sections —
   kind distinguished by this small dot + the legend below instead of by section. */
.panel-tag-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 4px; vertical-align: middle; }
.panel-tag-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 8px; font-size: 10.5px; color: var(--text2); }
.panel-tag-legend-item { display: inline-flex; align-items: center; }

/* Owned by — ordered by last played (most recent first, see buildOwnersHtml in
   app.js), with a playtime meter: a sequential single-hue magnitude cue layered
   *under* the number, which stays the primary read — color never stands in alone
   for the value. */
.panel-owners { display: flex; flex-direction: column; gap: 10px; }
.panel-owner-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.panel-owner-name { color: var(--text0); font-weight: 500; font-size: 12.5px; }
.panel-owner-lastplayed { color: var(--text2); font-size: 11px; flex-shrink: 0; white-space: nowrap; }
.panel-owner-meter-track { height: 4px; border-radius: 2px; background: var(--bg0); overflow: hidden; margin-top: 5px; }
.panel-owner-meter-fill { height: 100%; background: var(--accent2); border-radius: 2px; }
.panel-owner-playtime { display: block; margin-top: 3px; font-size: 11px; color: var(--text1); }
.panel-section-subtitle { text-transform: none; font-weight: 400; letter-spacing: 0; color: var(--text2); }

/* Screenshot lightbox */
#screenshot-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  align-items: center;
  justify-content: center;
}
#screenshot-lightbox.open { display: flex; }
body.lb-open { overflow: hidden; }
.lb-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.88);
  cursor: zoom-out;
}
.lb-img {
  position: relative;
  max-width: 100vw;
  max-height: 100vh;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
  transition: opacity 0.18s;
  transform-origin: center center;
  user-select: none;
}
.lb-video {
  position: relative;
  width: 100vw;
  height: 100vh;
  object-fit: contain;
  display: none;
  cursor: pointer;
}
.lb-vctrls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 24px 14px 14px;
  background: linear-gradient(transparent, rgba(0,0,0,0.65));
  transition: opacity 0.25s;
}
/* Idle state (video playing, unattended): hide all chrome + the cursor */
#screenshot-lightbox.lb-idle .lb-vctrls,
#screenshot-lightbox.lb-idle .lb-btn,
#screenshot-lightbox.lb-idle .lb-toolbar { opacity: 0; pointer-events: none; }
#screenshot-lightbox.lb-idle,
#screenshot-lightbox.lb-idle .lb-video,
#screenshot-lightbox.lb-idle .lb-backdrop { cursor: none; }
.lb-vc-btn {
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 4px;
  display: flex;
  align-items: center;
  flex-shrink: 0;
  opacity: 0.9;
}
.lb-vc-btn:hover { opacity: 1; }
.lb-vc-time,
.lb-vc-dur {
  color: rgba(255,255,255,0.85);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  user-select: none;
}
.lb-vc-scrub {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  height: 3px;
  border-radius: 2px;
  background: rgba(255,255,255,0.25);
  cursor: pointer;
  outline: none;
  border: none;
}
.lb-vc-scrub::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  cursor: pointer;
}
.lb-vc-scrub::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  border: none;
  cursor: pointer;
}
.lb-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(255,255,255,0.15);
  color: #fff;
  font-size: 32px;
  line-height: 1;
  width: 48px;
  height: 64px;
  border-radius: 4px;
  cursor: pointer;
  z-index: 1;
  transition: background 0.15s, opacity 0.25s;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lb-btn:hover:not(:disabled) { background: rgba(26,159,255,0.5); }
.lb-btn:disabled { opacity: 0.25; cursor: default; }
.lb-prev { left: 12px; }
.lb-next { right: 12px; }
.lb-toolbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  z-index: 1;
  pointer-events: none;
  transition: opacity 0.25s;
}
.lb-toolbar-left,
.lb-toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  pointer-events: auto;
}
.lb-toolbar button {
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(255,255,255,0.15);
  color: #fff;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
  font-size: 22px;
}
.lb-fullscreen:hover,
.lb-share:hover { background: rgba(26,159,255,0.5); }
.lb-close:hover { background: rgba(200,60,60,0.7); }
.lb-counter {
  color: rgba(255,255,255,0.7);
  font-size: 13px;
  background: rgba(0,0,0,0.5);
  padding: 3px 10px;
  border-radius: 10px;
}

@keyframes lb-enter-right {
  from { transform: translateX(40px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
@keyframes lb-enter-left {
  from { transform: translateX(-40px); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}
.lb-img.lb-anim-right { animation: lb-enter-right 0.18s ease-out forwards; }
.lb-img.lb-anim-left  { animation: lb-enter-left  0.18s ease-out forwards; }
#screenshot-lightbox.lb--loading::after {
  content: '';
  position: absolute;
  width: 32px;
  height: 32px;
  border: 3px solid rgba(255,255,255,0.2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
  z-index: 2;
  pointer-events: none;
}

/* Site footer */
.site-footer {
  text-align: center;
  font-size: 12px;
  color: var(--text2);
  margin-top: 40px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.site-footer kbd {
  font-family: inherit;
  font-size: 11px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  color: var(--text1);
}
.footer-link { color: var(--text2); text-decoration: none; }
.footer-link:hover { color: var(--accent2); }

/* Keyboard shortcuts modal */
kbd {
  font-family: inherit;
  font-size: 11px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 3px;
  padding: 2px 6px;
  color: var(--text0);
  white-space: nowrap;
}
.shortcuts-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}
.shortcuts-backdrop.open { opacity: 1; pointer-events: auto; }
.shortcuts-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -48%);
  width: 340px;
  max-width: calc(100vw - 32px);
  background: var(--bg1);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 16px 48px rgba(0,0,0,0.5);
  z-index: 201;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s, transform 0.15s;
}
.shortcuts-modal.open {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%);
}
.shortcuts-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--border);
}
.shortcuts-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text0);
  letter-spacing: 0.2px;
}
.shortcuts-close {
  background: none;
  border: none;
  color: var(--text1);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.shortcuts-close:hover { color: var(--text0); }
.shortcuts-body { padding: 12px 16px 16px; display: flex; flex-direction: column; gap: 16px; }
.shortcuts-section-title {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text2);
  margin-bottom: 8px;
}
.shortcuts-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--text1);
}
.shortcuts-row:last-child { margin-bottom: 0; }
.shortcuts-row span { margin-left: 4px; }
