/* ==========================================================================
   TwicePlay — Reusable components
   Every visual element on the platform is defined once, here.
   ========================================================================== */

/* ==========================================================================
   1. Buttons
   ========================================================================== */

.btn {
  --btn-bg: var(--surface-2);
  --btn-fg: var(--text);
  --btn-bd: var(--border);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 0.66rem 1.15rem;
  border: 1px solid var(--btn-bd);
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  isolation: isolate;
  transition: transform var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              box-shadow var(--t-mid) var(--ease),
              color var(--t-fast) var(--ease);
}

.btn:hover { background: var(--surface-3); border-color: var(--border-strong); transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.985); }
.btn[disabled],
.btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }

.btn svg { flex: 0 0 auto; }

/* Primary — the platform's single loudest control */
.btn-primary {
  --btn-fg: var(--primary-ink);
  --btn-bd: transparent;
  background: var(--grad-brand);
  box-shadow: var(--sh-glow);
}
.btn-primary:hover {
  background: var(--grad-brand);
  filter: brightness(1.06);
  box-shadow: 0 16px 46px -12px rgba(255, 167, 34, 0.6);
  border-color: transparent;
}

.btn-accent {
  --btn-fg: var(--accent-ink);
  --btn-bd: transparent;
  background: var(--grad-accent);
  box-shadow: var(--sh-glow-accent);
}
.btn-accent:hover { background: var(--grad-accent); filter: brightness(1.06); border-color: transparent; }

.btn-ghost {
  --btn-bg: transparent;
  --btn-bd: var(--border);
}
.btn-ghost:hover { background: var(--surface-2); }

.btn-quiet {
  --btn-bg: transparent;
  --btn-bd: transparent;
  --btn-fg: var(--text-dim);
  padding: 0.5rem 0.75rem;
}
.btn-quiet:hover { --btn-fg: var(--text); background: var(--surface-2); border-color: transparent; }

.btn-lg { padding: 0.9rem 1.6rem; font-size: var(--fs-md); }
.btn-sm { padding: 0.42rem 0.85rem; font-size: var(--fs-xs); }

.btn-icon {
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: var(--r-md);
}

.btn-block { width: 100%; }

/* A button must never be the reason a page scrolls sideways. */
.btn { max-width: 100%; }

/* ==========================================================================
   2. Badges, pills, chips
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 0.22rem 0.55rem;
  border-radius: var(--r-xs);
  background: var(--surface-3);
  color: var(--text-soft);
  font-family: var(--font-display);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  line-height: 1.5;
  white-space: nowrap;
}

.badge-new     { background: var(--accent-soft);  color: var(--brand-teal-300); box-shadow: inset 0 0 0 1px rgba(34,203,180,.28); }
.badge-trend   { background: var(--primary-soft); color: var(--brand-amber-300); box-shadow: inset 0 0 0 1px rgba(255,167,34,.28); }
.badge-hot     { background: rgba(255,95,109,.14); color: #ff97a1; box-shadow: inset 0 0 0 1px rgba(255,95,109,.28); }
.badge-soon    { background: rgba(124,92,255,.16); color: #c0b0ff; box-shadow: inset 0 0 0 1px rgba(124,92,255,.3); }

:root[data-theme="light"] .badge-new   { color: var(--brand-teal-600); }
:root[data-theme="light"] .badge-trend { color: var(--brand-amber-700); }
:root[data-theme="light"] .badge-soon  { color: #5b3fd6; }

/* Category chip — used in the category filter bar and on cards */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-soft);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--t-fast) var(--ease);
}

.chip .chip-ico { font-size: 1.05em; line-height: 1; }
.chip:hover { color: var(--text); background: var(--surface-2); border-color: var(--border-strong); transform: translateY(-1px); }

.chip[aria-pressed="true"],
.chip.is-active {
  background: var(--primary-soft);
  border-color: rgba(255, 167, 34, 0.45);
  color: var(--primary);
}

