:root {
  --bg: #121018;
  --panel: #1d1926;
  --panel-2: #241f30;
  --line: #393043;
  --text: #f2eef8;
  --muted: #b4abbe;
  --accent: #c8a4ff;
  --accent-solid: #8346df;
  --mint: #7ddbb3;
  --amber: #e8c07a;
  --rose: #ef8fa4;
  --radius: 14px;
  --gutter: 16px;
}

* { box-sizing: border-box; }

/*
 * One focus indicator for the whole interface.
 *
 * Only two inputs had their own, so the other twenty-eight controls fell back
 * to the browser default: 1px, amber, and nothing to do with this palette. The
 * outline follows each element's own border-radius, so the pills keep theirs.
 */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/*
 * Headings take focus only so keyboard and screen-reader users land where the
 * page moved them (a game opening, Donar, Admin). They cannot be pressed, so a
 * ring round them reads as a stray box. The focus itself stays where it is.
 */
h1[tabindex="-1"]:focus, h2[tabindex="-1"]:focus { outline: none; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "DM Sans", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.15; margin: 0 0 .4rem; font-weight: 700; letter-spacing: -.02em; }
h1 { font-size: clamp(1.8rem, 4.5vw, 2.7rem); }
/* Panel headings are h2: they sit directly under the page h1, and jumping the
   level left a gap for anyone navigating by heading. */
h2 { font-size: 1.15rem; }
p { margin: 0 0 .6rem; }
a { color: var(--accent); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.eyebrow {
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); margin-bottom: .35rem;
}
.muted { color: var(--muted); }
.small { font-size: .82rem; }

/* ── Top bar ──────────────────────────────────────────────────────────── */

/* Both bars stick as one; the header no longer sticks on its own. */
.topbar-stack { position: sticky; top: 0; z-index: 20; }

.topbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px var(--gutter);
  border-bottom: 1px solid var(--line);
  background: rgba(18, 16, 24, .92);
  backdrop-filter: blur(10px);
}
.brand {
  display: flex; align-items: center; gap: 9px;
  font-weight: 700; color: var(--text); text-decoration: none; flex-shrink: 0;
}
.brand-mark {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 9px;
  background: var(--accent-solid); color: #fff; font-size: .8rem; font-weight: 700;
}
/*
 * Donar, the profile and the language share one shape: a 44px pill with the
 * same hairline. The language used to be lit in solid purple, the loudest
 * thing in the bar, louder than the one action it exists beside. The chosen
 * flag now sits on a raised tint; the other one is dimmed until hovered.
 */
.lang-switch {
  display: inline-flex; padding: 3px; gap: 2px; border-radius: 999px;
  border: 1px solid var(--line);
}
.lang-switch button {
  display: inline-grid; place-items: center;
  min-width: 44px; min-height: 36px; padding: 0 10px; border-radius: 999px; border: 0;
  background: transparent; cursor: pointer; transition: background-color .15s;
}
.lang-switch .flag {
  width: 22px; height: 15px; border-radius: 3px; display: block;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .14);
  opacity: .45; filter: saturate(.6); transition: opacity .15s, filter .15s;
}
.lang-switch button:hover .flag { opacity: .8; filter: none; }
.lang-switch button[aria-pressed="true"] { background: var(--panel-2); }
.lang-switch button[aria-pressed="true"] .flag { opacity: 1; filter: none; }

.account { position: relative; }
.account-pill {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 12px 0 7px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; color: var(--text);
  font: inherit; font-size: .84rem; font-weight: 500; cursor: pointer;
  transition: border-color .15s;
}
.account-pill:hover, .account-pill[aria-expanded="true"] { border-color: var(--accent); }
.account-pill img, .account-initial { width: 28px; height: 28px; border-radius: 50%; flex: none; }
.account-initial {
  display: inline-grid; place-items: center; background: var(--panel-2); color: var(--accent); font-size: .78rem;
}
.account-name { max-width: 14ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-chevron {
  width: 12px; height: 12px; fill: none; stroke: var(--muted); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round; transition: transform .15s;
}
.account-pill[aria-expanded="true"] .account-chevron { transform: rotate(180deg); }
.account-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; min-width: 180px;
  display: grid; padding: 6px; border-radius: 12px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: 0 18px 40px rgba(0, 0, 0, .5);
}
.account-menu[hidden] { display: none; }
.account-menu a {
  display: flex; align-items: center; min-height: 40px; padding: 0 12px; border-radius: 8px;
  color: var(--text); text-decoration: none; font-size: .88rem;
}
.account-menu a:hover, .account-menu a:focus-visible { background: var(--panel-2); }
.account-menu a:focus-visible { outline-offset: -2px; }
#watchlist { scroll-margin-top: 96px; }

