/* ==========================================================================
   EzyGamers — core stylesheet
   Play. Think. Challenge Yourself.
   ========================================================================== */

:root {
  /* Brand palette */
  --bg: #080910;
  --bg-2: #11121b;
  --header: #171825;
  --card: #1b1d29;
  --card-2: #232637;
  --purple: #6c4cff;
  --purple-bright: #8b5cf6;
  --cyan: #22d3ee;
  --text: #ffffff;
  --muted: #9aa0b5;
  --muted-dim: #6b7189;
  --line: rgba(255, 255, 255, .07);
  --line-strong: rgba(255, 255, 255, .14);

  --gold: #fbbf24;
  --green: #22c55e;
  --pink: #ec4899;

  /* Metrics */
  --header-h: 64px;
  --sidebar-w: 236px;
  --sidebar-w-collapsed: 72px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-sm: 10px;
  --radius-card: 10px;

  --shadow: 0 10px 30px rgba(0, 0, 0, .45);
  --shadow-hover: 0 18px 44px rgba(108, 76, 255, .28);
  --ease: cubic-bezier(.22, .61, .36, 1);

  --grad: linear-gradient(135deg, var(--purple-bright), var(--purple) 55%, var(--cyan));
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", Inter, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; }
img { display: block; max-width: 100%; }
ul { list-style: none; margin: 0; padding: 0; }

h1, h2, h3, h4 { margin: 0; line-height: 1.2; letter-spacing: -.02em; }

::selection { background: var(--purple); color: #fff; }

/* One focus ring for the whole product ------------------------------------
   Only a handful of components declared their own, so keyboard focus looked
   different on every page and was invisible on several. :focus-visible means
   a mouse click never shows it - it appears for keyboard and assistive
   navigation, which is who it is for. */
:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  border-radius: 6px;
}
a:focus-visible, button:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
[tabindex]:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}
/* Skip the ring where a component already draws a better one of its own. */
.gcard:focus-visible, .lb-pick:focus-visible, .lb-seg:focus-visible,
.tabs__btn:focus-visible { outline-offset: 2px; }

/* Scrollbars ------------------------------------------------------------- */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #2a2d40; border-radius: 999px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #3b3f59; }