.chip-count {
  font-size: var(--fs-2xs);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.chip-row {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  padding-bottom: var(--sp-2);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.chip-row::-webkit-scrollbar { display: none; }

/* ==========================================================================
   3. Star rating
   ========================================================================== */

.rating {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}

.rating .star { width: 13px; height: 13px; fill: var(--star); flex: 0 0 auto; }

.rating-stars { display: inline-flex; gap: 2px; }
.rating-stars .star { width: 15px; height: 15px; fill: var(--star); }
.rating-stars .star.is-empty { fill: var(--surface-3); }

:root[data-theme="light"] .rating-stars .star.is-empty { fill: #d5dce6; }

/* ==========================================================================
   4. Game card — the atom of the entire platform.
      Markup is produced by js/components.js → renderGameCard()
   ========================================================================== */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr));
  gap: var(--sp-5);
}

.card-grid--tight { --card-min: 158px; gap: var(--sp-4); }

/* Spotlight: larger cards that stay a readable size and sit left, instead of
   stretching across a row they cannot fill. Used where a shelf is expected to
   hold only a handful of games — "Ready to play" today holds the two titles
   that are actually live. */
.card-grid--spotlight {
  grid-template-columns: repeat(auto-fill, minmax(250px, 330px));
  justify-content: start;
}

.game-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  overflow: hidden;
  transition: transform var(--t-mid) var(--ease),
              box-shadow var(--t-mid) var(--ease),
              border-color var(--t-mid) var(--ease);
  will-change: transform;
}

.game-card:hover,
.game-card:focus-within {
  transform: translateY(-6px);
  border-color: var(--border-strong);
  box-shadow: var(--sh-lg);
}

.game-card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
  overflow: hidden;
}

.game-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease-out), opacity var(--t-mid) var(--ease);
}

.game-card__img[data-loaded="false"] { opacity: 0; }

.game-card:hover .game-card__img { transform: scale(1.07); }

.game-card__flags {
  position: absolute;
  inset: var(--sp-3) var(--sp-3) auto var(--sp-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-2);
  pointer-events: none;
}

.game-card__fav {
  position: absolute;
  top: var(--sp-2);
  right: var(--sp-2);
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: rgba(8, 11, 16, 0.6);
  backdrop-filter: blur(8px);
  color: #fff;
  opacity: 0;
  transform: scale(0.85);
  transition: all var(--t-mid) var(--ease);
  z-index: 4;
}

.game-card:hover .game-card__fav,
.game-card__fav:focus-visible,
.game-card__fav[aria-pressed="true"] { opacity: 1; transform: scale(1); }

/* Touch devices have no hover, so the heart was invisible — and therefore
   unusable — on phones and tablets. Show it there permanently. */
@media (hover: none) {
  .game-card__fav { opacity: 1; transform: scale(1); }
}
.game-card__fav:hover { background: rgba(8, 11, 16, 0.85); }
.game-card__fav svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; }
.game-card__fav[aria-pressed="true"] { color: var(--danger); }
.game-card__fav[aria-pressed="true"] svg { fill: currentColor; stroke: currentColor; }

/* Play overlay — appears on hover, is the primary affordance */
.game-card__overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: linear-gradient(to top, rgba(4, 7, 11, 0.85), rgba(4, 7, 11, 0.25));
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease);
  z-index: 1;
  /* Purely decorative: clicks must reach .game-card__link underneath it. */
  pointer-events: none;
}

.game-card:hover .game-card__overlay,
.game-card:focus-within .game-card__overlay { opacity: 1; }

.game-card__play {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.6rem 1.15rem;
  border-radius: var(--r-pill);
  background: var(--grad-brand);
  color: var(--primary-ink);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  box-shadow: var(--sh-glow);
  transform: translateY(10px) scale(0.94);
  transition: transform var(--t-mid) var(--ease-out);
}

.game-card:hover .game-card__play,
.game-card:focus-within .game-card__play { transform: none; }
.game-card__play svg { width: 13px; height: 13px; fill: currentColor; }

.game-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
}

.game-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-base);
  font-weight: 650;
  line-height: 1.28;
  letter-spacing: -0.01em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.game-card__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-top: auto;
}

.game-card__cat {
  position: relative;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--text-dim);
  transition: color var(--t-fast) var(--ease);
}
.game-card__cat:hover { color: var(--accent); }