/* On a phone the name is what gives way; the avatar still says whose it is. */
@media (max-width: 480px) {
  .account-name { display: none; }
  .account-pill { padding-right: 10px; }
}
/* Donar and the account travel together at the end of the bar. */
.top-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.donate-link {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--text);
  text-decoration: none; font-size: .84rem; font-weight: 500; white-space: nowrap;
  transition: border-color .15s, color .15s;
}
.donate-link:hover { border-color: var(--amber); color: var(--amber); }
.donate-link[hidden] { display: none; }

/* Shown only once the game's own header actions have scrolled off. [hidden] has
   to be spelled out, because display:flex would otherwise override it. */
.game-bar {
  display: flex; align-items: center; gap: 12px; min-width: 0; font-size: .84rem;
  padding: 8px var(--gutter);
  background: rgba(18, 16, 24, .92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.game-bar[hidden] { display: none; }
.game-bar-name {
  color: var(--muted); max-width: 40ch; margin-right: auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.game-bar-price { font-weight: 700; white-space: nowrap; }
.game-bar-price b { color: var(--mint); font-weight: 700; }
.game-bar-buy {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px;
  border-radius: 999px; border: 1px solid var(--accent); color: var(--accent);
  text-decoration: none; font-weight: 500; white-space: nowrap;
}
.game-bar-buy:hover { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; }

/*
 * On a narrow screen the bar cannot live in the header: as a fourth row it took
 * the top bar to 235px of a 417px viewport — 56% of the screen, permanently,
 * to keep one link reachable. Fixed to the bottom it costs a row of nobody's
 * viewport and lands where a thumb already is.
 */
@media (max-width: 720px) {
  .game-bar-name { display: none; }
  .game-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 25;
    justify-content: space-between; gap: 10px;
    padding: 8px var(--gutter);
    background: rgba(18, 16, 24, .96);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--line);
  }
  /* So the bar never sits on top of the last thing on the page. */
  .footer { padding-bottom: 78px; }
}

.steam-btn {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 999px;
  border: 1px solid var(--accent); color: var(--accent);
  text-decoration: none; font-size: .84rem; font-weight: 500; white-space: nowrap;
}
.steam-btn:hover { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; }


.head-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.head-actions .external { margin-top: 0; }
.fav-btn { background: transparent; color: var(--text); font: inherit; font-size: .88rem; cursor: pointer; }
.fav-btn.active { border-color: var(--amber); color: var(--amber); }

/* ── Watchlist ────────────────────────────────────────────────────────── */

.watchlist { margin-top: 20px; }
.watch-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 12px; margin-top: 14px;
}
.watch-card {
  display: block; text-decoration: none; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line);
  border-left-width: 3px; border-radius: 10px; overflow: hidden;
  transition: border-color .15s;
}
.watch-card:hover { border-color: var(--accent); }
.watch-card img { width: 100%; height: auto; display: block; }
.watch-body { padding: 10px 12px 12px; }
.watch-name { font-size: .88rem; line-height: 1.3; margin-bottom: .4rem; }
.watch-fav { color: var(--amber); }
.watch-price { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-bottom: .3rem; }
.watch-price s { color: var(--muted); font-size: .78rem; }
.watch-signal { font-size: .8rem; font-weight: 700; margin-bottom: .2rem; }
.watch-soon { color: var(--muted); font-size: .85rem; }
.watch-note { margin: 0; }

.watch-good { border-left-color: var(--mint); }
.watch-good .watch-signal, .watch-good .watch-price b { color: var(--mint); }
.watch-fair { border-left-color: var(--amber); }
.watch-fair .watch-signal { color: var(--amber); }
.watch-poor { border-left-color: var(--rose); }
.watch-poor .watch-signal { color: var(--rose); }
.watch-unknown { border-left-color: var(--muted); }
.watch-unknown .watch-signal { color: var(--muted); }

/* The search form moves between these two slots, so the slots carry the
   layout and the form only carries its own presentation. */
#search-slot-bar { flex: 1 1 260px; min-width: 0; }
#search-slot-bar:empty { flex: 0 0 0; }
#search-slot-home { margin-top: 22px; max-width: 520px; }