/* ==========================================================================
   Header
   ========================================================================== */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--header-h);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 16px;
  background: rgba(23, 24, 37, .92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.header__left { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 40px; height: 40px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  transition: background .18s var(--ease), color .18s var(--ease), transform .18s var(--ease);
}
.icon-btn:hover { background: rgba(255, 255, 255, .07); color: #fff; }
.icon-btn:active { transform: scale(.94); }
.icon-btn.is-active { color: var(--cyan); background: rgba(34, 211, 238, .12); }
.icon-btn svg { width: 20px; height: 20px; }

.brand { display: flex; align-items: center; gap: 10px; padding-right: 6px; }
.brand__mark { width: 34px; height: 34px; border-radius: 12px; box-shadow: 0 6px 18px rgba(108, 76, 255, .45); }
.brand__text { display: flex; flex-direction: column; line-height: 1; }
.brand__name { font-size: 18px; font-weight: 800; letter-spacing: -.03em; }
.brand__name span { background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.brand__tag { font-size: 11px; color: var(--muted-dim); letter-spacing: .14em; text-transform: uppercase; margin-top: 3px; }

/* Search ----------------------------------------------------------------- */
.search {
  position: relative;
  flex: 1 1 auto;
  max-width: 580px;
  margin: 0 auto;
}
.search__input {
  width: 100%;
  height: 42px;
  padding: 0 44px 0 18px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #1f2130;
  color: #fff;
  outline: none;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease);
}
.search__input::placeholder { color: var(--muted-dim); }
.search__input:focus {
  border-color: var(--purple);
  background: #22243a;
  box-shadow: 0 0 0 4px rgba(108, 76, 255, .18);
}
.search__btn {
  position: absolute; right: 4px; top: 4px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--muted);
}
.search__btn:hover { color: #fff; }
.search__btn svg { width: 18px; height: 18px; }

.search__results {
  position: absolute;
  top: calc(100% + 10px);
  left: 0; right: 0;
  background: var(--card);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  max-height: 60vh;
  overflow-y: auto;
  display: none;
  animation: dropIn .18s var(--ease);
}
.search__results.is-open { display: block; }
@keyframes dropIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

.sresult {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  transition: background .15s var(--ease);
}
.sresult:last-child { border-bottom: 0; }
.sresult:hover, .sresult.is-highlighted { background: rgba(108, 76, 255, .16); }
.sresult img { width: 62px; height: 35px; object-fit: cover; border-radius: 8px; flex: 0 0 auto; }
.sresult__title { font-weight: 600; font-size: 14px; }
.sresult__meta { font-size: 11.5px; color: var(--muted); }
.sresult--empty { padding: 20px; text-align: center; color: var(--muted); }

.header__right { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.avatar {
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--grad);
  display: grid; place-items: center;
  font-weight: 800; font-size: 14px; color: #0b0c14;
  border: 2px solid rgba(255, 255, 255, .18);
  cursor: pointer;
}
.badge-dot {
  position: absolute; top: 7px; right: 7px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--pink); border: 2px solid var(--header);
}
.icon-btn { position: relative; }

/* ==========================================================================
   Sidebar
   ========================================================================== */
.sidebar {
  position: fixed;
  top: var(--header-h);
  left: 0;
  bottom: 0;
  width: var(--sidebar-w);
  background: var(--bg-2);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  overflow-x: hidden;
  padding: 12px 10px 40px;
  z-index: 50;
  transition: width .22s var(--ease), transform .22s var(--ease);
}
body.sidebar-collapsed .sidebar { width: var(--sidebar-w-collapsed); }

.nav__group + .nav__group { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.nav__label {
  font-size: 11.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted-dim); padding: 10px 12px 6px; white-space: nowrap;
}
body.sidebar-collapsed .nav__label { opacity: 0; height: 12px; padding: 0; overflow: hidden; }

.nav__item {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px;
  border-radius: 12px;
  color: var(--muted);
  font-size: 14px; font-weight: 500;
  white-space: nowrap;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.nav__item:hover { background: rgba(255, 255, 255, .06); color: #fff; }
.nav__item.is-active { background: rgba(108, 76, 255, .18); color: #fff; }
.nav__item.is-active .nav__ico { color: var(--purple-bright); }
.nav__ico { flex: 0 0 20px; width: 20px; height: 20px; display: grid; place-items: center; font-size: 15px; }
.nav__ico svg { width: 19px; height: 19px; }
body.sidebar-collapsed .nav__text { display: none; }
body.sidebar-collapsed .nav__item { justify-content: center; padding: 11px 0; }

/* "More" reveals the rest of the category list without ever leaving the
   sidebar taller than the layout expects. */
.nav__more { width: 100%; border: 0; background: transparent; text-align: left; }
.nav__more .nav__text { color: var(--muted-dim); font-weight: 600; }
.nav__more:hover .nav__text { color: #fff; }
.nav__rest[hidden] { display: none; }

/* Mobile drawer */
.scrim {
  position: fixed; inset: 0;
  background: rgba(4, 5, 10, .65);
  backdrop-filter: blur(2px);
  z-index: 45;
  opacity: 0; pointer-events: none;
  transition: opacity .2s var(--ease);
}
.scrim.is-open { opacity: 1; pointer-events: auto; }

/* ==========================================================================
   Layout
   ========================================================================== */
.layout { padding-top: var(--header-h); }
.main {
  margin-left: var(--sidebar-w);
  padding: 22px 26px 70px;
  transition: margin-left .22s var(--ease);
  min-height: calc(100vh - var(--header-h));
}
body.sidebar-collapsed .main { margin-left: var(--sidebar-w-collapsed); }

/* Reference density: shelves sit close enough together that a second row is
   always visible under the first without being cramped. */
.section { margin-bottom: 30px; }
.section__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-bottom: 14px;
}
.section__title {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 22px; font-weight: 800;
}
.section__title .arrow { color: var(--muted-dim); transition: transform .2s var(--ease), color .2s var(--ease); }
a.section__title:hover .arrow { transform: translateX(4px); color: var(--purple-bright); }
.section__sub { font-size: 14px; color: var(--muted); margin-top: 2px; }
.section__emoji { font-size: 22px; }

.rail-nav { display: flex; gap: 8px; }

/* Horizontal scroll rails ------------------------------------------------ */
.rail-wrap { position: relative; }
.rail {
  display: flex; gap: 12px;
  overflow-x: auto;
  scroll-behavior: smooth;
  scroll-snap-type: x proximity;
  padding: 4px 2px 10px;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; flex: 0 0 auto; }

.rail-btn {
  position: absolute; top: 50%; transform: translateY(-60%);
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(12, 13, 22, .88);
  border: 1px solid var(--line-strong);
  color: #fff;
  z-index: 5;
  opacity: 0;
  transition: opacity .2s var(--ease), background .2s var(--ease), transform .2s var(--ease);
}
.rail-wrap:hover .rail-btn { opacity: 1; }
.rail-btn:hover { background: var(--purple); transform: translateY(-60%) scale(1.08); }
.rail-btn[hidden] { display: none; }
.rail-btn--prev { left: -6px; }
.rail-btn--next { right: -6px; }

/* ==========================================================================
   Game cards

   Image-first tiles: the art carries the card, a compact title strip sits
   under it, and hovering swaps the still for a looping muted preview.
   ========================================================================== */
.gcard {
  position: relative;
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  isolation: isolate;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.gcard:hover,
.gcard:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(139, 92, 246, .6);
  box-shadow: var(--shadow-hover);
}
.gcard:focus-visible { outline: 2px solid var(--purple-bright); outline-offset: 2px; }

.gcard__thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--card-2);
}
.gcard__img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .35s var(--ease), opacity .26s var(--ease);
}
/* Only the still zooms — once the preview takes over it holds steady. */
.gcard:hover .gcard__img { transform: scale(1.06); }
.gcard.is-previewing .gcard__img { opacity: 0; transform: scale(1.06); }

/* Hover preview ----------------------------------------------------------- */
.gcard__preview {
  position: absolute; inset: 0;
  opacity: 0;
  pointer-events: none;               /* clicks belong to the card link */
  transition: opacity .26s var(--ease);
  z-index: 1;
}
.gcard.is-previewing .gcard__preview { opacity: 1; }
.gcard__preview-media {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  background: var(--card-2);
}

/* Hover overlay: the Play affordance sits centred, with the game's name and
   its real numbers along the bottom so pointing at a card tells you something
   before you commit to it. */
.gcard__overlay {
  position: absolute; inset: 0;
  z-index: 2;
  background: linear-gradient(180deg, rgba(8, 9, 16, .05), rgba(8, 9, 16, .86));
  display: grid;
  grid-template-rows: 1fr auto auto;   /* play button, title, facts */
  place-items: center stretch;
  padding: 10px;
  opacity: 0;
  transition: opacity .22s var(--ease);
}
.gcard:hover .gcard__overlay,
.gcard:focus-visible .gcard__overlay { opacity: 1; }
.gcard__play {
  grid-row: 1;
  justify-self: center; align-self: center;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 18px;
  border-radius: 999px;
  background: var(--grad);
  color: #0b0c14; font-weight: 800; font-size: 12px;
  letter-spacing: .04em;
  transform: translateY(9px) scale(.94);
  transition: transform .22s var(--ease);
  box-shadow: 0 8px 24px rgba(108, 76, 255, .5);
}
.gcard:hover .gcard__play,
.gcard:focus-visible .gcard__play { transform: none; }

.gcard__hovertitle {
  grid-row: 2;
  font-size: 12.5px; font-weight: 700; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.gcard__facts {
  grid-row: 3;
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 3px;
  font-size: 11px; color: #cdd2e4;
  font-variant-numeric: tabular-nums;
}
.gcard__fact { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }

/* Badge pills ------------------------------------------------------------- */
.gcard__badge {
  position: absolute; top: 7px; left: 7px;
  z-index: 3;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px;
  border-radius: 6px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .02em;
  background: #2a2d40; color: #fff;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .45);
}
.gcard__badge-ico { font-size: 11px; line-height: 1; }
.gcard__badge--hot { background: linear-gradient(135deg, #f97316, #ef4444); }
.gcard__badge--top { background: #fff; color: #241a00; }
.gcard__badge--top .gcard__badge-ico { color: #f59e0b; }
.gcard__badge--new { background: linear-gradient(135deg, #a855f7, #7c3aed); }
.gcard__badge--updated { background: linear-gradient(135deg, #38bdf8, #2563eb); }
.gcard__badge--original { background: #fff; color: var(--purple); }

/* Title strip ------------------------------------------------------------- */
.gcard__body { padding: 9px 11px 11px; }
.gcard__title {
  font-size: 14px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gcard__meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 4px;
  font-size: 11.5px; color: var(--muted);
}
.gcard__cat { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gcard__rating { display: inline-flex; align-items: center; gap: 4px; color: var(--gold); font-weight: 700; flex: 0 0 auto; }
/* A game with no votes yet says so rather than showing a zero-star score. */
.gcard__unrated { color: var(--muted-dim); font-weight: 600; flex: 0 0 auto; }

/* Portrait showcase variant -----------------------------------------------
   Tall tiles use the 2:3 poster art in assets/games/posters/ so they are
   full-bleed; the blurred backdrop only shows through behind the 16:9 hover
   animation. */
.gcard__art { display: none; }
.gcard--tall .gcard__thumb { aspect-ratio: 2 / 3; }
.gcard--tall .gcard__art {
  display: block;
  position: absolute; inset: -1px;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  filter: blur(22px) saturate(1.4) brightness(.62);
  transform: scale(1.3);
}
.gcard--tall .gcard__img { position: relative; object-fit: cover; }
/* The hover animation is 16:9, so it sits letterboxed on the blurred poster
   rather than being cropped down to the portrait window. */
.gcard--tall .gcard__preview-media { position: relative; object-fit: contain; background: none; }

/* Skeletons ----------------------------------------------------------------
   Shown between "the page rendered" and "the catalogue arrived", so a shelf
   holds its height instead of the layout jumping when cards land. Built from
   the real .gcard box so the placeholder is exactly the size of what replaces
   it. */
.gcard--skeleton {
  pointer-events: none;
  border-color: var(--line);
  background: var(--card);
}
.gcard--skeleton .gcard__thumb,
.skel-line {
  position: relative;
  overflow: hidden;
  background: rgba(255, 255, 255, .05);
}
.gcard--skeleton .gcard__thumb::after,
.skel-line::after {
  content: "";
  position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .07), transparent);
  animation: skel-sweep 1.25s ease-in-out infinite;
}
.gcard--skeleton .gcard__body { display: grid; gap: 7px; padding: 11px 12px 13px; }
.skel-line { height: 11px; border-radius: 5px; }
.skel-line--short { width: 55%; height: 9px; }

@keyframes skel-sweep { to { transform: translateX(100%); } }

@media (prefers-reduced-motion: reduce) {
  .gcard--skeleton .gcard__thumb::after,
  .skel-line::after { animation: none; }
}

/* Rail card sizing */
.rail .gcard { width: 236px; }
.rail .gcard--tall { width: 188px; }
.rail--tall .gcard { width: 236px; }

/* Grid */
.grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(214px, 1fr));
}
.grid--wide { grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); }

/* Mosaic shelf --------------------------------------------------------------
   The reference's headline block: one tile at double size leading a grid of
   ordinary ones. The lead card stretches to cover both rows, so the row height
   is set by the small cards' natural proportions and nothing is letterboxed. */
.mosaic {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto auto;
  gap: 14px;
}
.mosaic > .gcard {
  width: auto;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.mosaic > .gcard .gcard__thumb { flex: 1 1 auto; aspect-ratio: auto; min-height: 118px; }
.mosaic > .gcard:first-child { grid-column: span 2; grid-row: span 2; }
.mosaic > .gcard:first-child .gcard__title { font-size: 17px; }
.mosaic > .gcard:first-child .gcard__body { padding: 12px 14px 14px; }
/* Only the five tiles the block is built for; anything past that would wrap
   into a ragged third row. */
.mosaic > .gcard:nth-child(n + 6) { display: none; }

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* Kept, but compact: the reference puts game tiles near the top of the page,
     so the banner earns less of the fold than it used to. */
  padding: 32px 34px;
  margin-bottom: 26px;
  border: 1px solid var(--line-strong);
  background: #12102b url("../assets/backgrounds/hero.svg") center/cover no-repeat;
}
.hero::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(8, 9, 16, .82) 0%, rgba(8, 9, 16, .45) 55%, rgba(8, 9, 16, .1) 100%);
}
.hero__inner { position: relative; z-index: 2; max-width: 620px; }

/* Catalogue figures on the right of the banner, which was dead space above
   1100px. Hidden below that, where the copy needs the whole width. */
.hero__stats { display: none; }
@media (min-width: 1100px) {
  .hero { display: flex; align-items: center; gap: 32px; }
  .hero__inner { flex: 1 1 auto; }
  .hero__stats {
    position: relative; z-index: 2;
    display: grid;
    grid-template-columns: repeat(2, minmax(96px, 1fr));
    gap: 10px;
    flex: 0 0 auto;
    margin: 0;
  }
  .hero__stats[hidden] { display: none; }
  .hero__stat {
    padding: 12px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: rgba(8, 9, 16, .5);
    backdrop-filter: blur(6px);
  }
  .hero__stat dt {
    font-size: 10px; font-weight: 800; letter-spacing: .13em;
    text-transform: uppercase; color: var(--muted);
  }
  .hero__stat dd {
    margin: 3px 0 0; font-size: 21px; font-weight: 900;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  }
}
.hero__eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--cyan);
  background: rgba(34, 211, 238, .1);
  border: 1px solid rgba(34, 211, 238, .3);
  padding: 5px 12px; border-radius: 999px;
  margin-bottom: 16px;
}
.hero__title { font-size: clamp(28px, 4vw, 44px); font-weight: 900; letter-spacing: -.035em; }
.hero__title em { font-style: normal; background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero__text { color: var(--muted); margin: 14px 0 24px; font-size: 16px; max-width: 470px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; }

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 22px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-weight: 700; font-size: 14px;
  background: #22243a; color: #fff;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease), border-color .18s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(.98); }
.btn--primary { background: var(--grad); color: #0b0c14; box-shadow: 0 10px 26px rgba(108, 76, 255, .42); }
.btn--primary:hover { box-shadow: 0 14px 34px rgba(108, 76, 255, .58); }
.btn--ghost { background: rgba(255, 255, 255, .05); border-color: var(--line-strong); }
.btn--ghost:hover { background: rgba(255, 255, 255, .11); border-color: var(--purple-bright); }
.btn--sm { padding: 8px 16px; font-size: 13px; }
.btn--block { width: 100%; justify-content: center; }

/* ==========================================================================
   Featured carousel
   ========================================================================== */
.featured { display: grid; grid-template-columns: 1.55fr 1fr; gap: 16px; }

.fmain {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line-strong);
  min-height: 360px;
  background: var(--card);
}
.fslide {
  position: absolute; inset: 0;
  opacity: 0; visibility: hidden;
  transform: scale(1.04);
  transition: opacity .55s var(--ease), transform .8s var(--ease), visibility .55s;
}
.fslide.is-active { opacity: 1; visibility: visible; transform: none; }
/* Letterboxed on a blurred copy of itself, so art with a wordmark painted into
   it is never cropped mid-word by this pane's near-square shape. Same
   treatment as .gcard--tall uses for its 16:9 preview. */
.fslide__art {
  position: absolute; inset: -1px;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  filter: blur(26px) saturate(1.35) brightness(.55);
  transform: scale(1.25);
}
.fslide img { position: relative; width: 100%; height: 100%; object-fit: contain; }
.fslide__shade {
  position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(8, 9, 16, .95) 8%, rgba(8, 9, 16, .35) 55%, rgba(8, 9, 16, .1) 100%);
}
.fslide__body { position: absolute; left: 0; right: 0; bottom: 0; padding: 28px 30px; }
.fslide__cat {
  display: inline-block; font-size: 11px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--cyan); margin-bottom: 8px;
}
.fslide__title { font-size: clamp(26px, 3.2vw, 38px); font-weight: 900; letter-spacing: -.035em; }
.fslide__desc { color: var(--muted); margin: 8px 0 18px; max-width: 440px; font-size: 14px; }

.fmain__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(12, 13, 22, .8);
  border: 1px solid var(--line-strong);
  color: #fff; z-index: 4;
  transition: background .2s var(--ease);
}
.fmain__nav:hover { background: var(--purple); }
.fmain__nav--prev { left: 14px; }
.fmain__nav--next { right: 14px; }

.fdots { position: absolute; bottom: 6px; right: 14px; display: flex; gap: 2px; z-index: 4; }
/* The dot stays 8px; the *button* is 24px square so it can actually be hit.
   Padding plus content-box clipping keeps the paint area at the dot while the
   hit area covers the WCAG minimum - the old control was 8x8. */
.fdot {
  width: 8px; height: 8px; box-sizing: content-box;
  padding: 8px; border: 0; background: transparent;
  border-radius: 999px;
  transition: width .25s var(--ease);
}
.fdot::before {
  content: ""; display: block;
  width: 100%; height: 100%; border-radius: 999px;
  background: rgba(255, 255, 255, .3);
  transition: background .25s var(--ease);
}
.fdot:hover::before { background: rgba(255, 255, 255, .6); }
.fdot.is-active { width: 24px; }
.fdot.is-active::before { background: var(--cyan); }

.fside { display: grid; grid-template-rows: repeat(2, 1fr); gap: 16px; }
.fside .gcard { width: auto; height: 100%; display: flex; flex-direction: column; }
.fside .gcard__thumb { flex: 1 1 auto; aspect-ratio: auto; }

/* ==========================================================================
   Leaderboard
   ========================================================================== */
.lb-banner {
  border-radius: var(--radius-lg);
  border: 1px solid rgba(251, 191, 36, .22);
  background:
    radial-gradient(900px 300px at 12% 0%, rgba(251, 191, 36, .14), transparent 60%),
    linear-gradient(135deg, #1a1526, #14131f 60%, #101725);
  padding: 24px 26px;
}
.lb-banner__head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.lb-trophy {
  width: 54px; height: 54px; border-radius: 16px;
  display: grid; place-items: center; font-size: 26px;
  background: linear-gradient(135deg, #fbbf24, #f97316);
  box-shadow: 0 10px 26px rgba(251, 191, 36, .32);
}
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 700;
  background: rgba(255, 255, 255, .07);
  border: 1px solid var(--line-strong);
  color: var(--muted);
}
.chip--gold { color: var(--gold); border-color: rgba(251, 191, 36, .35); background: rgba(251, 191, 36, .1); }
.chip--green { color: var(--green); border-color: rgba(34, 197, 94, .35); background: rgba(34, 197, 94, .1); }

.lb-grid { display: grid; grid-template-columns: 1fr 1.2fr; gap: 20px; align-items: start; }

.lb-list { display: flex; flex-direction: column; gap: 6px; }
.lb-row {
  display: grid;
  grid-template-columns: 34px 34px 1fr auto;
  align-items: center; gap: 12px;
  padding: 9px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid transparent;
  transition: background .16s var(--ease), transform .16s var(--ease);
}
.lb-row:hover { background: rgba(255, 255, 255, .07); transform: translateX(3px); }
.lb-row--me { border-color: rgba(108, 76, 255, .5); background: rgba(108, 76, 255, .13); }
.lb-rank { font-weight: 900; color: var(--muted-dim); text-align: center; font-variant-numeric: tabular-nums; }

/* Medal colour follows the *rank*, not the row's position in the list. Those
   are not the same thing the moment there is a tie: three players level on
   points rank 1, 2, 2, and the position-based rule painted the third of them
   bronze for a rank it does not hold. */
.lb-row[data-rank="1"] .lb-rank { color: #fbbf24; }
.lb-row[data-rank="2"] .lb-rank { color: #cbd5e1; }
.lb-row[data-rank="3"] .lb-rank { color: #d97706; }

.lb-ava {
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  font-weight: 800; font-size: 13px; color: #0b0c14;
  background: var(--grad);
  flex: 0 0 auto;
}
/* The name column is the only elastic one, so it is the one that has to be
   told it may shrink - without min-width:0 a long username stretches the grid
   and pushes the score off the row. */
.lb-who { min-width: 0; }
.lb-name {
  font-weight: 600; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-sub {
  font-size: 11.5px; color: var(--muted-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-score {
  font-weight: 800; color: var(--cyan);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- loading, empty and failed boards -------------------------------------
   Shared by every board on the site: this page, the home banner, the play
   page rail and the arena side panel. */
.lb-row--skel { pointer-events: none; }
.lb-row--skel:hover { transform: none; background: rgba(255, 255, 255, .035); }
.lb-row--skel i {
  display: block; height: 10px; border-radius: 999px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .12), rgba(255, 255, 255, .05));
  background-size: 200% 100%;
  animation: lb-shimmer 1.1s linear infinite;
}
.lb-row--skel .lb-ava { background: rgba(255, 255, 255, .08); animation: lb-shimmer 1.1s linear infinite; }
.lb-row--skel .lb-rank i { width: 14px; margin: 0 auto; }
.lb-row--skel .lb-name-skel { width: 62%; margin-bottom: 6px; }
.lb-row--skel .lb-sub-skel { width: 38%; height: 8px; }
.lb-row--skel .lb-score-skel { width: 48px; }
@keyframes lb-shimmer { to { background-position: -200% 0; } }

.lb-state {
  padding: 26px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.55;
}
.lb-state__icon { font-size: 26px; line-height: 1; margin-bottom: 8px; }
.lb-state strong { display: block; color: #fff; font-size: 14.5px; margin-bottom: 4px; }
.lb-state .btn { margin-top: 14px; }
.lb-state--error { color: #fda4af; }
.lb-state--error strong { color: #fecdd3; }

/* ==========================================================================
   Category cards
   ========================================================================== */
.cat-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.cat-card {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 16px 16px;
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--line);
  overflow: hidden;
  transition: transform .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
/* Not a link: reads as a placeholder, and does not invite a tap that would
   land on an empty listing. */
.cat-card--empty { opacity: .5; cursor: default; }
.cat-card--empty:hover { transform: none; border-color: var(--line); box-shadow: none; }
.cat-card--empty .cat-card__count { font-style: italic; }

.cat-card::before {
  content: ""; position: absolute; inset: 0;
  background: var(--cat-grad, var(--grad));
  opacity: .1;
  transition: opacity .2s var(--ease);
}
.cat-card:hover { transform: translateY(-4px); border-color: var(--line-strong); box-shadow: var(--shadow); }
.cat-card:hover::before { opacity: .22; }
.cat-card__ico {
  position: relative; z-index: 2;
  width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center; font-size: 22px;
  background: rgba(0, 0, 0, .35);
  border: 1px solid var(--line-strong);
}
.cat-card__txt { position: relative; z-index: 2; }
.cat-card__name { font-weight: 700; font-size: 14px; }
.cat-card__count { font-size: 11.5px; color: var(--muted); }

/* Tinted section blocks --------------------------------------------------- */
.block {
  border-radius: var(--radius-lg);
  padding: 22px 22px 10px;
  border: 1px solid var(--line);
  background: var(--block-bg, var(--bg-2));
}
.block--brain { --block-bg: radial-gradient(800px 260px at 6% 0%, rgba(139, 92, 246, .18), transparent 62%), #101122; }
.block--math  { --block-bg: radial-gradient(800px 260px at 6% 0%, rgba(34, 211, 238, .16), transparent 62%), #0c1620; }
.block--arcade{ --block-bg: radial-gradient(800px 260px at 6% 0%, rgba(236, 72, 153, .16), transparent 62%), #180f18; }

/* ==========================================================================
   Footer
   ========================================================================== */
.footer {
  margin-top: 46px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 13px;
}
.footer__cols { display: grid; gap: 26px; grid-template-columns: 1.6fr repeat(3, 1fr); margin-bottom: 24px; }
.footer h4 { font-size: 13px; text-transform: uppercase; letter-spacing: .12em; color: #fff; margin-bottom: 12px; }
.footer a { display: block; padding: 4px 0; transition: color .15s var(--ease); }
.footer a:hover { color: var(--cyan); }
.footer__bottom { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding-bottom: 10px; font-size: 12px; color: var(--muted-dim); }

/* ==========================================================================
   Utilities
   ========================================================================== */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.muted { color: var(--muted); }
.empty {
  padding: 60px 20px; text-align: center;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  color: var(--muted);
}
.empty__emoji { font-size: 40px; margin-bottom: 10px; }
/* An empty state's headline is a real heading where it is the only one on the
   page (the signed-out profile), so it needs the weight of the <strong> it
   replaced rather than a browser-default h1. */
.empty strong, .empty__title {
  display: block;
  font-size: 16px; font-weight: 700; line-height: 1.35;
  color: #fff;
  letter-spacing: -.01em;
  margin: 0;
}
.empty p { margin: 6px 0 0; }
/* Empty state standing in for one shelf rather than a whole page: a single
   compact band, so an absent history costs a line rather than half the fold. */
.empty--inline {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px;
  text-align: left;
}
.empty--inline .empty__emoji { font-size: 24px; margin: 0; flex: 0 0 auto; }
.empty--inline p { margin: 2px 0 0; font-size: 13px; }
.empty--inline .btn { margin: 0 0 0 auto !important; flex: 0 0 auto; }

/* Sponsor slots ------------------------------------------------------------
   Reserved space that stays out of the layout until something is actually
   placed in it — `hidden` is honoured, and an empty slot has no height. */
.ad-slot {
  margin-top: 18px;
  border-radius: var(--radius);
  overflow: hidden;
}
.ad-slot[hidden] { display: none; }
.ad-slot:empty { display: none; }

.toast {
  position: fixed; left: 50%; bottom: 26px;
  transform: translate(-50%, 20px);
  background: var(--card-2);
  border: 1px solid var(--line-strong);
  color: #fff;
  padding: 11px 20px; border-radius: 999px;
  box-shadow: var(--shadow);
  font-size: 14px; font-weight: 600;
  opacity: 0; pointer-events: none;
  transition: opacity .22s var(--ease), transform .22s var(--ease);
  z-index: 200;
}
.toast.is-open { opacity: 1; transform: translate(-50%, 0); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ==========================================================================
   Game preview
   --------------------------------------------------------------------------
   Clicking a card opens this before the game itself. The card stays a real
   <a href="/slug">, so middle-click, ctrl-click and "open in new tab" all
   still reach the game directly - only a plain left-click is intercepted.
   ========================================================================== */
.gpv {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  padding: 20px;
  background: rgba(6, 7, 14, .84);
  /* The blur ramps in with the fade. Going straight to blur(7px) on the first
     frame reads as the page behind snapping out of focus. */
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  opacity: 0;
  transition:
    opacity .22s var(--ease),
    backdrop-filter .28s var(--ease),
    -webkit-backdrop-filter .28s var(--ease);
}
.gpv[hidden] { display: none; }
.gpv.is-on {
  opacity: 1;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.gpv__card {
  width: min(880px, 100%);
  max-height: calc(100vh - 40px);
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line-strong);
  background:
    radial-gradient(700px 240px at 50% 0%, rgba(108, 76, 255, .26), transparent 68%),
    linear-gradient(165deg, #1b1d2b, #111220);
  box-shadow: 0 34px 90px rgba(0, 0, 0, .72);
  overflow: hidden;
  transform: translateY(18px) scale(.965);
  /* Overshoots a touch on the way in, which is what separates "a panel
     appeared" from "a panel was placed there". */
  transition: transform .3s cubic-bezier(.16, .84, .44, 1);
  will-change: transform;
}
.gpv.is-on .gpv__card { transform: none; }

/* ------------------------------------------------------------------- head */
.gpv__head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.gpv__art {
  width: 42px; height: 42px; flex: 0 0 auto;
  border-radius: 11px; overflow: hidden;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .05);
}
.gpv__art img { width: 100%; height: 100%; object-fit: cover; }
.gpv__id { min-width: 0; margin-right: auto; }
.gpv__title {
  font-size: 17px; font-weight: 800; letter-spacing: -.02em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gpv__sub {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gpv__close {
  width: 36px; height: 36px; flex: 0 0 auto;
  display: grid; place-items: center;
  border-radius: 10px; border: 1px solid var(--line);
  background: rgba(255, 255, 255, .05);
  color: var(--muted); font-size: 17px; line-height: 1;
  transition: all .16s var(--ease);
}
.gpv__close:hover { color: #fff; background: rgba(255, 255, 255, .13); }

/* ------------------------------------------------------------------ stage */
.gpv__stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  background: #05060c;
  aspect-ratio: 16 / 9;
  display: grid; place-items: center;
  overflow: hidden;
}
.gpv__stage video,
.gpv__stage img {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
  animation: gpv-media .34s var(--ease) both;
}
/* The media element is created after the card is already on screen, so it
   gets its own short settle rather than appearing mid-frame. */
@keyframes gpv-media {
  from { opacity: 0; transform: scale(1.015); }
}
.gpv__spinner {
  position: absolute;
  width: 30px; height: 30px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .12);
  border-top-color: var(--purple-bright);
  animation: gpv-spin .8s linear infinite;
}
.gpv__spinner[hidden] { display: none; }
@keyframes gpv-spin { to { transform: rotate(360deg); } }

/* The label a still preview carries, so nobody waits for a video that was
   never there. */
.gpv__tag {
  position: absolute; left: 12px; bottom: 12px;
  padding: 5px 11px; border-radius: 999px;
  font-size: 11px; font-weight: 700;
  background: rgba(6, 7, 14, .72);
  border: 1px solid var(--line-strong);
  color: var(--muted);
  backdrop-filter: blur(4px);
}
.gpv__tag[hidden] { display: none; }

/* ------------------------------------------------------------------ foot */
.gpv__foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 13px 16px;
  border-top: 1px solid var(--line);
  flex: 0 0 auto;
}
.gpv__vctl { display: flex; gap: 8px; }
.gpv__vctl[hidden] { display: none; }
.gpv__icon {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 10px; border: 1px solid var(--line);
  background: rgba(255, 255, 255, .05);
  color: var(--muted); font-size: 15px; line-height: 1;
  transition: all .16s var(--ease);
}
.gpv__icon:hover { color: #fff; background: rgba(255, 255, 255, .13); }
.gpv__blurb {
  flex: 1 1 200px; min-width: 0;
  font-size: 12.5px; line-height: 1.45; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.gpv__blurb:empty { display: none; }
.gpv__foot .btn { flex: 0 0 auto; }

/* --------------------------------------------------------------- responsive
   On a phone the card fills the screen and the stage takes the room the
   chrome does not, so a 16:9 video is never cropped or pushed off. */
@media (max-width: 620px) {
  .gpv { padding: 12px; }
  .gpv__card { width: 100%; max-height: calc(100vh - 24px); }
  /* The card hugs its content rather than stretching to the full height: the
     previews are 16:9, and a full-height sheet on a 9:16 phone is mostly
     letterbox above and below the thing you came to look at. */
  .gpv__stage { aspect-ratio: 16 / 9; flex: 0 0 auto; }

  /* The description used to be hidden outright here, which took it away on
     the one screen where the reader has least context for what the game is.
     It moves to its own row above the controls instead. */
  .gpv__foot { padding: 12px; row-gap: 12px; }
  .gpv__blurb { flex: 1 1 100%; order: -1; -webkit-line-clamp: 3; }
  .gpv__vctl { flex: 0 0 auto; }
  .gpv__foot .btn--primary { flex: 1 1 auto; justify-content: center; }

  /* Thumb-sized targets for the two things you reach for most. */
  .gpv__close { width: 44px; height: 44px; }
  .gpv__icon { width: 44px; height: 44px; }
}

/* A landscape phone has almost no vertical room: cap the stage so the title
   and the Play button are never pushed off the bottom of the sheet. */
@media (max-height: 460px) and (orientation: landscape) {
  .gpv { padding: 8px; }
  .gpv__card { max-height: calc(100vh - 16px); }
  .gpv__stage { aspect-ratio: auto; flex: 1 1 auto; min-height: 90px; }
  .gpv__head { padding: 8px 12px; }
  .gpv__foot { padding: 8px 12px; }
  .gpv__blurb { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .gpv, .gpv__card { transition: none; }
  .gpv__stage video, .gpv__stage img { animation: none; }
  .gpv__spinner { animation-duration: 2s; }
}