/* Whole-card link target: above the decorative overlay, below the fav button */
.game-card__link {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: var(--r-lg);
}

/* Compact horizontal variant — used in "related games" and recently played */
.game-strip { display: flex; flex-direction: column; gap: var(--sp-2); }

.game-strip-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2);
  border-radius: var(--r-md);
  border: 1px solid transparent;
  transition: all var(--t-fast) var(--ease);
}
.game-strip-item:hover { background: var(--surface-2); border-color: var(--border); }

.game-strip-item__thumb {
  width: 74px;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-sm);
  object-fit: cover;
  flex: 0 0 auto;
  background: var(--surface-2);
}

.game-strip-item__title {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 650;
  line-height: 1.3;
}

.game-strip-item__sub {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: 2px;
}

/* ==========================================================================
   5. Category card
   ========================================================================== */

.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: var(--sp-4);
}

.cat-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
  transition: transform var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease), box-shadow var(--t-mid) var(--ease);
}

.cat-card::after {
  content: "";
  position: absolute;
  inset: auto -30% -60% auto;
  width: 170px;
  height: 170px;
  border-radius: 50%;
  background: var(--cat-color, var(--primary));
  opacity: 0.16;
  filter: blur(6px);
  transition: transform var(--t-slow) var(--ease-out), opacity var(--t-mid) var(--ease);
}

.cat-card:hover { transform: translateY(-4px); border-color: var(--border-strong); box-shadow: var(--sh-md); }
.cat-card:hover::after { transform: scale(1.35) translate(-10%, -12%); opacity: 0.26; }

.cat-card__ico {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--cat-color, var(--primary)) 18%, transparent);
  font-size: 1.35rem;
  line-height: 1;
  position: relative;
  z-index: 1;
}

.cat-card__name {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 700;
  position: relative;
  z-index: 1;
}

.cat-card__count {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  position: relative;
  z-index: 1;
}

/* ==========================================================================
   6. Header / navigation
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(18px) saturate(160%);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-mid) var(--ease), background var(--t-mid) var(--ease);
}

.site-header.is-stuck {
  border-bottom-color: var(--border);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  box-shadow: 0 8px 30px -20px rgba(0, 0, 0, 0.8);
}

.header-inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--sp-5);
}

/* --- Logo --- */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex: 0 0 auto;
  transition: opacity var(--t-fast) var(--ease);
}
.logo:hover { opacity: 0.85; }

.logo__mark {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  filter: drop-shadow(0 4px 12px rgba(255, 167, 34, 0.35));
}

.logo__word {
  font-family: var(--font-display);
  font-size: 1.28rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1;
}
.logo__word .a { color: var(--text); }
.logo__word .b {
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* The primary navigation is the rail in css/layout.css (PORTAL SHELL).
   The horizontal header nav it replaced is gone, not hidden. */

/* --- Header actions --- */
.header-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
  margin-left: auto;
}

/* --- Search field in header --- */
.search-field {
  position: relative;
  display: flex;
  align-items: center;
  width: clamp(180px, 24vw, 320px);
}

.search-field__icon {
  position: absolute;
  left: 13px;
  width: 16px;
  height: 16px;
  color: var(--text-faint);
  pointer-events: none;
}

.search-field__input {
  width: 100%;
  padding: 0.6rem 2.4rem 0.6rem 2.4rem;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  transition: all var(--t-fast) var(--ease);
}

.search-field__input::placeholder { color: var(--text-faint); }
.search-field__input:hover { border-color: var(--border-strong); }
.search-field__input:focus {
  outline: none;
  border-color: rgba(34, 203, 180, 0.55);
  background: var(--surface-2);
  box-shadow: 0 0 0 4px var(--accent-soft);
}

.search-field__clear {
  position: absolute;
  right: 8px;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  color: var(--text-faint);
  transition: all var(--t-fast) var(--ease);
}
.search-field__clear:hover { color: var(--text); background: var(--surface-3); }
.search-field__clear svg { width: 13px; height: 13px; }

/* --- Search suggestion dropdown --- */
.search-pop {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: min(420px, calc(100vw - 2 * var(--gutter)));
  max-height: min(70vh, 460px);
  overflow-y: auto;
  padding: var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--bg-elevated);
  box-shadow: var(--sh-lg);
  z-index: 120;
  animation: ph-pop 160ms var(--ease-out) both;
}