.search { position: relative; width: 100%; min-width: 0; }
.search input {
  width: 100%; padding: 10px 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  font: inherit; font-size: .95rem;
}
.search input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* On the home page searching is the point of the page, so it is sized like it. */
.search.hero input {
  padding: 14px 18px; font-size: 1.05rem; border-radius: 12px;
  background: var(--panel-2); border-color: var(--line);
}
.search.hero input::placeholder { color: var(--muted); }
.search.hero input:hover { border-color: #4b3f5c; }

.search-popover {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 30;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 8px; box-shadow: 0 18px 40px rgba(0, 0, 0, .5);
}
.search-status { font-size: .78rem; color: var(--muted); margin: 4px 6px 6px; }
.search-results { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.search-results button {
  display: block; width: 100%; text-align: left; padding: 8px 10px;
  background: none; border: 0; color: var(--text); font: inherit; border-radius: 8px; cursor: pointer;
}
/*
 * The background alone is not an indicator: panel-2 against panel is nowhere
 * near the 3:1 that a focus cue owes. It used to cancel the outline outright,
 * which is exactly the habit the global rule above exists to undo.
 */
.search-results button:hover, .search-results button:focus-visible {
  background: var(--panel-2);
}
.search-results button:focus-visible { outline-offset: -2px; }

/* ── Layout ───────────────────────────────────────────────────────────── */

main { max-width: 1120px; margin: 0 auto; padding: 28px var(--gutter) 60px; }

.intro { max-width: 620px; padding: 32px 0 20px; }
.lede { color: var(--muted); font-size: 1.05rem; }
.suggestions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
/* Same control, same target: a 38px chip beside a 44px pill reads as a mistake. */
.chip {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 16px;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text); font: inherit; font-size: .88rem; cursor: pointer;
}
.chip:hover { border-color: var(--accent); }

.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px;
}

.loading, .error { padding: 16px 0; color: var(--muted); }
/* Rendered even with nothing to say, so it stays in the accessibility tree and
   the next message counts as a change. Empty, it takes no space. */
.loading:empty { padding: 0; }
/* Now that it opens the page instead of closing it, the error has to read as a
   message and not as a stray line of text above the hero. */
.error {
  color: var(--rose);
  border: 1px solid var(--rose);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 4px;
  background: rgba(239, 143, 164, .08);
}
.error:focus-visible { outline: 2px solid var(--rose); outline-offset: 2px; }

/* ── Game header ──────────────────────────────────────────────────────── */

.game-head {
  display: grid; grid-template-columns: minmax(0, 300px) 1fr; gap: 22px;
  align-items: center; margin-bottom: 20px;
}
.cover img { width: 100%; height: auto; border-radius: 12px; display: block; border: 1px solid var(--line); }
.identity h1 { margin-bottom: .3rem; }
.external {
  display: inline-flex; align-items: center; min-height: 44px;
  margin-top: 8px; padding: 0 16px; border-radius: 999px;
  border: 1px solid var(--line); text-decoration: none; font-size: .88rem;
}
.external:hover { border-color: var(--accent); }

/* ── Metrics ──────────────────────────────────────────────────────────── */

.metrics {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; margin-bottom: 20px;
}
.metrics article {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 15px 16px;
}
.metrics p { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: .3rem; }
.metrics strong { display: block; font-size: 1.55rem; letter-spacing: -.02em; }
/* Scoped to the caption span only. A bare `.metrics span` also caught the
   badges and, being more specific than their own rules, painted mint text onto
   a mint background. */
.metrics article > span { display: block; font-size: .82rem; color: var(--muted); margin-top: 2px; }

/* ── Verdict ──────────────────────────────────────────────────────────── */

/*
 * The answer, ahead of the evidence. It reads before the three figures rather
 * than fourth among them, and its type is the largest on the page after the
 * game's own name — which is the hierarchy the app's question implies.
 */
.verdict {
  background: var(--panel); border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: var(--radius); padding: 18px 20px; margin-bottom: 12px;
}
.verdict-label { font-size: 1.9rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; margin: 0 0 .2rem; }
.verdict-note { color: var(--muted); max-width: 70ch; margin-bottom: 0; }
.verdict .badges { margin-top: 12px; }