.search-pop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.search-pop__foot {
  border-top: 1px solid var(--border);
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
}

/* --- Theme toggle --- */
.theme-toggle svg { width: 17px; height: 17px; }
:root[data-theme="light"] .theme-toggle .ico-moon { display: none; }
:root:not([data-theme="light"]) .theme-toggle .ico-sun { display: none; }

/* --- Mobile menu button --- */
.burger {
  display: none;
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  position: relative;
}
.burger:hover { background: var(--surface-2); }

.burger span {
  position: absolute;
  left: 11px;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--text);
  transition: transform var(--t-mid) var(--ease), opacity var(--t-fast) var(--ease);
}
.burger span:nth-child(1) { top: 13px; }
.burger span:nth-child(2) { top: 19px; }
.burger span:nth-child(3) { top: 25px; }

.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* --- Scrim, shared by the drawer state of the rail --- */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 130;
  background: rgba(4, 7, 11, 0.6);
  backdrop-filter: blur(3px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-mid) var(--ease);
}
.scrim.is-open { opacity: 1; pointer-events: auto; }

/* The slide-out menu is the same .sidenav element as the desktop rail,
   moved off-canvas by a media query in css/layout.css. There is no
   separate drawer component any more. */

/* ==========================================================================
   7. Hero / featured
   ========================================================================== */

.hero {
  position: relative;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  align-items: stretch;
  gap: 0;
  border-radius: var(--r-xl);
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
  min-height: 380px;
  box-shadow: var(--sh-lg);
}

.hero__content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-4);
  padding: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  position: relative;
  z-index: 2;
}

.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--primary);
}

.hero__title { font-size: var(--fs-3xl); }

.hero__desc {
  color: var(--text-soft);
  font-size: var(--fs-md);
  max-width: 46ch;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.hero__meta { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.hero__cta { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-2); }

.hero__media { position: relative; overflow: hidden; }

.hero__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 900ms var(--ease-out), opacity var(--t-slow) var(--ease);
}

.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, var(--surface) 0%, color-mix(in srgb, var(--surface) 55%, transparent) 32%, transparent 68%);
}

.hero:hover .hero__media img { transform: scale(1.04); }

/* Slide transition */
.hero__slide { display: contents; }
.hero.is-swapping .hero__content > *,
.hero.is-swapping .hero__media img { animation: ph-fade var(--t-mid) var(--ease) both; }

.hero__dots {
  position: absolute;
  bottom: var(--sp-5);
  left: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  display: flex;
  gap: var(--sp-2);
  z-index: 3;
}

.hero__dot {
  width: 26px;
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--border-strong);
  transition: all var(--t-mid) var(--ease);
}
.hero__dot:hover { background: var(--text-dim); }
.hero__dot.is-active { width: 42px; background: var(--grad-brand); }

/* ==========================================================================
   8. Skeletons / loading / empty states
   ========================================================================== */

.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 45%, var(--surface-2) 65%);
  background-size: 220% 100%;
  animation: ph-shimmer 1.5s linear infinite;
  border-radius: var(--r-sm);
}

.sk-card {
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
}
.sk-card__media { aspect-ratio: 4 / 3; }
.sk-card__body { padding: var(--sp-3) var(--sp-4) var(--sp-4); display: grid; gap: var(--sp-2); }
.sk-line { height: 11px; }
.sk-line--sm { height: 9px; width: 55%; }

.spinner {
  width: 22px;
  height: 22px;
  border: 2.5px solid var(--surface-3);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: ph-spin 720ms linear infinite;
}

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-16) var(--sp-5);
  text-align: center;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
  animation: ph-rise var(--t-slow) var(--ease-out) both;
}

.empty__ico {
  width: 62px;
  height: 62px;
  display: grid;
  place-items: center;
  border-radius: var(--r-lg);
  background: var(--surface-2);
  color: var(--text-faint);
}
.empty__ico svg { width: 28px; height: 28px; }

.empty__title { font-size: var(--fs-lg); }
.empty__text { color: var(--text-dim); max-width: 46ch; font-size: var(--fs-sm); }

/* ==========================================================================
   9. Panels, notices, toast
   ========================================================================== */

.panel {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  padding: var(--sp-5);
}

.panel__title {
  font-size: var(--fs-md);
  margin-bottom: var(--sp-3);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.kv { display: grid; gap: var(--sp-3); }
.kv__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); font-size: var(--fs-sm); }
.kv__k { color: var(--text-dim); }
.kv__v { font-weight: 600; text-align: right; }

.notice {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-md);
  border: 1px solid rgba(124, 92, 255, 0.3);
  background: rgba(124, 92, 255, 0.08);
  font-size: var(--fs-sm);
  color: var(--text-soft);
}
.notice svg { width: 18px; height: 18px; flex: 0 0 auto; color: #c0b0ff; }

.toast-host {
  position: fixed;
  left: 50%;
  bottom: var(--sp-6);
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-items: center;
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0.7rem 1.1rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: var(--bg-elevated);
  box-shadow: var(--sh-lg);
  font-size: var(--fs-sm);
  font-weight: 600;
  animation: ph-pop 200ms var(--ease-out) both;
}
.toast.is-out { animation: ph-fade var(--t-mid) var(--ease) reverse both; }

/* ==========================================================================
   10. Breadcrumb + back button
   ========================================================================== */

.crumbs {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  font-size: var(--fs-xs);
  color: var(--text-faint);
  margin-bottom: var(--sp-4);
}
.crumbs a { color: var(--text-dim); transition: color var(--t-fast) var(--ease); }
.crumbs a:hover { color: var(--accent); }
.crumbs .sep { opacity: 0.5; }

/* ==========================================================================
   11. Footer
   ========================================================================== */

.site-footer {
  margin-top: var(--sp-20);
  border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg-elevated) 70%, transparent);
}

.footer-top {
  display: grid;
  grid-template-columns: 1.5fr repeat(3, 1fr);
  gap: var(--sp-8);
  padding-block: var(--sp-12) var(--sp-8);
}

.footer-brand { display: flex; flex-direction: column; gap: var(--sp-3); max-width: 34ch; }
.footer-brand p { color: var(--text-dim); font-size: var(--fs-sm); }

.footer-col h4 {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--sp-3);
}

.footer-col ul { display: grid; gap: var(--sp-2); }

.footer-col a {
  font-size: var(--fs-sm);
  color: var(--text-soft);
  transition: color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  display: inline-block;
}
.footer-col a:hover { color: var(--primary); transform: translateX(2px); }

.socials { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }

.social {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  transition: all var(--t-fast) var(--ease);
}
.social:hover { color: var(--primary); border-color: rgba(255, 167, 34, 0.4); background: var(--primary-soft); transform: translateY(-2px); }
.social svg { width: 17px; height: 17px; fill: currentColor; }

.footer-bottom {
  border-top: 1px solid var(--border);
  padding-block: var(--sp-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  font-size: var(--fs-xs);
  color: var(--text-faint);
}

.footer-bottom nav { display: flex; gap: var(--sp-4); flex-wrap: wrap; }
.footer-bottom nav a:hover { color: var(--text-soft); }

/* ==========================================================================
   12. Discovery — facet bar, tag cloud
   Added with Step 3 (library & discovery). Uses only existing tokens so both
   themes and every breakpoint are covered automatically.
   ========================================================================== */

.facets { margin-bottom: var(--sp-4); }

.facets__row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
}

.facets__label {
  flex: 0 0 auto;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.facets__clear { flex: 0 0 auto; font-size: var(--fs-xs); }

/* Toggle-style chip (the "Playable now" filter) */
.chip--toggle svg { width: 15px; height: 15px; }
.chip--toggle[aria-pressed="true"] {
  background: var(--accent-soft);
  border-color: rgba(34, 203, 180, 0.45);
  color: var(--accent);
}

.listing-bar { margin-bottom: var(--sp-5); }

/* --- Tag cloud (categories page) --- */
.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.tag-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-soft);
  font-size: var(--fs-sm);
  font-weight: 600;
  transition: all var(--t-fast) var(--ease);
}