.verdict-good { border-left-color: var(--mint); }
.verdict-good .verdict-label { color: var(--mint); }
.verdict-fair { border-left-color: var(--amber); }
.verdict-fair .verdict-label { color: var(--amber); }
.verdict-poor { border-left-color: var(--rose); }
.verdict-poor .verdict-label { color: var(--rose); }
.verdict-unknown { border-left-color: var(--muted); }
.verdict-unknown .verdict-label { color: var(--muted); }

.badges { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.badge {
  display: inline-block; white-space: nowrap;
  font-size: .62rem; letter-spacing: .09em; padding: 3px 8px;
  border-radius: 999px; border: 1px solid currentColor; font-weight: 700;
}
.badge-best { color: var(--mint); }
.badge-good { color: var(--accent); }
.badge-warn { color: var(--amber); }

/*
 * Sitting at the floor *while discounted* is the one moment the tool exists to
 * catch, so it gets a filled pill instead of an outline — the pattern Open,
 * Posh and Suno all use for the one badge that matters, with the secondary ones
 * left as low-contrast outlines. Mint on #10231c measures 9.9:1, past AAA.
 */
.badge-hero {
  background: var(--mint);
  border-color: var(--mint);
  color: #10231c;
  font-size: .68rem;
  padding: 4px 11px;
  box-shadow: 0 0 0 4px rgba(125, 219, 179, .16);
}

@media (prefers-reduced-motion: no-preference) {
  .badge-hero { animation: badge-in .45s ease-out both; }
  @keyframes badge-in {
    from { transform: scale(.88); opacity: 0; }
    to   { transform: scale(1);   opacity: 1; }
  }
}

/* ── Workspace ────────────────────────────────────────────────────────── */

.workspace { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 320px); gap: 16px; margin-bottom: 16px; }

.section-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }

.pills { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
/*
 * 44px is the touch target, not the type size: the text stays at .84rem and the
 * box grows around it. These are the main control of the tool — period, target
 * discount, DLC filter, player range — and they were 35px tall.
 */
.pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 16px;
  border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font: inherit; font-size: .84rem; cursor: pointer;
}
.pill:hover { color: var(--text); border-color: var(--accent); }
.pill.active { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; font-weight: 500; }
.pill.ghost { color: var(--muted); }

.custom { display: inline-flex; align-items: center; gap: 3px; color: var(--muted); font-size: .84rem; }
.custom input {
  width: 62px; min-height: 44px; padding: 0 10px; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--text); font: inherit; font-size: .84rem;
}