.tag-pill:hover {
  color: var(--accent);
  border-color: rgba(34, 203, 180, 0.45);
  background: var(--accent-soft);
  transform: translateY(-1px);
}

.tag-pill__n {
  font-size: var(--fs-2xs);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
  .facets__label { display: none; }
}

/* ==========================================================================
   13. Personal features — ratings split, library page, header library button
   ========================================================================== */

/* --- Platform rating vs your rating, side by side and labelled --- */
.rating-split {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-4);
  align-items: start;
}

.rating-split__col {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
}

.rating-split__col + .rating-split__col {
  padding-left: var(--sp-4);
  border-left: 1px solid var(--border);
}

.rating-split__label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.rating-split__value {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.rating-split__of {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--text-faint);
  margin-left: 0.2rem;
}

.rating-split__note {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  text-wrap: pretty;
}

.link-btn {
  color: var(--accent);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  padding: 0;
}
.link-btn:hover { color: var(--text); }

/* --- Header library button with a favourite count --- */
.library-btn { position: relative; }

.library-btn__count {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: var(--grad-brand);
  color: var(--primary-ink);
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--bg);
}

/* --- Library page --- */
.library-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-8);
}

.rated-list { display: grid; gap: var(--sp-2); }

.rated-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  transition: all var(--t-fast) var(--ease);
}
.rated-row:hover { border-color: var(--border-strong); background: var(--surface-2); }

.rated-row__thumb {
  width: 56px;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-sm);
  object-fit: cover;
  flex: 0 0 auto;
  background: var(--surface-2);
}

.rated-row__main { min-width: 0; flex: 1 1 auto; }

.rated-row__title {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 650;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rated-row__sub { font-size: var(--fs-xs); color: var(--text-dim); }

.rated-row__mine { flex: 0 0 auto; display: flex; align-items: center; gap: var(--sp-2); }

@media (max-width: 640px) {
  .rating-split { grid-template-columns: 1fr; gap: var(--sp-3); }
  .rating-split__col + .rating-split__col {
    padding-left: 0;
    padding-top: var(--sp-3);
    border-left: 0;
    border-top: 1px solid var(--border);
  }
}

/* ==========================================================================
   14. Gamification — daily challenge, stats, streak, achievements, board
   Built entirely from existing tokens, so both themes and every breakpoint
   are covered without new colour decisions.
   ========================================================================== */

.hub-nav { margin-bottom: var(--sp-8); }

/* --- Daily challenge card --- */
.daily-card {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--sh-md);
  position: relative;
}

.daily-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--grad-brand);
  z-index: 2;
}
.daily-card--completed::before { background: var(--grad-accent); }

.daily-card__art { position: relative; overflow: hidden; background: var(--surface-2); }
.daily-card__art img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease-out);
}
.daily-card:hover .daily-card__art img { transform: scale(1.04); }

.daily-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  min-width: 0;
}

.daily-card__top { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.daily-card__title { font-size: var(--fs-2xl); }
.daily-card__desc {
  color: var(--text-soft);
  font-size: var(--fs-sm);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.daily-card__meta { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }

/* Compact daily flag on the game page sidebar */
.daily-flag {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-md);
  background: var(--primary-soft);
  border: 1px solid rgba(255, 167, 34, 0.3);
  font-size: var(--fs-sm);
}
.daily-flag.is-done { background: var(--accent-soft); border-color: rgba(34, 203, 180, 0.35); }
.daily-flag__ico { font-size: 1.3rem; line-height: 1; flex: 0 0 auto; }

.score-value {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--primary);
}

/* --- Stat grid --- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: var(--sp-3);
}
.stat__hint {
  font-size: var(--fs-2xs);
  color: var(--text-faint);
  margin-top: 2px;
}

/* --- Streak --- */
.streak-strip {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--surface) 65%, transparent);
  flex-wrap: wrap;
}
.streak-strip--empty { justify-content: center; text-align: center; }

.streak-strip__flame {
  position: relative;
  font-size: 1.9rem;
  line-height: 1;
  filter: grayscale(1) opacity(0.4);
  transition: filter var(--t-mid) var(--ease);
  flex: 0 0 auto;
}
.streak-strip__flame.is-lit { filter: none; }