.legend { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; font-size: .78rem; color: var(--muted); margin: 14px 0 6px; }
.key { display: inline-block; width: 16px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.key.past { background: var(--mint); }
.key.future { background: var(--accent); }
.key.band { background: var(--accent); opacity: .3; height: 9px; }
/*
 * The target was the label, at 110x19 — under the 24x24 of WCAG 2.5.8, and the
 * only unstyled native control in the interface. It shows the prediction, which
 * is the one thing here that is ours.
 */
.toggle {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  min-height: 44px; padding: 0 10px 0 4px; border-radius: 999px;
}
.toggle:hover { color: var(--text); }
.toggle input {
  width: 18px; height: 18px; margin: 0;
  accent-color: var(--accent-solid); cursor: pointer;
}

.chart { width: 100%; }
.chart svg { width: 100%; height: auto; display: block; overflow: visible; }
.chart-empty { color: var(--muted); padding: 40px 0; text-align: center; }
.chart-note { font-size: .78rem; color: var(--muted); margin-top: 10px; }

/* Chart internals */
.grid { stroke: #4b3f5c; stroke-dasharray: 3 5; }
.axis-y { fill: var(--muted); font-size: 11px; text-anchor: end; }
.axis-x { fill: var(--muted); font-size: 11px; }
.area-past { fill: var(--mint); opacity: .11; }
.line-past { fill: none; stroke: var(--mint); stroke-width: 2.4; stroke-linejoin: round; }
.dot-now { fill: var(--mint); }
.label-now { fill: var(--mint); font-size: 12px; font-weight: 700; }
.future-bg { fill: var(--accent); opacity: .04; }
.band-future { fill: var(--accent); opacity: .18; }
.line-future { fill: none; stroke: var(--accent); stroke-width: 2.2; stroke-dasharray: 6 5; stroke-linejoin: round; }
.divider-now { stroke: var(--accent); stroke-dasharray: 3 5; }
.label-future { fill: var(--accent); font-size: 10px; letter-spacing: .1em; }
.line-target { stroke: var(--amber); stroke-width: 1.6; stroke-dasharray: 5 4; }
.label-target { fill: var(--amber); font-size: 11px; font-weight: 700; }
.line-low { stroke: #6f6383; stroke-width: 1.2; stroke-dasharray: 2 4; }
.label-low { fill: var(--muted); font-size: 11px; }
.event-tick { stroke-width: 2; }
.event-accent { stroke: var(--accent); }
.event-mint { stroke: var(--mint); }
.event-muted { stroke: #6f6383; }
.key.events { background: var(--accent); height: 9px; width: 3px; }

/* ── Forecast ─────────────────────────────────────────────────────────── */

.forecast { background: linear-gradient(170deg, var(--panel-2), var(--panel)); }
.forecast-window { font-size: 1.5rem; font-weight: 700; letter-spacing: -.02em; margin-bottom: .2rem; }
.forecast-depth { color: var(--muted); }
.forecast-depth strong { color: var(--accent); }
.confidence {
  display: inline-block; font-size: .7rem; letter-spacing: .09em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px; border: 1px solid currentColor; font-weight: 700; margin-bottom: .6rem;
}
.confidence-alta { color: var(--mint); }
.confidence-media { color: var(--amber); }
.confidence-baja { color: var(--rose); }

.reasoning { margin: 10px 0; }
.reasoning summary { cursor: pointer; color: var(--accent); font-size: .88rem; }
.reasoning ul { margin: 8px 0; padding-left: 18px; font-size: .84rem; color: var(--muted); }
.reasoning .evidence { border-top: 1px solid var(--line); padding-top: 8px; }
.reasoning .evidence b { color: var(--accent); font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; }

/* ── Targets ──────────────────────────────────────────────────────────── */

.targets .pills { margin: 12px 0 16px; }
.target-outcome { border-top: 1px solid var(--line); padding-top: 14px; }
.target-yes { font-size: 1.3rem; font-weight: 700; color: var(--mint); margin-bottom: .3rem; }
.target-no { font-size: 1.3rem; font-weight: 700; color: var(--rose); margin-bottom: .3rem; }

/* ── Players ──────────────────────────────────────────────────────────── */

.players, .reviews, .dlc { margin-top: 16px; }

/* Metric tiles nested inside a panel sit flatter than the top-level row. */
.metrics.inline { margin: 14px 0; gap: 10px; }
.metrics.inline article { background: var(--panel-2); padding: 12px 13px; }
.metrics.inline strong { font-size: 1.25rem; }

.trend-up strong { color: var(--mint); }
.trend-down strong { color: var(--rose); }

.band-players { fill: var(--accent); opacity: .16; }
.area-players { fill: var(--accent); opacity: .08; }
.line-players { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.dot-peak { fill: var(--amber); }

/* ── Reviews ──────────────────────────────────────────────────────────── */

/* The distance between Steam's lifetime score and what recent buyers say is
   the one thing this panel offers that the Steam page does not, so it gets
   its own block rather than a line of body copy. */
.gap {
  border-left: 3px solid var(--line);
  background: var(--panel-2);
  border-radius: 0 10px 10px 0;
  padding: 13px 16px;
  margin: 14px 0;
}
.gap-better { border-left-color: var(--mint); }
.gap-better .gap-line strong { color: var(--mint); }
.gap-worse { border-left-color: var(--rose); }
.gap-worse .gap-line strong { color: var(--rose); }
.gap-line { font-size: 1rem; margin-bottom: .35rem; }
.gap-line strong { font-size: 1.2rem; }

.review-trend { margin: 16px 0; }
.spark { width: 100%; max-width: 420px; height: auto; display: block; margin: 8px 0; }
.spark-mid { stroke: #4b3f5c; stroke-dasharray: 2 3; stroke-width: 1; }
.spark .bar-good { fill: var(--mint); }
.spark .bar-mid { fill: var(--amber); }
.spark .bar-bad { fill: var(--rose); }

.review-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin: 14px 0; }
.review {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 13px 14px; font-size: .88rem;
}
.review-head { font-size: .74rem; font-weight: 700; letter-spacing: .04em; margin-bottom: .4rem; }
.review.up .review-head { color: var(--mint); }
.review.down .review-head { color: var(--rose); }
.review-head .muted { font-weight: 400; letter-spacing: 0; }

/* ── DLC ──────────────────────────────────────────────────────────────── */

.dlc-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px; margin: 14px 0;
}
.dlc-card {
  display: block; text-decoration: none; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px; transition: border-color .15s;
}
.dlc-card:hover { border-color: var(--accent); }
.dlc-card.on-sale { border-color: rgba(125, 219, 179, .45); }
.dlc-card img { width: 100%; height: auto; border-radius: 6px; display: block; margin-bottom: 8px; }
.dlc-name { font-size: .85rem; line-height: 1.3; margin-bottom: .35rem; }
.dlc-price { font-size: .85rem; margin: 0; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.dlc-price s { color: var(--muted); font-size: .78rem; }
.dlc-price b { color: var(--text); }
.dlc-off {
  background: var(--mint); color: #10231c; font-weight: 700;
  font-size: .68rem; padding: 1px 6px; border-radius: 4px;
}
.dlc-card.on-sale .dlc-price b { color: var(--mint); }
.dlc-included { color: var(--muted); font-size: .78rem; font-style: italic; }

/* ── Sources ──────────────────────────────────────────────────────────── */

.sources, .donate { margin-top: 16px; }

.source-form { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 6px; }
.source-form input {
  flex: 1 1 220px; min-width: 0; padding: 9px 13px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font: inherit; font-size: .9rem;
}
.source-form input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.source-form button { padding: 9px 18px; }
.source-form button:disabled { opacity: .55; cursor: progress; }

.source-feedback { font-size: .84rem; min-height: 1.3em; margin: 0 0 8px; color: var(--muted); }
.source-feedback.ok { color: var(--mint); }
.source-feedback.warn { color: var(--amber); }
.source-feedback.bad { color: var(--rose); }

.source-list { list-style: none; margin: 12px 0; padding: 0; }
.source-row {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 14px;
  padding: 11px 0; border-top: 1px solid var(--line); flex-wrap: wrap;
}
.source-title { margin-bottom: .2rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.source-title a { color: var(--text); text-decoration: none; font-size: .92rem; }
.source-title a:hover { color: var(--accent); }
.source-error { color: var(--rose); margin: .2rem 0 0; }
.source-actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* ── Donations ────────────────────────────────────────────────────────── */

/*
 * One card per way to give, the same shape for each. Cards size to their own
 * content (align-items: start), so opening the crypto address does not
 * stretch the PayPal card beside it into an empty tower.
 */
/* Why the money is asked for, said before the ask rather than in the fine print. */
.donate-purpose { color: var(--muted); margin: 0 0 .2rem; }

.donate-methods {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px; margin: 14px 0; align-items: start;
}
.donate-card {
  display: grid; gap: 4px; padding: 16px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
}
.donate-icon {
  display: inline-grid; place-items: center; width: 34px; height: 34px; margin-bottom: 6px;
  border-radius: 9px; font-size: .78rem; font-weight: 700;
}
.donate-icon-paypal { background: #1b2a4a; color: #8ab4ff; }
.donate-icon-crypto { background: #123a2e; color: var(--mint); font-size: 1rem; }
.donate-icon-binance { background: #3a2f12; color: var(--amber); }
.donate-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 1rem; margin: 0; }
.donate-desc { color: var(--muted); font-size: .86rem; margin: 0 0 10px; }

/* The network is as prominent as the asset: the same address on the wrong
   chain loses the funds, so it is never a footnote and never folded away. */
.donate-chain {
  background: var(--amber); color: #2a1f08; font-weight: 700;
  font-size: .7rem; letter-spacing: .04em; padding: 3px 9px; border-radius: 999px;
}

.donate-action {
  justify-self: start; display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 16px; border-radius: 999px;
  border: 1px solid var(--accent); background: transparent; color: var(--accent);
  font: inherit; font-size: .86rem; font-weight: 500; text-decoration: none; cursor: pointer;
  transition: background-color .15s, border-color .15s, color .15s;
}
.donate-action:hover { background: var(--accent-solid); border-color: var(--accent-solid); color: #fff; }
.donate-chevron {
  width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round; transition: transform .15s;
}
.donate-action[aria-expanded="true"] .donate-chevron { transform: rotate(180deg); }

.donate-reveal { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.donate-reveal[hidden] { display: none; }
.donate-inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 .6rem; }
.donate-inline code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .8rem; word-break: break-all; color: var(--text);
  background: var(--panel); border: 1px solid var(--line);
  padding: 7px 10px; border-radius: 7px; flex: 1 1 200px;
}
.donate-warning { font-size: .8rem; color: var(--muted); margin: 0; }
.donate-warning strong { color: var(--amber); }

/* ── Events ───────────────────────────────────────────────────────────── */

.events { margin-top: 16px; }
.event-list { list-style: none; margin: 8px 0 16px; padding: 0; }
.event-list li {
  display: grid; grid-template-columns: 130px 1fr; gap: 12px;
  padding: 7px 0; border-top: 1px solid var(--line); font-size: .88rem; align-items: baseline;
}
.event-when { color: var(--muted); font-size: .78rem; }
.event-list a { color: var(--text); text-decoration: none; display: block; }
.event-list a:hover { color: var(--accent); }
.event-list b {
  color: var(--accent); font-size: .66rem; letter-spacing: .07em;
  text-transform: uppercase; margin-right: 7px;
}

@media (max-width: 620px) {
  .event-list li { grid-template-columns: 1fr; gap: 2px; }
}

/* ── Footer ───────────────────────────────────────────────────────────── */

.footer {
  border-top: 1px solid var(--line); padding: 22px var(--gutter);
  max-width: 1120px; margin: 0 auto; font-size: .8rem; color: var(--muted);
}
.footer strong { color: var(--text); }
.footer-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.footer-row p { margin: 0; }
.report-btn {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; color: var(--muted);
  font: inherit; font-size: .84rem; cursor: pointer;
  transition: border-color .15s, color .15s;
}
.report-btn:hover { border-color: var(--rose); color: var(--text); }
.footer-actions { display: flex; gap: 8px; flex-wrap: wrap; }
a.report-btn { text-decoration: none; }
a.report-btn:hover { border-color: var(--accent); }
.report-btn[hidden] { display: none; }
.admin-head { padding-bottom: 4px; }

/* ── Bug report dialog ────────────────────────────────────────────────── */

.report {
  width: min(520px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100dvh - 2 * var(--gutter));
  padding: 22px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
}
.report::backdrop { background: rgba(10, 8, 14, .72); backdrop-filter: blur(3px); }
.field-label { display: block; font-size: .84rem; font-weight: 500; margin: 14px 0 6px; }
.report textarea, .report input {
  width: 100%; padding: 10px 13px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font: inherit; font-size: .9rem;
}
.report textarea { resize: vertical; min-height: 110px; }
.report textarea::placeholder, .report input::placeholder { color: var(--muted); }
.report-context { margin: 14px 0 4px; font-size: .84rem; }
.report-context summary { cursor: pointer; color: var(--accent); }
.report-context ul { margin: 8px 0; padding-left: 18px; color: var(--muted); }
.report-context li { overflow-wrap: anywhere; }
.report-actions { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.report-actions button:disabled { opacity: .55; cursor: progress; }

/* ── API usage (moderator only) ───────────────────────────────────────── */

.usage { margin-top: 16px; }
.usage-row { margin: 16px 0 0; }
.usage-top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 6px; font-size: .9rem; }
.usage-count { font-variant-numeric: tabular-nums; font-weight: 500; white-space: nowrap; }
.usage-bar { height: 8px; border-radius: 999px; background: var(--panel-2); overflow: hidden; }
.usage-fill { display: block; height: 100%; min-width: 2px; border-radius: 999px; transition: width .3s ease-out; }
.usage-good { background: var(--mint); }
.usage-warn { background: var(--amber); }
.usage-bad { background: var(--rose); }
.usage-note { margin: 6px 0 0; }
.usage-tiles { margin-top: 18px; }
@media (prefers-reduced-motion: reduce) { .usage-fill { transition: none; } }

/* ── Bug report queue (moderator only) ────────────────────────────────── */

.bugs { margin-top: 16px; }
.bug-message { white-space: pre-wrap; overflow-wrap: anywhere; margin-bottom: .3rem; }
.bug-row.closed .bug-message { color: var(--muted); }

@media (max-width: 860px) {
  .workspace { grid-template-columns: 1fr; }
  .game-head { grid-template-columns: 1fr; }
  .cover img { max-width: 380px; }
}
.local-price { color: var(--accent) !important; font-size: .8rem !important; margin-top: 4px !important; }

/* The header is sticky, so a panel scrolled to by link keeps clear of it. */
#apoyar { scroll-margin-top: 96px; }