.streak-strip__n {
  position: absolute;
  right: -8px;
  bottom: -6px;
  min-width: 20px;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--grad-brand);
  color: var(--primary-ink);
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 800;
  line-height: 18px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--bg);
}

.streak-strip__label { font-size: var(--fs-sm); font-weight: 600; margin-bottom: var(--sp-2); }
.streak-days { display: flex; gap: var(--sp-2); }

.streak-day {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-faint);
  font-size: var(--fs-2xs);
  font-weight: 700;
}
.streak-day.is-active {
  background: var(--primary-soft);
  border-color: rgba(255, 167, 34, 0.45);
  color: var(--primary);
}
.streak-day.is-today { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --- Achievements --- */
.ach-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--sp-4);
}

.ach {
  position: relative;
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  transition: transform var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease),
              box-shadow var(--t-mid) var(--ease);
}
.ach:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--sh-md); }

.ach__ico {
  font-size: 1.6rem;
  line-height: 1;
  flex: 0 0 auto;
  filter: grayscale(1) opacity(0.35);
  transition: filter var(--t-mid) var(--ease);
}
.ach.is-unlocked .ach__ico { filter: none; }

.ach__body { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); flex: 1 1 auto; }
.ach__name { font-size: var(--fs-base); }
.ach__hint { font-size: var(--fs-xs); color: var(--text-dim); }
.ach__state { font-size: var(--fs-2xs); color: var(--text-faint); font-variant-numeric: tabular-nums; }

.ach__progress {
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
  overflow: hidden;
  margin-top: var(--sp-2);
}
.ach__progress span {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--grad-brand);
  transition: width var(--t-slow) var(--ease-out);
}

.ach.is-unlocked { border-color: rgba(255, 167, 34, 0.35); background: color-mix(in srgb, var(--primary-soft) 40%, var(--surface)); }
.ach--silver.is-unlocked { border-color: rgba(34, 203, 180, 0.35); background: color-mix(in srgb, var(--accent-soft) 40%, var(--surface)); }
.ach--gold.is-unlocked { border-color: rgba(255, 167, 34, 0.55); box-shadow: var(--sh-glow); }

.ach__tick {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--grad-brand);
  color: var(--primary-ink);
  font-size: 11px;
  font-weight: 800;
}

/* --- Personal leaderboard --- */
.board {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
}

.board__head,
.board__row {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) 120px 110px;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
}

.board__head {
  background: var(--surface-2);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.board__row {
  border-top: 1px solid var(--border);
  transition: background var(--t-fast) var(--ease);
}
.board__row:hover { background: var(--surface-2); }

.board__rank {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 800;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.board__rank.is-top { color: var(--primary); }

.board__game { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.board__game img { width: 44px; aspect-ratio: 4/3; border-radius: var(--r-sm); object-fit: cover; flex: 0 0 auto; }
.board__game span { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.board__score {
  font-family: var(--font-display);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-direction: column;
}
.board__meta { font-family: var(--font-body); font-size: var(--fs-2xs); font-weight: 500; color: var(--text-faint); }
.board__when { font-size: var(--fs-xs); color: var(--text-dim); }

@media (max-width: 900px) {
  .daily-card { grid-template-columns: 1fr; }
  .daily-card__art { aspect-ratio: 16 / 9; }
}

@media (max-width: 640px) {
  .board__head { display: none; }
  .board__row {
    grid-template-columns: 34px minmax(0, 1fr) auto;
    grid-template-areas: "rank game score";
    row-gap: var(--sp-1);
  }
  .board__rank { grid-area: rank; }
  .board__game { grid-area: game; }
  .board__score { grid-area: score; text-align: right; align-items: flex-end; }
  .board__when { display: none; }
  .ach-grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   15. Ad slots (Step 7)
   --------------------------------------------------------------------------
   Placeholders for advertising that does not exist yet. Deliberately quiet:
   they sit in the document flow, reserve their own height so nothing shifts
   when a real ad arrives, and never overlap a control or the player.
   ========================================================================== */

.ad-slot {
  display: block;
  width: 100%;
  max-width: 100%;
  margin: var(--sp-6) 0;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background:
    repeating-linear-gradient(
      135deg,
      color-mix(in srgb, var(--surface) 92%, transparent) 0 10px,
      color-mix(in srgb, var(--surface-2) 92%, transparent) 10px 20px
    );
  overflow: hidden;
}

/* Height is reserved up front, so switching a real ad on later does not push
   the page around under someone's cursor. */
.ad-slot--leaderboard { min-height: 90px; }
.ad-slot--rectangle { min-height: 250px; }

.ad-slot__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: inherit;
  padding: var(--sp-4);
  text-align: center;
}

.ad-slot--leaderboard .ad-slot__inner { min-height: 90px; }
.ad-slot--rectangle .ad-slot__inner { min-height: 250px; }

.ad-slot__tag {
  font-family: var(--font-body);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 0.15rem 0.5rem;
  border-radius: var(--r-xs);
  background: var(--surface-3);
}

.ad-slot__label {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  max-width: 42ch;
}

.ad-slot__note {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--text-faint);
}

/* Belt and braces for rule 1: even if a slot were placed inside the player by
   mistake, it renders as nothing rather than covering the game. js/ads.js
   also refuses to fill it. */
.player .ad-slot,
.player__stage .ad-slot {
  display: none !important;
}

/* A slot the owner has switched off takes up no space at all. */
.ad-slot[hidden] { display: none !important; }

@media (max-width: 560px) {
  .ad-slot { margin: var(--sp-5) 0; }
  .ad-slot--rectangle { min-height: 200px; }
  .ad-slot--rectangle .ad-slot__inner { min-height: 200px; }
  .ad-slot__label { font-size: var(--fs-2xs); }
}

/* ==========================================================================
   16. Gameplay previews + the richer card (experience upgrade)
   --------------------------------------------------------------------------
   The clip is layered OVER the thumbnail and fades in once it is really
   playing. The thumbnail is never removed, so if the clip fails, stalls or is
   switched off, what stays on screen is the cover art — never an empty box.
   ========================================================================== */

.game-card__media video.preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 240ms var(--ease);
  /* Purely decorative and never interactive: clicks belong to the card link. */
  pointer-events: none;
  z-index: 1;
}

.game-card__media.is-previewing video.preview { opacity: 1; }

/* While a clip is playing the still underneath stops its hover zoom, so the
   two layers are not moving against each other. */
.game-card__media.is-previewing .game-card__img { transform: none; }

/* A quiet marker that this card has real gameplay behind it. */
.game-card__live {
  position: absolute;
  left: var(--sp-3);
  bottom: var(--sp-3);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0.18rem 0.5rem;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(6px);
  border: 1px solid var(--border-strong);
  color: var(--text-soft);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
}

.game-card:hover .game-card__live,
.game-card__media.is-previewing .game-card__live { opacity: 1; transform: none; }

.game-card__live-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 70%, transparent);
  animation: ph-pulse 2s var(--ease) infinite;
}

@keyframes ph-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
  70%  { box-shadow: 0 0 0 6px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* One line of the game's own description, so a card answers "what is this?" */
.game-card__blurb {
  font-size: var(--fs-xs);
  line-height: 1.5;
  color: var(--text-dim);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
}

/* An explicit action on the card face, not only on hover. */
.game-card__cta {
  position: relative;
  z-index: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: var(--sp-1);
  padding: 0.45rem 0.7rem;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-soft);
  font-size: var(--fs-xs);
  font-weight: 650;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
.game-card__cta svg { width: 11px; height: 11px; fill: currentColor; }

.game-card:hover .game-card__cta:not(.is-soon),
.game-card:focus-within .game-card__cta:not(.is-soon) {
  background: var(--grad-brand);
  border-color: transparent;
  color: var(--primary-ink);
}

.game-card__cta.is-soon { color: var(--text-faint); }

@media (prefers-reduced-motion: reduce) {
  .game-card,
  .game-card__img,
  .game-card__cta,
  .game-card__live { transition: none; }
  .game-card:hover { transform: none; }
  .game-card:hover .game-card__img { transform: none; }
  .game-card__live-dot { animation: none; }
}
