/* ============================================================
   STYLE.CSS — visual theme.
   Colors are controlled from js/config.js (theme presets or
   custom hex values). The variables below are fallbacks.

   Dynamic per-item colors (elements, tiers) arrive through the
   --dyn variable, set by JS after render — never as inline
   style attributes, which keeps the Content-Security-Policy
   strict.
   ============================================================ */

:root {
  --bg: #0E1016;
  --panel: #161821;
  --panel-2: #12141C;
  --line: #262A38;
  --text: #EDEEF4;
  --muted: #8B93B8;
  --accent: #2E9BF0;
  --accent-soft: rgba(46, 155, 240, 0.13);
  --accent-line: rgba(46, 155, 240, 0.33);
  /* Rarity colours, matched to the pull-card frames: SSR gold, SR violet,
     R blue. The -glow pairs are the same hues as rgb triples so the pulse
     keyframes below can fade them in and out inside a box-shadow. */
  --r5: #F7C64B;   /* SSR */
  --r4: #B07CFF;   /* SR  */
  --r3: #47A6F2;   /* R   */
  --r5-glow: 247, 198, 75;
  --r4-glow: 176, 124, 255;
  --r3-glow: 71, 166, 242;
  --radius: 10px;
  --sidebar-w: 250px;
  --topbar-h: 72px;
  --font-display: "Rajdhani", "Segoe UI", sans-serif;
  --font-body: "Inter", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; margin: 0; }
/* overflow-x: clip, not hidden. `hidden` would turn <html> into a scroll
   container and silently kill every position: sticky descendant (the stat-table
   headers and the login card both rely on one); `clip` stops sideways scrolling
   without creating that container. This is a backstop, not the fix - anything
   that actually overhangs the viewport is a bug to find and repair at the
   source (see /tmp-style overflow probe notes in the handoff). It is here so
   one stray wide element can never again drag the whole page sideways. */
html { scroll-behavior: smooth; scrollbar-width: thin; scrollbar-color: var(--accent) var(--bg); overflow-x: clip; }
html::-webkit-scrollbar { width: 10px; }
html::-webkit-scrollbar-track { background: var(--bg); }
html::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 5px; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  padding-top: var(--topbar-h);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* Scrolling parallax keyart layer (from config.scrollingBackground) */
.bg-scroll {
  position: fixed;
  top: 0; left: 0;
  width: 200%; height: 100%;
  background-repeat: repeat-x;
  background-size: auto 100%;
  animation: scrollBackground 60s linear infinite;
  z-index: -1;
  opacity: 0.16;
  pointer-events: none;
}
@keyframes scrollBackground {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

h1, h2, h3, .brand, .side-item, .cat-banner, .pill, .tl-tier-label, .tl-col-head {
  font-family: var(--font-display);
}
h1 { font-size: clamp(1.7rem, 4vw, 2.5rem); line-height: 1.15; font-weight: 700; margin: 0.25em 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: var(--muted); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Skip link. Every page here builds a topbar with a dozen focusable things in
   it plus, on game pages, a whole sidebar, so a keyboard or switch user had to
   tab through the entire navigation on every single page before reaching the
   article. This is the standard escape hatch: invisible until focused, first in
   the tab order, drops you straight into <main>. */
.skip-link {
  position: absolute; left: 0.75rem; top: -100px; z-index: 200;
  padding: 0.7rem 1.1rem; border-radius: 0 0 10px 10px;
  background: var(--accent); color: #10121A;
  font-weight: 700; font-size: 0.9rem; text-decoration: none;
  transition: top 0.16s ease;
}
.skip-link:focus { top: 0; text-decoration: none; }
/* <main> is only focusable so the skip link has somewhere to land; it should
   never draw a ring of its own when it receives that programmatic focus. */
#main:focus { outline: none; }

/* Anchored headings have to clear the fixed topbar, or a jump link parks the
   target underneath it and reads as "nothing happened". The category strip adds
   its own height on top of this, which its click handler measures at the time
   rather than guessing here, since the strip changes height as it pins. */
[id] { scroll-margin-top: calc(var(--topbar-h) + 16px); }

.fade-in { animation: fadeIn 0.45s ease; }
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ================= topbar ================= */

#site-nav {
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--topbar-h); z-index: 60;
  background: rgba(14, 16, 22, 0.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.nav-inner {
  height: 100%; max-width: 1560px; margin: 0 auto;
  padding: 0 1.6rem;
  display: flex; align-items: center; gap: 0.9rem;
}
.brand {
  display: flex; align-items: center; gap: 0.6rem; flex: none;
  color: var(--text); font-weight: 700; font-size: 1.2rem;
  letter-spacing: 0.05em; text-transform: uppercase; white-space: nowrap;
}
.brand:hover { text-decoration: none; color: var(--accent); }
.brand-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; font-size: 1.1rem; color: var(--bg);
  background: linear-gradient(135deg, var(--accent), var(--r4));
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
/* One non-wrapping line; children never shrink and the row clips. */
.nav-links {
  flex: 1 1 auto; min-width: 0; margin-left: 1.4rem;
  display: flex; align-items: center; gap: 0.5rem;
  overflow: hidden; white-space: nowrap;
}
.nav-links > * { flex: none; }
.nav-main { display: flex; align-items: center; gap: 0.2rem; }
.nav-link {
  color: var(--muted); padding: 0.5rem 0.75rem; border-radius: 8px;
  font-size: 0.95rem; font-weight: 600; white-space: nowrap;
  transition: color 0.16s ease, background 0.16s ease;
}
.nav-link:hover { color: var(--text); background: var(--panel); text-decoration: none; }
.nav-link.active { color: var(--accent); background: var(--accent-soft); }

/* ================= topbar search =================
   Lives outside .nav-links on purpose: that row is overflow:hidden, so a
   dropdown parented inside it would be clipped at the first result.
   #site-nav sets no overflow, which is what lets the panel hang below.

   Visible by default rather than behind a magnifier: the point of the feature
   is that someone who lands on a game page can type a unit name instead of
   guessing which of eleven sub-pages it lives on, and a search you have to find
   first does not get used. The / and Ctrl-K hints are for the people who will
   never touch it with a mouse. */
/* 216px, not 280. The bar has to hold a brand, three section links, three game
   chips, a Discord link and an account chip, and at 1440 the wider field was
   costing exactly the two game chips the user asked to have back. The field is
   still unmistakably a search field at this width; it does not grow on focus,
   because growing it would silently clip the chip row beside it. */
.nav-search {
  position: relative; flex: 0 1 216px; min-width: 0;
  display: flex; align-items: center; gap: 0.45rem;
  height: 38px; padding: 0 0.55rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.nav-search:focus-within {
  border-color: var(--accent); background: var(--panel-2);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.nav-search-ic { flex: 0 0 auto; font-size: 0.9rem; opacity: 0.75; }
.nav-search-in {
  flex: 1 1 auto; min-width: 0;
  background: none; border: 0; outline: none; color: var(--text);
  font: inherit; font-size: 0.88rem; padding: 0;
}
.nav-search-in::placeholder { color: var(--muted); }
/* Chrome draws its own clear button on type=search and it collides with the kbd hint. */
.nav-search-in::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.nav-search-kbd {
  flex: 0 0 auto; font-family: var(--font-display); font-size: 0.68rem; font-weight: 700;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 5px; padding: 0.05rem 0.35rem; line-height: 1.5;
}
.nav-search:focus-within .nav-search-kbd { opacity: 0; }
/* The magnifier button is the phone affordance only; on desktop the field is
   always there and a button next to it would just be a second way in. */
.nav-search-btn { display: none; }

/* ---- results ---- */
.nav-search-res {
  position: absolute; top: calc(100% + 0.5rem); right: 0; z-index: 61;
  width: min(420px, calc(100vw - 2rem)); min-width: 100%;
  max-height: min(70vh, 520px); overflow-y: auto; overscroll-behavior: contain;
  background: #0E1016; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.55);
  padding: 0.35rem;
  animation: navDrop 0.16s ease;
}
.nav-search-res[hidden] { display: none; }
/* Results group under the GAME, not under the kind of thing they are. "Which
   game is this unit in, and which page of it" is the actual question being
   asked; a header that said "Characters" would answer the one nobody asked. */
.nsr-group {
  display: block; font-family: var(--font-display); font-weight: 800;
  font-size: 0.63rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--accent); padding: 0.55rem 0.6rem 0.3rem;
}
.nsr-item {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 0.4rem 0.55rem; border-radius: 8px;
  color: var(--text); text-decoration: none;
}
.nsr-item:hover, .nsr-item[aria-selected="true"] {
  background: var(--accent-soft); text-decoration: none;
}
.nsr-ic {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 7px;
  background: var(--panel-2) center 12% / cover no-repeat;
  border: 1px solid var(--line);
  display: grid; place-items: center; overflow: hidden;
}
.nsr-ic-glyph { font-size: 0.9rem; }
.nsr-ph { font-family: var(--font-display); font-weight: 800; font-size: 0.78rem; color: var(--muted); }
.nsr-ic.has-img .nsr-ph { display: none; }
.nsr-tx { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; }
.nsr-t {
  font-size: 0.88rem; font-weight: 600; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nsr-s {
  font-size: 0.72rem; color: var(--muted); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nsr-kind {
  flex: 0 0 auto; font-size: 0.66rem; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px; padding: 0.08rem 0.45rem;
  max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nsr-empty { padding: 0.9rem 0.7rem; font-size: 0.85rem; color: var(--muted); text-align: center; }

/* Both Discord buttons carry a label. Two unlabelled Discord marks side by
   side, one blue and one yellow, gave no clue which one joined the server and
   which one signed you in. */
.btn-discord {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  height: 40px; padding: 0 0.85rem; border-radius: 9px;
  background: var(--accent); color: #fff; flex: none;
  font-family: var(--font-display); font-weight: 700; font-size: 0.85rem;
  white-space: nowrap;
  transition: transform 0.15s ease, filter 0.15s ease;
}
.btn-discord:hover { transform: translateY(-2px); filter: brightness(1.15); text-decoration: none; }
.btn-discord svg { flex: none; }
.bd-short { display: none; }
.nav-toggle, .side-toggle {
  display: none; background: none; border: 1px solid var(--line);
  color: var(--text); font-size: 1.05rem; padding: 0.3rem 0.65rem;
  border-radius: 6px; cursor: pointer;
}

/* ================= sidebar layout ================= */

#sidebar {
  position: fixed; top: var(--topbar-h); bottom: 0; left: 0;
  width: var(--sidebar-w);
  background: var(--panel-2);
  border-right: 1px solid var(--line);
  padding: 0.8rem 0.7rem 2rem;
  overflow-y: auto;
  z-index: 50;
  transition: transform 0.3s ease-in-out;
}
body.with-sidebar #main, body.with-sidebar #site-footer { margin-left: var(--sidebar-w); }

.side-game {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.7rem 0.8rem; margin-bottom: 0.6rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
}
.side-game-name { font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; line-height: 1.25; }
.side-switch {
  flex: none; width: 28px; height: 28px; display: inline-flex;
  align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 6px; color: var(--muted);
  transition: all 0.2s ease;
}
.side-switch:hover { color: var(--accent); border-color: var(--accent); text-decoration: none; transform: rotate(180deg); }

.side-label {
  font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted); padding: 0.9rem 0.8rem 0.25rem;
}
.side-item {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.55rem 0.8rem; border-radius: 7px;
  color: var(--text); font-weight: 600; font-size: 0.98rem;
  border-left: 3px solid transparent;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.side-item:hover { background: var(--panel); text-decoration: none; transform: translateX(3px); }
.side-item.active { background: var(--accent-soft); border-left-color: var(--accent); color: var(--accent); }
.side-icon { width: 1.2em; text-align: center; opacity: 0.9; }

/* ================= shared layout ================= */

#main { min-height: calc(100vh - var(--topbar-h) - 90px); }
.page-pad { max-width: 1180px; margin: 0 auto; padding: 1.4rem 1.4rem 3.5rem; }
.section { margin-top: 2.4rem; }
.hero-sub { color: var(--muted); font-size: 1rem; margin-bottom: 1rem; }

/* Prydwen-style section header: accent square + rule */
.sec-head {
  display: flex; align-items: center; gap: 0.6rem;
  font-size: 1.25rem; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase;
  border-bottom: 2px solid var(--accent-line);
  padding-bottom: 0.45rem; margin-bottom: 1.1rem;
}
.sec-square { width: 12px; height: 12px; background: var(--accent); flex: none; }

.crumbs { font-size: 0.86rem; color: var(--muted); margin-bottom: 0.9rem; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--accent); }
.crumb-sep { margin: 0 0.45rem; opacity: 0.6; }
.crumb-here { color: var(--text); }

/* ================= home ================= */

/* The hero is a signpost, not a splash screen. It says what the site is, offers
   the one-tap jumps, and then gets out of the way of the games grid, which is
   what people actually came for. Everything here is sized to keep the top of
   the grid above the fold on a laptop. */
.home-hero {
  position: relative; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  background-color: var(--panel-2);
  background-size: cover; background-position: center top;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.home-hero::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(700px 260px at 75% 0%, var(--accent-soft), transparent 60%),
    linear-gradient(rgba(10, 11, 16, 0.72), rgba(10, 11, 16, 0.86));
}
/* Trimmed again, for the same reason as the band below it: "rather than giving
   me time to think, wait, should I read that title? augh, where is the
   guides..". The copy still has to exist for search engines and for anyone who
   has genuinely never heard of the site, but it should cost one glance, not a
   paragraph, and it must not push the band below the fold. */
.home-hero-inner {
  position: relative; text-align: center;
  max-width: 720px; padding: 1.15rem 1.4rem 1.05rem;
  animation: fadeIn 0.7s ease;
}
.home-hero h1 { font-size: clamp(1.3rem, 2.2vw, 1.7rem); line-height: 1.16; }
.home-hero-blurb {
  color: #CBD1E8; font-size: 0.84rem; line-height: 1.45;
  margin-top: 0.35rem; max-width: 58ch; margin-left: auto; margin-right: auto;
}

/* ============================================================
   THE BROWSE BAND (home)
   Round one it was ghost pills inside the hero and the tester never saw them.
   Round two it became its own band and he still said: "the 3 game names should
   be like the whole screen size... you force me not to look at anything else
   but that." So the resting state is art: edge-to-edge poster tiles that own
   the width of the page and are the loudest thing on it.

   ROUND FOUR REMOVED THE PIN. Do not put position:sticky back on .qnav.

   The band used to stick under the topbar and shrink 216px -> 54px as you
   scrolled past. Sticky elements are still in normal flow, so animating the
   height rewrote the document's flow height by ~160px in the middle of a scroll
   gesture and every section below slid under the reader while they were reading
   it. That is what "it glitches out and the elements get messed up" meant, and
   it is not an easing problem - the page really was moving. On phones the
   pinned row was also 496px of chips inside a 358px viewport, which is where
   the horizontal scrolling came from.

   The pin was also making navigation worse, not better. The topbar carries all
   three game chips now, so a pinned copy one line below it meant either two
   identical rows on screen at once or fading the topbar's row out - which left
   the reader with FEWER options the further down they went.

   So: constant height, scrolls away like any other section, and the topbar is
   the thing that persists with every link intact. The tester's own alternative
   was "or you can make it disappear and it appears in the top"; the top is
   simply where it already lives.
   ============================================================ */
.qnav {
  background: linear-gradient(180deg, var(--panel-2), var(--bg));
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 var(--accent-soft);
}
.qnav-inner {
  max-width: 1400px; margin: 0 auto;
  padding: 0.9rem 1.4rem 1rem;
}
.qnav-label {
  display: block; font-size: 0.62rem; font-weight: 800;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 0.6rem;
  overflow: hidden; white-space: nowrap;
}
/* Wrap, not nowrap. With a fixed count of three this behaves as one row on any
   desktop width, but if a fourth game is registered the row folds instead of
   overflowing the page, and the phone override below depends on it too. */
.qnav-row {
  display: flex; flex-wrap: wrap; align-items: stretch; gap: 0.6rem;
}
.qnav-tile {
  position: relative; overflow: hidden; isolation: isolate;
  flex: 1 1 220px; min-width: 0;
  display: flex; flex-direction: row; align-items: flex-end;
  justify-content: flex-start;
  min-height: 126px; padding: 0.85rem 0.95rem;
  border-radius: 14px; border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text); text-decoration: none;
  transition: border-color 0.16s ease, transform 0.16s ease, box-shadow 0.16s ease;
}
/* The poster. Same URLs the game hub headers already request, so the browser
   serves both from one fetch and the band costs no extra bytes. */
.qnav-art {
  position: absolute; inset: 0; z-index: -2;
  background: var(--panel-2) center/cover no-repeat;
  transition: transform 0.4s ease;
}
/* Scrim. Key art is bright and busy and the label has to stay readable on top
   of all three games without hand-tuning any of them. */
.qnav-tile::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    rgba(10, 11, 16, 0.20) 0%, rgba(10, 11, 16, 0.55) 45%,
    rgba(10, 11, 16, 0.88) 100%);
}
.qnav-tile:hover, .qnav-tile:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
  transform: translateY(-2px); text-decoration: none;
}
.qnav-tile:hover .qnav-art, .qnav-tile:focus-visible .qnav-art { transform: scale(1.06); }

/* New / Popular, moved up from the "Games we cover" cards this band replaced. */
.qnav-tile .gcard-badges {
  position: absolute; top: 0.6rem; right: 0.6rem; z-index: 1;
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.3rem;
}

/* The game icon, sitting next to the title rather than hidden behind it. With
   no collapse to animate there is no reason for the old negative-margin trick,
   and a real in-flow box is also what the lazy image loader needs: it is an
   IntersectionObserver, and an element with no box never fires. */
.qnav-ic {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 10px;
  margin-right: 0.6rem;
  background: var(--panel-2) center/cover no-repeat;
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
  display: grid; place-items: center; overflow: hidden;
}
.qnav-ph { font-family: var(--font-display); font-weight: 800; color: var(--muted); font-size: 1rem; }
.qnav-ic.has-img .qnav-ph { display: none; }
.qnav-tx {
  position: relative; min-width: 0; max-width: 100%;
  display: flex; flex-direction: column; gap: 0.15rem;
}
.qnav-t {
  font-family: var(--font-display); font-weight: 800; font-size: 1.06rem;
  line-height: 1.15; color: #fff; letter-spacing: 0.01em;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.7);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qnav-s {
  font-size: 0.74rem; color: #C7CDE4; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.7);
}
/* Second-tier destinations. Deliberately a thin line of text: the band only
   works if there are three things shouting, not seven. */
.qnav-more {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 1.1rem;
  margin-top: 0.75rem;
}
.qnav-more a {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.78rem; font-weight: 600; color: var(--muted); text-decoration: none;
}
.qnav-more a:hover, .qnav-more a:focus-visible { color: var(--accent); text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
  .qnav-tile, .qnav-art { transition: none; }
  .qnav-tile:hover, .qnav-tile:focus-visible { transform: none; }
  .qnav-tile:hover .qnav-art, .qnav-tile:focus-visible .qnav-art { transform: none; }
}

.home-body { max-width: 1400px; margin: 0 auto; padding: 1.6rem 1.4rem 3.5rem; }
.home-body > .section + .section { margin-top: 2.4rem; }
/* Every home heading is a .sec-head inside a .sec-head-row now (see homeHead()
   in renderers.js) so the page has one alignment instead of two. */
.home-ico { font-size: 1.05rem; }
.home-body .sec-head-row { margin-bottom: 1.1rem; }
.home-body .sec-head-row .sec-head { flex: 1 1 auto; }

.gcard-grid {
  display: grid; gap: 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.gcard-grid-small { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }

/* Popular / New are badges now rather than their own duplicate grids. */
.gcard-badges {
  position: absolute; top: 0.6rem; left: 0.6rem; z-index: 2;
  display: flex; flex-wrap: wrap; gap: 0.35rem;
}
.gcard-badge {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.2rem 0.5rem; border-radius: 999px;
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; white-space: nowrap;
  background: rgba(8, 9, 14, 0.72); color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(4px);
}
.gcard-badge.is-new { border-color: #7ADCA8; color: #C6F5DC; }
.gcard-badge.is-hot { border-color: #F0A24E; color: #FFDCB4; }
.gcard {
  position: relative; display: block; aspect-ratio: 16 / 7;
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line);
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.gcard:hover {
  transform: translateY(-4px) scale(1.02);
  border-color: var(--accent);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5), 0 0 0 1px var(--accent-line);
  text-decoration: none; z-index: 2;
}
.gcard-media {
  position: absolute; inset: 0;
  background: linear-gradient(130deg, var(--panel) 30%, var(--accent-soft) 100%);
  background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center;
  filter: saturate(1.02) brightness(0.9);
  transition: transform 0.4s ease, filter 0.3s ease;
}
.gcard:hover .gcard-media { transform: scale(1.06); filter: saturate(1.06) brightness(1.02); }
.gcard-ph {
  font-family: var(--font-display); font-size: 3rem; font-weight: 700;
  color: var(--line);
}
/* Prydwen-style transparency: a soft vignette over the banner so the key art
   reads as a background and the game name stays legible on top. */
.gcard-shade {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(6, 7, 11, 0.18) 0%,
    rgba(6, 7, 11, 0) 32%,
    rgba(6, 7, 11, 0.38) 58%,
    rgba(6, 7, 11, 0.9) 100%);
}
.gcard-name {
  position: absolute; left: 0.9rem; right: 0.9rem; bottom: 0.7rem;
  font-family: var(--font-display); font-weight: 700; font-size: 1.12rem;
  color: #fff; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.9);
}

/* Two equal rails below the games grid. The old 1.6fr/1fr split left a tall
   dead column beside the banner row. */
.home-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 2.2rem; align-items: start; }
.home-col { min-width: 0; }
.up-list { display: flex; flex-direction: column; gap: 0.55rem; }
.up-row {
  display: flex; justify-content: space-between; align-items: center; gap: 0.8rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 0.65rem 0.9rem;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.up-link:hover { border-color: var(--accent); transform: translateX(3px); text-decoration: none; }
.up-name { display: block; font-weight: 600; color: var(--text); font-size: 0.95rem; }
.up-note {
  display: block; font-size: 0.8rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.up-date { font-size: 0.8rem; color: var(--accent); white-space: nowrap; font-weight: 600; }
/* Cropped banner thumb. Falls back to a tinted initial when no art resolves,
   so a rail with half its art missing still lines up. */
.up-thumb {
  position: relative; flex: none; width: 76px; height: 46px; overflow: hidden;
  border-radius: 6px; border: 1px solid var(--line);
  background: linear-gradient(130deg, var(--panel-2) 30%, var(--accent-soft) 100%);
  background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center;
  transition: transform 0.2s ease;
}
.up-link:hover .up-thumb { transform: scale(1.04); }
.up-thumb-ph { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; color: var(--muted); }
.up-thumb.has-img .up-thumb-ph { display: none; }
/* min-width:0 is what lets the ellipsis on .up-note actually kick in. */
.up-txt { flex: 1 1 auto; min-width: 0; }

/* ================= game hub ================= */

.hub-hero {
  position: relative; min-height: 300px;
  display: flex; align-items: center; justify-content: center;
  background-color: var(--panel-2);
  background-size: cover; background-position: center top;
  border-bottom: 1px solid var(--line);
}
.hub-hero::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(rgba(10, 11, 16, 0.7), rgba(10, 11, 16, 0.88));
}
.hub-hero-inner {
  position: relative; text-align: center;
  max-width: 860px; padding: 3rem 1.4rem; animation: fadeIn 0.6s ease;
}
.hub-hero p { color: #CBD1E8; margin-top: 0.6rem; }
.hub-meta { font-size: 0.85rem; color: var(--accent) !important; text-transform: uppercase; letter-spacing: 0.1em; }

/* Guild notice: sits under the "Updated" stamp on a game page and points at
   the Discord button in the top bar. The icon breathes gently so the eye is
   drawn upward to the matching button rather than past the line. */
.guild-note {
  display: inline-flex; align-items: center; gap: 0.6rem;
  margin-top: 0.55rem; padding: 0.5rem 0.85rem;
  border: 1px solid rgba(88, 101, 242, 0.5); border-radius: 999px;
  background: rgba(88, 101, 242, 0.12);
  color: var(--text) !important; font-size: 0.86rem; line-height: 1.35;
  text-decoration: none; max-width: 46rem;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.guild-note:hover { text-decoration: none; transform: translateY(-1px); border-color: rgba(88, 101, 242, 0.95); background: rgba(88, 101, 242, 0.2); }
.guild-note-ic { display: inline-flex; flex: none; color: #7A87F5; animation: guildNudge 3.2s ease-in-out infinite; }
@keyframes guildNudge {
  0%, 72%, 100% { transform: translateY(0); }
  80% { transform: translateY(-3px); }
  88% { transform: translateY(0); }
}
@media (max-width: 560px) { .guild-note { font-size: 0.8rem; padding: 0.45rem 0.7rem; } }
@media (prefers-reduced-motion: reduce) { .guild-note-ic { animation: none; } }

.tool-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; }
.tool-card {
  display: flex; align-items: center; gap: 1rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.2rem; color: var(--text);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.tool-card:hover {
  border-color: var(--accent); transform: translateY(-3px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45); text-decoration: none;
}
.tool-ico { font-size: 1.5rem; }
.tool-card strong { display: block; font-family: var(--font-display); font-size: 1.08rem; }
.tool-card span:not(.tool-ico):not(.guide-arrow) { font-size: 0.85rem; color: var(--muted); }
.tool-card .guide-arrow { margin-left: auto; }

.cat-head {
  font-size: 1.12rem; font-weight: 700; margin: 1.5rem 0 0.8rem;
  color: var(--text);
}
.guide-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 0.9rem; }
.guide-card {
  display: flex; align-items: center; gap: 0.9rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 0.55rem 0.9rem 0.55rem 0.55rem; color: var(--text);
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.guide-card:hover { border-color: var(--accent); background: var(--panel-2); transform: translateY(-2px); text-decoration: none; }
.guide-thumb {
  width: 74px; height: 74px; flex: none; border-radius: 6px;
  background-color: var(--panel-2);
  background-size: cover; background-position: center;
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.6rem;
}
.guide-card-title { font-weight: 600; font-size: 1rem; line-height: 1.3; }
.guide-arrow {
  margin-left: auto; color: var(--muted); font-size: 1.1rem;
  transition: transform 0.2s ease, color 0.2s ease;
}
.guide-card:hover .guide-arrow, .tool-card:hover .guide-arrow { transform: translateX(5px); color: var(--accent); }

/* ================= guide cards + drop-down shelves (.gdx-*) =================
   Used by the guides index and the game-hub guides section. Cards carry cover
   art, a category chip, a summary and a byline; they live inside collapsible
   shelves so nothing dumps out all at once. Per-game tint arrives through
   data-clr -> --dyn (no inline styles, CSP-safe). */

.gdx-head { margin: 0 0 1.2rem; }
.gdx-head h1 { margin: 0 0 0.3rem; }
.gdx-toolbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem;
  margin: 0 0 1.2rem;
}
.gdx-search {
  flex: 1 1 240px; min-width: 180px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: inherit; font-size: 0.92rem;
  padding: 0.55rem 0.8rem;
}
.gdx-search:focus { outline: none; border-color: var(--accent); }
/* label wrapper: tiny caps caption above the select, same shape as .upg-sel */
.gdx-sel {
  display: flex; flex-direction: column; gap: 0.2rem;
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--muted); font-weight: 700;
}
.gdx-sel select {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font-family: inherit; font-size: 0.85rem; font-weight: 500;
  text-transform: none; letter-spacing: 0; cursor: pointer;
  padding: 0.45rem 0.6rem;
}
.gdx-sel select:focus { outline: none; border-color: var(--accent); }
.gdx-tool-btns { display: flex; gap: 0.45rem; margin-left: auto; }
.gdx-tbtn {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font: inherit; font-size: 0.85rem; cursor: pointer;
  padding: 0.5rem 0.8rem;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.gdx-tbtn:hover { color: var(--text); border-color: var(--accent); background: var(--panel-2); }

.gdx-list { display: flex; flex-direction: column; gap: 0.6rem; }

/* ---- shelf (click the title, it drops down) ---- */
.gdx-acc {
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel); overflow: hidden;
  transition: border-color 0.22s ease, background 0.22s ease;
}
.gdx-acc.open { background: var(--panel-2); border-color: color-mix(in srgb, var(--dyn, var(--accent)) 55%, var(--line)); }
.gdx-acc-head {
  display: flex; align-items: center; gap: 0.65rem; width: 100%;
  background: transparent; border: none; cursor: pointer; text-align: left;
  color: var(--text); font-family: var(--font-display); font-weight: 700;
  font-size: 1.05rem; padding: 0.9rem 1.1rem;
}
.gdx-acc-head:hover { color: var(--dyn, var(--accent)); }
.gdx-acc-chev {
  flex: none; color: var(--dyn, var(--accent)); font-size: 0.95rem; line-height: 1;
  transition: transform 0.22s ease;
}
.gdx-acc.open .gdx-acc-chev { transform: rotate(90deg); }
.gdx-acc-title { flex: 1 1 auto; }
.gdx-acc-sub { flex: none; color: var(--muted); font-family: var(--font-body, inherit); font-size: 0.8rem; font-weight: 500; }
.gdx-acc-body {
  display: none;
  padding: 0 1.1rem 1.1rem;
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}
.gdx-acc.open .gdx-acc-body { display: block; animation: gdxDrop 0.24s ease; }
@keyframes gdxDrop { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

.gdx-cat + .gdx-cat { margin-top: 1.2rem; }
.gdx-cat-head {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.82rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 0.7rem;
}

.gdx-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.85rem; }

/* ---- card ---- */
.gdx-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); text-decoration: none;
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.gdx-acc.open .gdx-card { background: var(--panel); }
.gdx-card:hover {
  text-decoration: none; transform: translateY(-3px);
  border-color: var(--dyn, var(--accent));
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.3);
}
.gdx-cover {
  position: relative; display: flex; align-items: center; justify-content: center;
  height: 96px; flex: none;
  background-color: var(--panel-2);
  background-size: cover; background-position: center;
  border-bottom: 1px solid var(--line);
}
/* No cover art yet: a soft tint wash behind the category glyph beats dead space. */
.gdx-cover:not(.has-img) {
  background-image: linear-gradient(135deg, color-mix(in srgb, var(--dyn, var(--accent)) 26%, transparent), transparent 72%);
}
.gdx-cover::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 35%, rgba(0, 0, 0, 0.45) 100%);
  opacity: 0; transition: opacity 0.2s ease;
}
.gdx-cover.has-img::after { opacity: 1; }
.gdx-cover-ic { font-size: 2rem; opacity: 0.85; }
.gdx-cover.has-img .gdx-cover-ic { display: none; }
.gdx-lock {
  position: absolute; top: 0.5rem; right: 0.5rem; z-index: 1;
  background: rgba(0, 0, 0, 0.6); border-radius: 999px;
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  font-size: 0.8rem;
}
.gdx-card.is-locked .gdx-cover { filter: saturate(0.5); }

.gdx-body { display: flex; flex-direction: column; gap: 0.4rem; padding: 0.75rem 0.85rem 0.7rem; flex: 1 1 auto; }
.gdx-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.gdx-chip {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  border-radius: 999px; padding: 0.18rem 0.5rem;
  border: 1px solid var(--line); color: var(--muted);
}
.gdx-chip-cat { color: var(--dyn, var(--accent)); border-color: color-mix(in srgb, var(--dyn, var(--accent)) 45%, transparent); }
.gdx-title { font-family: var(--font-display); font-weight: 700; font-size: 1rem; line-height: 1.3; }
.gdx-card:hover .gdx-title { color: var(--dyn, var(--accent)); }
.gdx-sum {
  color: var(--muted); font-size: 0.85rem; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.gdx-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  margin-top: auto; padding-top: 0.5rem;
}
.gdx-meta { color: var(--muted); font-size: 0.76rem; }
.gdx-go { color: var(--dyn, var(--accent)); font-size: 0.8rem; font-weight: 700; white-space: nowrap; }
.gdx-card:hover .gdx-go span { display: inline-block; transform: translateX(4px); transition: transform 0.2s ease; }

@media (max-width: 620px) {
  .gdx-tool-btns { margin-left: 0; }
  .gdx-grid { grid-template-columns: 1fr; }
  .gdx-acc-head { font-size: 0.98rem; padding: 0.8rem 0.85rem; }
  .gdx-acc-body { padding-left: 0.85rem; padding-right: 0.85rem; }
  .gdx-acc-sub { display: none; }
}

/* ================= accordions (tier list) ================= */

.acc-stack { display: flex; flex-direction: column; gap: 0.55rem; margin: 1.2rem 0 1.6rem; }
.acc { border: 1px solid var(--line); border-radius: 8px; background: var(--panel); overflow: hidden; transition: background 0.25s ease; }
.acc.open { background: var(--panel-2); }
.acc-head {
  display: flex; justify-content: space-between; align-items: center; width: 100%;
  background: transparent; border: none; cursor: pointer;
  color: var(--text); font-family: var(--font-display); font-weight: 600; font-size: 1.02rem;
  padding: 0.8rem 1.1rem; text-align: left;
  transition: color 0.2s ease;
}
.acc-head:hover, .acc.open .acc-head { color: var(--accent); }
.acc-chev { transition: transform 0.25s ease; font-size: 1.1rem; }
.acc.open .acc-chev { transform: rotate(180deg); }
/* Smooth height animation via the grid 0fr -> 1fr technique */
.acc-body-outer {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.32s ease;
}
.acc.open .acc-body-outer { grid-template-rows: 1fr; }
.acc-body {
  min-height: 0; overflow: hidden;
  padding: 0 1.1rem;
  color: #C9CEE2; font-size: 0.93rem;
  border-top: 1px solid transparent;
  opacity: 0;
  transition: padding 0.32s ease, opacity 0.3s ease, border-color 0.3s ease;
}
.acc.open .acc-body { padding: 0.2rem 1.1rem 1rem; opacity: 1; border-top-color: var(--line); }
.acc-body ul { padding-left: 1.2rem; }
.acc-body li { margin: 0.35rem 0; }
.chg { margin: 0.45rem 0; }
.chg-date { color: var(--accent); font-weight: 600; margin-right: 0.4rem; }

/* ================= tier list ================= */

.cat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0.7rem; margin-bottom: 0.7rem; }
.cat-banner {
  position: relative; overflow: hidden; cursor: pointer;
  padding: 1.15rem 1rem; border-radius: 8px;
  border: 2px solid var(--line);
  background: linear-gradient(120deg, var(--panel), var(--panel-2));
  color: var(--muted);
  font-size: 1.15rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  transition: all 0.25s ease;
}
.cat-banner:hover { color: var(--text); border-color: var(--accent-line); }
.cat-banner.active {
  color: var(--text); border-color: var(--accent);
  background: linear-gradient(120deg, var(--accent-soft), var(--panel-2));
  box-shadow: 0 0 18px var(--accent-soft);
}
.cat-banner.active::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 45%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.06), transparent);
  animation: shimmer 3.8s ease-in-out infinite;
}
@keyframes shimmer { 0% { left: -50%; } 60%, 100% { left: 120%; } }
.cat-blurb { color: var(--muted); font-size: 0.9rem; margin-bottom: 1.1rem; min-height: 1.4em; }

.tl-toolbar { display: flex; flex-direction: column; gap: 0.7rem; margin-bottom: 1.2rem; }
.search-input {
  width: 100%; max-width: 420px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); padding: 0.6rem 0.9rem; font-size: 0.95rem; font-family: var(--font-body);
}
.search-input:focus { outline: 2px solid var(--accent); border-color: var(--accent); }
.pill-row { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.pill-gap { width: 0.7rem; }
.pill {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); font-weight: 600; font-size: 0.85rem;
  padding: 0.32rem 0.8rem; cursor: pointer;
  transition: all 0.18s ease;
}
.pill:hover { color: var(--text); border-color: var(--accent-line); }
.pill.active { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
.pill-el.active { border-color: var(--dyn, var(--accent)); background: transparent; box-shadow: 0 0 10px var(--dyn, transparent) inset; }
.el-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--dyn, var(--muted)); flex: none; }
.pill-reset { margin-left: auto; border-style: dashed; }
.pill-reset:hover { color: #F3555A; border-color: #F3555A; }

.tl-grid-wrap { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--panel-2); }
.tl-row {
  display: grid;
  grid-template-columns: 72px repeat(var(--cols, 3), 1fr);
  border-bottom: 1px solid var(--line);
}
.tl-row:last-child { border-bottom: none; }
.tl-head-row { background: var(--panel); }
.tl-col-head {
  padding: 0.55rem 0.8rem; text-align: center;
  font-weight: 700; font-size: 0.95rem; letter-spacing: 0.1em; text-transform: uppercase;
  border-left: 1px solid var(--line);
}
.tl-col-0 { color: #F3555A; } .tl-col-1 { color: #A278FF; } .tl-col-2 { color: #5AD98A; }
.tl-col-3 { color: #F0A24E; } .tl-col-4 { color: #55C8F0; } .tl-col-5 { color: #EFC94C; }
.tl-tier-label {
  display: flex; align-items: center; justify-content: center;
  font-size: 1.35rem; font-weight: 700; color: #0B0C10;
  background: var(--dyn, var(--panel));
}
.tl-tier-blank { background: var(--panel); }
.tl-cell {
  display: flex; flex-wrap: wrap; gap: 0.55rem; align-content: flex-start;
  padding: 0.65rem; border-left: 1px solid var(--line); min-height: 84px;
}
.tl-empty { padding: 1.2rem; }

.tl-avatar {
  position: relative; width: 64px; text-align: center; color: var(--text);
  transition: transform 0.18s ease;
}
.tl-avatar:hover { transform: translateY(-3px); text-decoration: none; z-index: 3; }
.tl-avatar-img {
  width: 64px; height: 64px; border-radius: 8px;
  background-color: var(--panel);
  background-size: cover; background-position: center top;
  border: 2px solid var(--dyn, var(--line));
  display: flex; align-items: center; justify-content: center;
  transition: box-shadow 0.18s ease;
}
/* Tier list avatars carry the same breathing rarity frame as the database
   cards, so a row of S tier reads at a glance as gold, violet or blue. Hover
   still wins: the halo in the element colour is what tells you which avatar
   the cursor is actually on. */
.tl-avatar.r5 .tl-avatar-img,
.tl-avatar.r4 .tl-avatar-img,
.tl-avatar.r3 .tl-avatar-img {
  border-color: rgba(var(--rc-glow), 0.6);
  animation: rarityEdge var(--rc-beat, 2.6s) ease-in-out infinite,
             rarityHalo var(--rc-beat, 2.6s) ease-in-out infinite;
}
.tl-avatar:hover .tl-avatar-img {
  box-shadow: 0 0 14px var(--dyn, var(--accent));
  animation: none; border-color: var(--dyn, var(--line));
}
@media (prefers-reduced-motion: reduce) {
  .tl-avatar .tl-avatar-img { animation: none; border-color: var(--rc, var(--dyn, var(--line))); }
}
.tl-avatar-ph { font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; color: var(--muted); }
.tl-avatar-name {
  display: block; font-size: 0.68rem; font-weight: 600; margin-top: 0.25rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tl-new {
  position: absolute; top: -6px; right: -8px; z-index: 2;
  background: #F3555A; color: #fff;
  font-size: 0.56rem; font-weight: 800; letter-spacing: 0.06em;
  padding: 0.1rem 0.32rem; border-radius: 4px;
  animation: newPulse 1.6s infinite alternate;
}
@keyframes newPulse { from { box-shadow: 0 0 3px #F3555A; } to { box-shadow: 0 0 10px #F3555A; } }

/* ================= tooltip ================= */

.char-tip {
  position: fixed; z-index: 200; width: 240px;
  background: rgba(12, 14, 20, 0.96);
  border: 1px solid var(--accent); border-radius: 10px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.6), 0 0 18px var(--accent-soft);
  backdrop-filter: blur(8px);
  padding: 0.8rem 0.9rem;
  opacity: 0; transform: scale(0.97); pointer-events: none;
  transition: opacity 0.14s ease-out, transform 0.14s ease-out;
}
.char-tip.show { opacity: 1; transform: scale(1); }
.tip-name { font-family: var(--font-display); font-weight: 700; font-size: 1.08rem; margin-bottom: 0.35rem; }
.tip-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.55rem; }
.tip-chip {
  display: inline-block; font-size: 0.72rem; font-weight: 700;
  padding: 0.1rem 0.5rem; border-radius: 5px;
  background: var(--panel); border: 1px solid var(--dyn, var(--line));
  color: var(--dyn, var(--muted));
}
.tip-tier-row {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 0.8rem; color: var(--muted); padding: 0.22rem 0;
  border-top: 1px solid var(--line);
}
.tip-tier-badge {
  display: inline-block; min-width: 40px; text-align: center;
  font-family: var(--font-display); font-weight: 700; font-size: 0.82rem;
  color: #0B0C10; background: var(--dyn, var(--muted));
  padding: 0.08rem 0.45rem; border-radius: 5px;
}
.tip-hint { font-size: 0.72rem; color: var(--accent); margin-top: 0.5rem; text-align: right; }

/* ================= characters DB ================= */

.db-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1.1rem; margin-top: 1.2rem;
}
.db-card {
  position: relative; display: block;
  background: var(--panel); border-radius: 12px; overflow: visible;
  border: 2px solid var(--line); color: var(--text);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.db-card:hover { transform: translateY(-4px) scale(1.03); text-decoration: none; z-index: 2; }
.db-portrait {
  position: relative;
  width: 100%; aspect-ratio: 1; border-radius: 10px 10px 0 0;
  background-color: var(--panel-2);
  background-size: cover; background-position: center top;
  display: flex; align-items: center; justify-content: center;
}
.db-card .tl-avatar-ph { font-size: 2.6rem; }
.db-card-body { padding: 0.55rem 0.7rem 0.7rem; display: flex; flex-direction: column; gap: 0.15rem; }
.db-name { font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; }
.db-role { display: flex; align-items: center; gap: 0.4rem; font-size: 0.76rem; color: var(--muted); }

/* Rarity flair — adapted from the old site's pulse system */
.stars-wrap { letter-spacing: 0.08em; font-size: 0.72rem; line-height: 1; }
.star.filled { display: inline-block; animation: starPulse 2s infinite ease-in-out; }
.star.filled:nth-child(2) { animation-delay: 0.12s; }
.star.filled:nth-child(3) { animation-delay: 0.24s; }
.star.filled:nth-child(4) { animation-delay: 0.36s; }
.star.filled:nth-child(5) { animation-delay: 0.48s; }
@keyframes starPulse {
  0%, 100% { transform: scale(1); opacity: 0.82; }
  50% { transform: scale(1.16); opacity: 1; }
}
.r5 .star.filled { color: var(--r5); }
.r4 .star.filled { color: var(--r4); }
.r3 .star.filled { color: var(--r3); }

/* Every rarity now breathes, not just SSR. Each tier drives the same two
   keyframes through its own --rc / --rc-glow pair, so the border brightens and
   the halo swells in the tier's colour: gold for SSR, violet for SR, blue for
   R. Speed steps down with rarity so an SSR card reads as the liveliest thing
   on the grid and an R card is a slow, quiet shimmer. */
.db-card.r5, .db-card.r4, .db-card.r3 {
  border-color: rgba(var(--rc-glow), 0.55);
  animation: rarityEdge var(--rc-beat, 2.6s) ease-in-out infinite,
             rarityHalo var(--rc-beat, 2.6s) ease-in-out infinite;
}
.r5 { --rc: var(--r5); --rc-glow: var(--r5-glow); --rc-beat: 2.4s; }
.r4 { --rc: var(--r4); --rc-glow: var(--r4-glow); --rc-beat: 3s; }
.r3 { --rc: var(--r3); --rc-glow: var(--r3-glow); --rc-beat: 3.8s; }
@keyframes rarityEdge {
  0%, 100% { border-color: rgba(var(--rc-glow), 0.45); }
  50%      { border-color: rgba(var(--rc-glow), 1); }
}
@keyframes rarityHalo {
  0%, 100% { box-shadow: 0 0 4px rgba(var(--rc-glow), 0.28); }
  50%      { box-shadow: 0 0 15px rgba(var(--rc-glow), 0.62); }
}
/* Kept for anything still calling the old name by hand. */
@keyframes pulseGold {
  0%, 100% { box-shadow: 0 0 4px rgba(247, 198, 75, 0.45); }
  50%      { box-shadow: 0 0 14px rgba(247, 198, 75, 0.6); }
}
/* Rarity ribbon across the top of the portrait, the same gradient as the
   card frame it is taken from, sliding slowly so gold reads as metallic. */
.db-card.r5 .db-portrait::after,
.db-card.r4 .db-portrait::after,
.db-card.r3 .db-portrait::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  border-radius: 10px 10px 0 0;
  background: linear-gradient(90deg,
    rgba(var(--rc-glow), 0.15) 0%, rgba(var(--rc-glow), 1) 35%,
    #FFFFFF 50%, rgba(var(--rc-glow), 1) 65%, rgba(var(--rc-glow), 0.15) 100%);
  background-size: 220% 100%;
  animation: raritySheen var(--rc-beat, 2.6s) linear infinite;
}
@keyframes raritySheen {
  from { background-position: 140% 0; }
  to   { background-position: -60% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .db-card.r5, .db-card.r4, .db-card.r3 { animation: none; border-color: var(--rc); }
  .db-card .db-portrait::after { animation: none; }
  .star.filled { animation: none; }
}

/* ================= character page ================= */

.char-head { display: flex; gap: 1.4rem; align-items: center; margin-top: 0.4rem; }
.char-head-portrait {
  width: 132px; height: 132px; flex: none;
  border-radius: 12px; border: 2px solid var(--line);
}
.char-head.r5 .char-head-portrait,
.char-head.r4 .char-head-portrait,
.char-head.r3 .char-head-portrait {
  border-color: rgba(var(--rc-glow), 0.55);
  animation: rarityEdge var(--rc-beat, 2.6s) ease-in-out infinite,
             rarityHalo var(--rc-beat, 2.6s) ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .char-head .char-head-portrait { animation: none; border-color: var(--rc, var(--line)); }
}
.char-title { color: var(--muted); font-style: italic; margin: 0.1rem 0 0.4rem; }
.char-tags { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.tier-badge-row { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 0.8rem; }
.tier-badge-block { display: flex; flex-direction: column; align-items: center; gap: 0.2rem; }
.tier-badge-cat { font-size: 0.68rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }

.char-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 2.4rem; }
.char-columns .sec-head { margin-top: 1.6rem; }
.char-columns > div > .sec-head:first-child { margin-top: 0; }

.rating { display: grid; grid-template-columns: 90px 1fr 42px; align-items: center; gap: 0.7rem; margin-bottom: 0.55rem; font-size: 0.88rem; }
.rating-label { color: var(--muted); }
.rating-track { height: 8px; background: var(--panel); border-radius: 99px; overflow: hidden; }
.rating-fill { display: block; height: 100%; width: 0; border-radius: 99px; background: linear-gradient(90deg, var(--r4), var(--accent)); transition: width 0.7s ease; }
.rating-num { text-align: right; font-family: var(--font-display); font-weight: 700; color: var(--accent); }

.build-list dt {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: 0.76rem; letter-spacing: 0.12em; color: var(--accent);
  margin-top: 0.8rem;
}
.build-list dd { margin: 0.15rem 0 0; font-size: 0.95rem; }

.pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1.6rem; }
.pros-cons h3 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.12em; margin-bottom: 0.4rem; }
.pros h3 { color: #7FD98F; }
.cons h3 { color: #F3555A; }
.pros-cons ul { padding-left: 1.1rem; font-size: 0.9rem; color: var(--muted); }
.pros-cons li { margin-bottom: 0.35rem; }

/* ================= guide article ================= */

.article { max-width: 780px; }
.article-head { display: flex; gap: 1.1rem; align-items: center; margin-bottom: 1.6rem; }
.article-thumb { width: 96px; height: 96px; font-size: 2rem; }
.article-sub { color: var(--muted); margin-top: 0.2rem; }
.article-meta { font-size: 0.84rem; color: var(--muted); margin-top: 0.35rem; }
.article-meta strong { color: var(--text); }
.article-body p { margin: 0.9rem 0; }
.article-body ul { padding-left: 1.3rem; margin: 0.9rem 0; }
.article-body li { margin-bottom: 0.45rem; }
.article-body .sec-head { margin-top: 2rem; }

.note {
  border: 1px solid var(--accent-line); border-left: 4px solid var(--accent);
  background: var(--accent-soft); border-radius: 0 8px 8px 0;
  padding: 0.9rem 1.1rem; margin: 1.3rem 0;
}
.note-head {
  display: flex; align-items: center; gap: 0.45rem;
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; font-size: 0.82rem; color: var(--accent);
  margin-bottom: 0.35rem;
}
.note p { margin: 0; font-size: 0.95rem; }
.tip {
  border-left: 3px solid var(--r5); background: rgba(245, 185, 66, 0.07);
  padding: 0.75rem 1rem; margin: 1.2rem 0; border-radius: 0 8px 8px 0; font-size: 0.93rem;
}
.tip strong { color: var(--r5); font-family: var(--font-display); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.12em; margin-right: 0.5rem; }

/* ================= footer ================= */

#site-footer { border-top: 1px solid var(--line); }
.footer-inner {
  max-width: 1180px; margin: 0 auto; padding: 1.5rem 1.4rem 2.2rem;
  color: var(--muted); font-size: 0.85rem;
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 1rem 2rem; flex-wrap: wrap;
}
.footer-info { min-width: 240px; flex: 1 1 320px; }
.footer-social a { text-transform: capitalize; margin-right: 0.3rem; }
@media (max-width: 720px) {
  .footer-inner { flex-direction: column; align-items: flex-start; }
}

/* ================= responsive ================= */

@media (max-width: 1020px) {
  .home-cols { grid-template-columns: 1fr; }
  .char-columns { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  .side-toggle { display: block; }
  .side-collapse { display: none; }
  #sidebar { transform: translateX(-100%); box-shadow: 12px 0 30px rgba(0,0,0,0.5); }
  body.sidebar-open #sidebar,
  body.with-sidebar.sidebar-collapsed.sidebar-open #sidebar { transform: translateX(0); }
  body.with-sidebar #main, body.with-sidebar #site-footer { margin-left: 0; }

  /* ---- mobile nav: hamburger sheet, games as a vertical accordion ---- */
  .nav-toggle { display: block; margin-left: auto; }
  .nav-links {
    display: none; position: absolute; top: var(--topbar-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0.15rem;
    background: #0E1016; border-bottom: 1px solid var(--line);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
    padding: 0.6rem 0.9rem 1rem;
    max-height: calc(100vh - var(--topbar-h)); overflow-y: auto;
    white-space: normal; margin-left: 0;
  }
  .nav-links.open { display: flex; animation: fadeIn 0.25s ease; }
  .nav-main { flex-direction: column; align-items: stretch; gap: 0.15rem; }

  /* ---- mobile search ----
     A 280px pill will not fit next to a brand, a hamburger, a Discord link and
     an account chip on a 390px screen, so the field collapses to a magnifier
     and reopens as its own full-width row hanging below the bar. #site-nav sets
     no overflow, which is what lets that row hang there instead of being
     clipped. The field is only display:none while closed, and JS focuses it
     after the class flips, so nothing is focused inside a hidden element. */
  .nav-search-btn {
    display: inline-grid; place-items: center;
    width: 38px; height: 38px; flex: 0 0 auto;
    background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
    color: var(--text); font-size: 1rem; cursor: pointer; padding: 0;
    transition: border-color 0.16s ease, background 0.16s ease;
  }
  .nav-search-btn[aria-expanded="true"] { border-color: var(--accent); background: var(--accent-soft); }
  .nav-search { display: none; }
  body.search-open .nav-search {
    display: flex;
    position: absolute; top: calc(var(--topbar-h) - 0.35rem); left: 0.9rem; right: 0.9rem;
    z-index: 61; flex: none; height: 42px;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
    animation: navDrop 0.2s ease;
  }
  .nav-search-kbd { display: none; }
  .nav-search-res { width: auto; left: 0; right: 0; }

  .brand-name { font-size: 1rem; }
  .tl-row { grid-template-columns: 52px repeat(var(--cols, 3), 1fr); }
  .tl-tier-label { font-size: 1rem; }
  .tl-avatar, .tl-avatar-img { width: 54px; }
  .tl-avatar-img { height: 54px; }
  .char-head { flex-direction: column; align-items: flex-start; }
  .pros-cons { grid-template-columns: 1fr; }
  .pill-reset { margin-left: 0; }
}

/* ================= accessibility ================= */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}

/* Unknown-rarity cards (stub entries, pets) — neutral border */
.db-card.r0 { border-color: var(--line); }
.char-head.r0 .char-head-portrait { border-color: var(--line); }
.tip-col { color: var(--muted); font-size: 0.72rem; }

/* Wide multi-column tier grids scroll horizontally on small screens */
.tl-grid-wrap { overflow-x: auto; }
@media (max-width: 1020px) {
  .tl-grid-wrap .tl-row { min-width: 820px; }
}

/* ================= per-game keyart background =================
   Two fixed layers crossfade between game backgrounds. The
   gradient overlay fades the art into the page background so
   content stays readable (Prydwen-style). */

.site-bg { position: fixed; inset: 0; z-index: -2; pointer-events: none; }
.site-bg-layer {
  position: absolute; inset: 0;
  background-size: cover; background-position: center 18%;
  opacity: 0;
  transform: scale(1.04);
  /* Smoother, silkier cross-fade for game-selection wallpaper swaps. core.js
     stacks one layer per wallpaper and uses this duration (BG_FADE_MS) to know
     when a retired layer has finished fading and can be removed. */
  transition: opacity 1.3s cubic-bezier(0.33, 0, 0.2, 1), transform 2.2s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity, transform;
}
.site-bg-layer.show { opacity: 0.38; transform: scale(1); }
.site-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg) 55%, transparent) 0%,
      color-mix(in srgb, var(--bg) 82%, transparent) 40%,
      var(--bg) 82%);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .site-bg::after {
    background: linear-gradient(180deg, rgba(10, 11, 16, 0.55) 0%, rgba(10, 11, 16, 0.82) 40%, rgba(10, 11, 16, 0.99) 82%);
  }
}

/* ================= page transitions ================= */

/* Cross-document View Transitions (Chrome/Edge 126+, Safari 18.2+) */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation-duration: 0.22s; }
::view-transition-new(root) { animation-duration: 0.28s; }

/* JS fallback: fade the page out before navigating */
body { transition: opacity 0.17s ease; }
body.page-exit { opacity: 0; }

/* ================= scroll polish ================= */

#site-nav { transition: box-shadow 0.25s ease; }
#site-nav.scrolled { box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45); }

/* ===== scroll reveal =====
   Two layers. The section itself fades and lifts on a transition, because a
   section never has a hover state to protect. The items inside it (game tiles,
   update rows, banner cards, guide and upcoming rails) stagger in one after
   another on a KEYFRAME with no fill-mode, and that detail is load-bearing: a
   transition, or animation-fill-mode: forwards, would leave a transform sitting
   on the element after the reveal finished and silently kill the hover lift on
   every card it touched. Ending with no fill means the element goes back to
   owning its own transform the moment the animation is over, and .rv-in - added
   by the same observer - is what holds the final opacity.

   Both classes are added by JS, so a browser without IntersectionObserver never
   sees .reveal or .rv and gets a plain, fully visible page. */
.section.reveal, .role-group.reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.section.reveal.in-view, .role-group.reveal.in-view { opacity: 1; transform: none; }

@keyframes rvUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.rv { opacity: 0; }
.rv.rv-in { opacity: 1; animation: rvUp 0.44s cubic-bezier(0.22, 0.61, 0.36, 1) backwards; }
/* `backwards`, never `forwards` or `both`. Backwards fills only during the
   stagger delay, so an item waiting its turn is already hidden instead of
   flashing at full opacity first. Forwards would keep applying the last
   keyframe after the animation ended, and that last keyframe sets
   transform: none - which is exactly the property every card hover needs. */

@media (prefers-reduced-motion: reduce) {
  .section.reveal, .role-group.reveal { transition: none; opacity: 1; transform: none; }
  .rv, .rv.rv-in { opacity: 1; animation: none; }
}

.to-top {
  position: fixed; right: 1.1rem; bottom: 1.1rem; z-index: 80;
  width: 44px; height: 44px; border-radius: 10px;
  background: var(--panel); color: var(--accent);
  border: 1px solid var(--line); font-size: 1.15rem; cursor: pointer;
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.to-top.show { opacity: 1; transform: none; pointer-events: auto; }
.to-top:hover { border-color: var(--accent); box-shadow: 0 0 14px var(--accent-soft); }

/* ============================================================
   PHONE BOTTOM BAR, GAMES SHEET, SECTION JUMP
   ------------------------------------------------------------
   Everything here is inert above 860px. The bar itself is display:none and the
   sheet is only ever opened by a button that lives inside the bar, so desktop
   never renders any of it. That is deliberate: this is a phone affordance, not
   a responsive restyle of an existing desktop one.

   --mbar-h is the bar's own height; the reserved space underneath the page is
   that plus the iOS home-indicator inset, which is why the two are separate
   variables. Anything fixed to the bottom of the screen (the back-to-top
   button, the contribute bar, the translate popup) has to sit above
   --mbar-space or it lands underneath the bar and cannot be tapped.
   ============================================================ */
:root { --mbar-h: 58px; --mbar-space: 0px; }

.mbar { display: none; }
.msheet-ov { display: none; }
.mjump { display: none; }

@media (max-width: 860px) {
  :root { --mbar-space: calc(var(--mbar-h) + env(safe-area-inset-bottom, 0px)); }

  .mbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    display: flex; align-items: stretch;
    height: var(--mbar-h);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: color-mix(in srgb, var(--panel) 92%, transparent);
    border-top: 1px solid var(--line);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.34);
  }
  /* backdrop-filter is progressive: where it is unsupported the 92% panel mix
     above is already opaque enough to read against. */
  @supports (backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px)) {
    .mbar { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); background: color-mix(in srgb, var(--panel) 76%, transparent); }
  }

  .mbar-i {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.14rem; padding: 0.3rem 0.15rem 0.2rem;
    background: none; border: 0; border-radius: 0;
    font: inherit; color: var(--muted); text-decoration: none;
    cursor: pointer; position: relative;
    -webkit-tap-highlight-color: transparent;
    transition: color 0.16s ease;
  }
  .mbar-i:hover, .mbar-i:focus-visible { color: var(--text); text-decoration: none; }
  .mbar-i.active { color: var(--accent); }
  /* The lit tab gets a short rule along the top edge rather than a filled pill.
     A pill under a 58px bar leaves no room for a legible label, and the label is
     the part that makes a four-icon bar learnable. */
  .mbar-i.active::before {
    content: ""; position: absolute; top: -1px; left: 50%; transform: translateX(-50%);
    width: 30px; height: 2px; border-radius: 0 0 3px 3px; background: var(--accent);
  }
  .mbar-svg { width: 22px; height: 22px; flex: none; }
  .mbar-l {
    font-size: 0.63rem; font-weight: 700; letter-spacing: 0.01em;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* Inside a game the Games tab wears that game's icon. */
  .mbar-gic {
    width: 22px; height: 22px; border-radius: 7px; flex: none;
    background: var(--panel-2) center/cover no-repeat;
    border: 1px solid var(--line);
    display: grid; place-items: center; overflow: hidden;
  }
  .mbar-i.active .mbar-gic { border-color: var(--accent); }
  .mbar-gph { font-family: var(--font-display); font-weight: 800; font-size: 0.7rem; color: var(--muted); }
  .mbar-gic.has-img .mbar-gph { display: none; }

  /* Reserve the bar's space at the end of the document rather than on <body>.
     Padding on the body would also pad the fixed topbar's containing block and
     is a common source of a phantom scrollbar; the footer is the last thing in
     flow, so growing it moves nothing else. */
  body.has-mbar #site-footer { padding-bottom: calc(var(--mbar-space) + 0.9rem); }
  body.has-mbar .to-top { bottom: calc(var(--mbar-space) + 0.7rem); }
  body.has-mbar .contrib-bar { bottom: calc(var(--mbar-space) + 0.7rem); }
  body.has-mbar .ct-pop { bottom: calc(var(--mbar-space) + 10px); }

  /* ---- the hamburger goes away ----
     CFG.nav is Home / Upcoming games / Guides and the sheet holds every game.
     The bar therefore carries the whole of the hamburger sheet, and keeping
     both would mean two menus with identical contents - which teaches a reader
     to trust neither, and costs ~46px of a topbar that measured 36px short. */
  .nav-toggle { display: none !important; }
  .nav-links { display: none !important; }

  /* ---- the section jump pill ----
     Left side, because the back-to-top button owns the right. It names the
     section you are scrolled to, so it is doing work even when it is not
     tapped. */
  .mjump {
    position: fixed; left: 0.9rem; bottom: calc(var(--mbar-space) + 0.7rem); z-index: 88;
    display: inline-flex; align-items: center; gap: 0.4rem;
    max-width: min(62vw, 260px);
    height: 38px; padding: 0 0.75rem;
    border-radius: 999px; border: 1px solid var(--line);
    background: color-mix(in srgb, var(--panel) 94%, transparent);
    color: var(--text); font: inherit; font-size: 0.78rem; font-weight: 700;
    cursor: pointer; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
    -webkit-tap-highlight-color: transparent;
  }
  .mjump {
    opacity: 0; transform: translateY(10px); pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease, border-color 0.2s ease;
  }
  .mjump.show { opacity: 1; transform: none; pointer-events: auto; }
  .mjump:hover, .mjump:focus-visible { border-color: var(--accent); }
  .mjump .mbar-svg { width: 16px; height: 16px; color: var(--accent); }
  .mjump-l { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* ---- the sheet ---- */
  .msheet-ov {
    position: fixed; inset: 0; z-index: 120;
    display: block; background: rgba(6, 7, 11, 0.62);
    opacity: 0; transition: opacity 0.22s ease;
  }
  .msheet-ov.open { opacity: 1; }
  .msheet-ov[hidden] { display: none; }
  .msheet {
    position: absolute; left: 0; right: 0; bottom: 0;
    max-height: 82vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 0.4rem 0.9rem calc(1rem + env(safe-area-inset-bottom, 0px));
    background: var(--panel); border-top: 1px solid var(--line);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -18px 50px rgba(0, 0, 0, 0.55);
    transform: translateY(101%);
    transition: transform 0.24s cubic-bezier(0.22, 0.8, 0.3, 1);
  }
  .msheet-ov.open .msheet { transform: none; }
  .msheet-grab { width: 40px; height: 4px; border-radius: 999px; background: var(--line); margin: 0.35rem auto 0.6rem; }
  .msheet-h {
    margin: 0 0 0.55rem; font-size: 0.62rem; font-weight: 800;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent);
  }

  .mrow + .mrow { margin-top: 0.5rem; }
  .mrow-head {
    position: relative; overflow: hidden; isolation: isolate;
    display: flex; align-items: center; gap: 0.6rem;
    min-height: 66px; padding: 0.6rem 0.75rem;
    border-radius: 13px; border: 1px solid var(--line);
    background: var(--panel-2); color: var(--text); text-decoration: none;
  }
  .mrow.current .mrow-head { border-color: var(--accent); }
  .mrow-art { position: absolute; inset: 0; z-index: -2; background: var(--panel-2) center/cover no-repeat; }
  .mrow-head::after {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(90deg, rgba(10, 11, 16, 0.9) 0%, rgba(10, 11, 16, 0.72) 55%, rgba(10, 11, 16, 0.5) 100%);
  }
  .mrow-ic {
    flex: none; width: 38px; height: 38px; border-radius: 10px;
    background: var(--panel) center/cover no-repeat;
    border: 1px solid rgba(255, 255, 255, 0.2);
    display: grid; place-items: center; overflow: hidden;
  }
  .mrow-ph { font-family: var(--font-display); font-weight: 800; color: var(--muted); }
  .mrow-ic.has-img .mrow-ph { display: none; }
  .mrow-tx { min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
  .mrow-t { font-family: var(--font-display); font-weight: 800; font-size: 0.98rem; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mrow-s { font-size: 0.7rem; color: #C7CDE4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mrow-tick { margin-left: auto; color: var(--accent); font-weight: 800; }
  .mrow-go { margin-left: auto; color: #C7CDE4; font-size: 1.2rem; line-height: 1; }

  /* Only the game you are already inside opens up. Expanding all three would be
     a wall of forty links, which is the sidebar the phone deliberately hides. */
  .mrow-secs {
    display: grid; grid-template-columns: 1fr 1fr; gap: 0.35rem;
    margin: 0.4rem 0 0; padding: 0.5rem;
    border: 1px solid var(--line); border-top: 0;
    border-radius: 0 0 12px 12px; background: var(--panel-2);
  }
  .msec {
    display: flex; align-items: center; gap: 0.4rem;
    min-height: 40px; padding: 0.4rem 0.55rem;
    border-radius: 9px; background: var(--panel);
    border: 1px solid var(--line);
    color: var(--text); text-decoration: none;
    font-size: 0.8rem; font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .msec:hover, .msec:focus-visible { border-color: var(--accent); text-decoration: none; }
  .msec-i { flex: none; font-size: 0.9rem; }

  .msheet-all {
    display: block; margin-top: 0.65rem; padding: 0.7rem;
    text-align: center; border-radius: 11px;
    border: 1px dashed var(--accent-line); color: var(--accent);
    font-size: 0.82rem; font-weight: 700; text-decoration: none;
  }
  .msheet-all:hover { text-decoration: none; background: var(--accent-soft); }

  .msheet-h2 { margin-top: 0.9rem; }
  .mrow-secs-flat { margin: 0; border-radius: 12px; border-top: 1px solid var(--line); }
  .msec.current { border-color: var(--accent); color: var(--accent); }

  .mjump-list { display: flex; flex-direction: column; gap: 0.3rem; }
  .mjump-i {
    display: flex; align-items: center; gap: 0.55rem;
    min-height: 44px; padding: 0.5rem 0.7rem; width: 100%;
    border-radius: 10px; border: 1px solid var(--line); background: var(--panel-2);
    color: var(--text); font: inherit; font-size: 0.86rem; font-weight: 600;
    text-align: left; cursor: pointer;
  }
  .mjump-i:hover, .mjump-i:focus-visible { border-color: var(--accent); }
  .mjump-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }

  /* position: fixed, not overflow: hidden. overflow:hidden on <body> does not
     stop the page scrolling behind a sheet on iOS Safari; pinning it does, and
     the JS restores the scroll offset when the sheet closes. */
  body.sheet-lock { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .msheet, .msheet-ov { transition: none; }
}

/* Staggered card entrances (new nodes re-trigger on each render) */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.gcard, .guide-card, .tool-card, .db-card { animation: riseIn 0.45s ease backwards; }
.gcard:nth-child(2), .guide-card:nth-child(2), .tool-card:nth-child(2), .db-card:nth-child(2) { animation-delay: 0.05s; }
.gcard:nth-child(3), .guide-card:nth-child(3), .tool-card:nth-child(3), .db-card:nth-child(3) { animation-delay: 0.1s; }
.gcard:nth-child(4), .guide-card:nth-child(4), .tool-card:nth-child(4), .db-card:nth-child(4) { animation-delay: 0.15s; }
.gcard:nth-child(5), .guide-card:nth-child(5), .tool-card:nth-child(5), .db-card:nth-child(5) { animation-delay: 0.2s; }
.gcard:nth-child(6), .guide-card:nth-child(6), .tool-card:nth-child(6), .db-card:nth-child(6) { animation-delay: 0.25s; }
.gcard:nth-child(n+7), .guide-card:nth-child(n+7), .tool-card:nth-child(n+7), .db-card:nth-child(n+7) { animation-delay: 0.3s; }

.tl-grid-wrap.fade-in .tl-row, .role-grid .role-row { animation: riseIn 0.4s ease backwards; }
.tl-grid-wrap.fade-in .tl-row:nth-child(2), .role-grid .role-row:nth-child(2) { animation-delay: 0.04s; }
.tl-grid-wrap.fade-in .tl-row:nth-child(3), .role-grid .role-row:nth-child(3) { animation-delay: 0.08s; }
.tl-grid-wrap.fade-in .tl-row:nth-child(4), .role-grid .role-row:nth-child(4) { animation-delay: 0.12s; }
.tl-grid-wrap.fade-in .tl-row:nth-child(n+5), .role-grid .role-row:nth-child(n+5) { animation-delay: 0.16s; }

/* ================= roles & effects page ================= */

.page-wide { max-width: 1400px; }

.role-key-panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.2rem 1.1rem; margin: 1.1rem 0 1.4rem;
}
.role-key-legend {
  display: flex; gap: 1.4rem; flex-wrap: wrap;
  margin-bottom: 0.6rem; font-size: 0.92rem;
}
.role-legend-item { display: inline-flex; align-items: center; gap: 0.45rem; }
.role-legend-swatch { display: inline-block; width: 14px; height: 14px; border-radius: 4px; flex: none; }
.role-legend-perm { background: linear-gradient(135deg, #6FA8F0, #F0A0C8); }
.role-legend-dur { background: #101219; border: 1px solid var(--line); }
.role-key-panel ul { padding-left: 1.2rem; margin: 0 0 0.9rem; color: #C9CEE2; font-size: 0.9rem; }
.role-key-panel li { margin: 0.25rem 0; }
.role-key-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.role-key {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.8rem; font-weight: 600; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
  padding: 0.28rem 0.75rem;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.role-key .el-dot { background: var(--dyn, var(--muted)); }
.role-key:hover {
  text-decoration: none; border-color: var(--dyn, var(--accent));
  transform: translateY(-1px);
}

.role-group { margin-top: 2rem; scroll-margin-top: calc(var(--topbar-h) + 14px); }
.role-group-head {
  display: flex; align-items: center; gap: 0.6rem;
  font-size: 1.2rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding-bottom: 0.45rem; margin-bottom: 0.8rem;
  border-bottom: 2px solid var(--dyn, var(--line));
}
.role-square { width: 12px; height: 12px; background: var(--dyn, var(--accent)); flex: none; }
.role-count {
  margin-left: auto; font-size: 0.72rem; font-family: var(--font-body);
  color: var(--muted); letter-spacing: 0.12em; font-weight: 600;
}

.role-grid {
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--panel-2);
}
.role-row { display: grid; grid-template-columns: 250px 1fr; border-bottom: 1px solid var(--line); }
.role-row:last-child { border-bottom: none; }
.role-label {
  display: flex; flex-direction: column; justify-content: center; gap: 0.35rem;
  padding: 0.7rem 0.9rem;
  background: var(--panel);
  border-left: 4px solid var(--dyn, var(--line));
  font-family: var(--font-display);
}
@supports (background: color-mix(in srgb, red 50%, blue)) {
  .role-label { background: color-mix(in srgb, var(--dyn) 16%, var(--panel-2)); }
}
/* Dark label = duration-based effect (see the page key) */
.role-duration .role-label { background: #0C0E14; }
.role-name { font-weight: 700; font-size: 0.95rem; line-height: 1.25; }
.role-tags { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.role-scope {
  font-size: 0.64rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  font-family: var(--font-body);
  color: var(--text); opacity: 0.85;
  background: rgba(255, 255, 255, 0.08);
  padding: 0.06rem 0.45rem; border-radius: 4px;
}
.role-dur {
  font-size: 0.64rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  font-family: var(--font-body);
  color: #F0C04E; background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(240, 192, 78, 0.4);
  padding: 0.06rem 0.45rem; border-radius: 4px;
}
.role-cell {
  display: flex; flex-wrap: wrap; gap: 0.55rem; align-content: flex-start;
  padding: 0.65rem; min-height: 84px;
}
.role-ghost { cursor: default; }
.role-ghost .tl-avatar-img { border-style: dashed; }
.role-hidden { display: none !important; }
.role-footnote { margin-top: 1.6rem; font-size: 0.85rem; }

@media (max-width: 860px) {
  .role-row { grid-template-columns: 1fr; }
  .role-label {
    flex-direction: row; align-items: center; justify-content: flex-start;
    border-left: none; border-top: 3px solid var(--dyn, var(--line));
    padding: 0.5rem 0.9rem;
  }
}

/* ================= sidebar collapse & game switcher ================= */

.side-collapse {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font-size: 1.02rem; cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.side-collapse:hover { color: var(--accent); border-color: var(--accent); }
body.with-sidebar #main, body.with-sidebar #site-footer { transition: margin-left 0.3s ease; }
body.with-sidebar.sidebar-collapsed #sidebar { transform: translateX(-100%); box-shadow: none; }
body.with-sidebar.sidebar-collapsed #main,
body.with-sidebar.sidebar-collapsed #site-footer { margin-left: 0; }

.side-game { position: relative; padding: 0; }
.side-game-btn {
  display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.7rem 0.8rem;
  background: none; border: none; color: var(--text);
  font-family: var(--font-display); cursor: pointer; text-align: left;
}
.side-game-btn:hover .side-switch { color: var(--accent); border-color: var(--accent); transform: rotate(180deg); }
.side-menu {
  display: none; position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 70;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.55);
  padding: 0.35rem;
}
.side-menu.open { display: block; animation: fadeIn 0.18s ease; }
.side-menu-item {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.5rem 0.65rem; border-radius: 6px;
  color: var(--text); font-weight: 600; font-size: 0.92rem;
}
.side-menu-item:hover { background: var(--accent-soft); color: var(--accent); text-decoration: none; }
.side-menu-item.current { color: var(--accent); }
.side-menu-tick { color: var(--accent); }
.side-menu-home { border-top: 1px solid var(--line); margin-top: 0.25rem; color: var(--muted); }
.side-menu-home .side-icon { margin-right: 0.35rem; }

/* ================= filter toolbar (Prydwen-style) ================= */

.filter-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
  margin: 0 0 1.2rem;
}
.filter-search { flex: 1 1 240px; max-width: 420px; }
.fgroup {
  display: inline-flex; overflow: hidden; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
}
.fbtn {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: transparent; border: none; border-left: 1px solid var(--line);
  color: var(--muted); cursor: pointer;
  font-family: var(--font-display); font-weight: 600; font-size: 0.88rem;
  padding: 0.5rem 0.8rem;
  transition: background 0.15s ease, color 0.15s ease;
}
.fgroup .fbtn:first-child { border-left: none; }
.fbtn:hover { color: var(--text); background: rgba(255, 255, 255, 0.05); }
.fbtn.active, .fbtn-all.active { background: var(--accent); color: #0B0C10; }
.fbtn-el .el-dot { background: var(--dyn, var(--muted)); }
.fbtn-el.active { background: var(--dyn, var(--accent)); color: #0B0C10; }
.fbtn-el.active .el-dot { background: rgba(0, 0, 0, 0.55); }
.fbtn-reset {
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
}
.fbtn-reset:hover { color: #F3555A; border-color: #F3555A; background: transparent; }
.filter-count { margin-left: auto; color: var(--muted); font-size: 0.82rem; white-space: nowrap; }
@media (max-width: 860px) {
  .filter-count { margin-left: 0; width: 100%; }
}

/* ================= upcoming games tracker ================= */

.upg-head { text-align: center; margin-bottom: 1.4rem; }
.upg-search { margin: 1rem auto 0; display: block; }
.upg-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 1rem; }
.upg-card {
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
  animation: riseIn 0.45s ease backwards;
}
.upg-card:hover { transform: translateY(-3px); border-color: var(--accent-line); box-shadow: 0 10px 26px rgba(0, 0, 0, 0.4); }
.upg-band {
  padding: 0.85rem 1rem 0.75rem;
  background: var(--panel-2);
  border-bottom: 2px solid var(--dyn, var(--line));
}
@supports (background: color-mix(in srgb, red 50%, blue)) {
  .upg-band { background: color-mix(in srgb, var(--dyn) 26%, var(--panel-2)); }
}
.upg-name { font-family: var(--font-display); font-size: 1.15rem; font-weight: 700; }
.upg-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.4rem; }
.upg-chip {
  font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  background: rgba(0, 0, 0, 0.4); color: #fff;
  padding: 0.12rem 0.5rem; border-radius: 4px;
}
.upg-chip-region { background: rgba(255, 255, 255, 0.14); }
.upg-body { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.9rem 1rem 1rem; flex: 1; }
.upg-blurb { font-size: 0.9rem; color: #C9CEE2; flex: 1; }
.upg-meta-row { display: flex; gap: 0.6rem; align-items: baseline; font-size: 0.85rem; }
.upg-meta-label {
  flex: none; width: 96px;
  color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em;
}
.upg-date { color: #7FD98F; }
.upg-tba { color: var(--muted); }
.upg-plat {
  display: inline-block; background: var(--panel-2); border: 1px solid var(--line);
  font-size: 0.72rem; padding: 0.06rem 0.45rem; border-radius: 4px; margin-right: 0.25rem;
}
.up-more .up-name { color: var(--accent); }

/* ================= team builder ================= */

.tb-actions { display: flex; gap: 0.6rem; align-items: center; margin-bottom: 1rem; flex-wrap: wrap; }
.tb-btn {
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  padding: 0.45rem 0.95rem; border-radius: 8px; cursor: pointer;
  font-family: var(--font-display); font-weight: 600; font-size: 0.92rem;
  transition: border-color 0.15s ease, color 0.15s ease, filter 0.15s ease;
}
.tb-btn:hover { border-color: var(--accent); color: var(--accent); }
.tb-btn-accent { background: var(--accent); border-color: var(--accent); color: #0B0C10; }
.tb-btn-accent:hover { filter: brightness(1.15); color: #0B0C10; }
.tb-copied { color: #7FD98F; font-size: 0.85rem; word-break: break-all; }

.tb-slots { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.9rem; max-width: 940px; }
.tb-slot {
  position: relative; min-height: 190px; padding: 0.6rem;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.35rem;
  border: 2px dashed var(--line); border-radius: 12px;
  background: var(--panel-2); color: var(--muted); cursor: pointer;
  font-family: var(--font-display); font-weight: 600; font-size: 0.95rem;
  transition: border-color 0.2s ease, transform 0.2s ease, color 0.2s ease;
}
.tb-slot:hover { border-color: var(--accent); color: var(--text); transform: translateY(-2px); }
.tb-slot-filled { border-style: solid; border-color: var(--dyn, var(--line)); background: var(--panel); }
/* A filled team slot glows in its unit's rarity colour, so a team of five
   reads as gold-heavy or blue-heavy before you have read a single name. */
.tb-slot-filled.r5, .tb-slot-filled.r4, .tb-slot-filled.r3 {
  border-color: rgba(var(--rc-glow), 0.6);
  animation: rarityEdge var(--rc-beat, 2.6s) ease-in-out infinite,
             rarityHalo var(--rc-beat, 2.6s) ease-in-out infinite;
}
.tb-slot-filled:hover { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .tb-slot-filled { animation: none; border-color: var(--rc, var(--dyn, var(--line))); }
}
.tb-plus { font-size: 1.7rem; color: var(--accent); line-height: 1; }
.tb-portrait {
  display: flex; align-items: center; justify-content: center;
  width: 84px; aspect-ratio: 1; border-radius: 10px;
  background-color: var(--panel-2);
  background-size: cover; background-position: center top;
}
.tb-slot-name { color: var(--text); font-size: 1rem; }
.tb-slot-sub {
  display: flex; align-items: center; gap: 0.35rem;
  font-family: var(--font-body); font-size: 0.72rem; color: var(--muted); font-weight: 400;
}
.tb-slot-sub .el-dot { background: var(--dyn, var(--muted)); }
.tb-remove {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px;
  background: rgba(0, 0, 0, 0.5); border: 1px solid var(--line); border-radius: 6px;
  color: var(--muted); cursor: pointer; font-size: 0.8rem;
}
.tb-remove:hover { color: #F3555A; border-color: #F3555A; }

.tb-analysis { margin-top: 1.2rem; max-width: 940px; }
.tb-comp { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.7rem; }
.tb-msg {
  display: flex; gap: 0.55rem; align-items: flex-start;
  padding: 0.55rem 0.85rem; border-radius: 8px; border: 1px solid;
  margin-bottom: 0.45rem; font-size: 0.9rem;
}
.tb-msg-ico { flex: none; }
.tb-msg-warn { background: rgba(243, 85, 90, 0.1); border-color: rgba(243, 85, 90, 0.45); color: #F8B4B6; }
.tb-msg-good { background: rgba(127, 217, 143, 0.08); border-color: rgba(127, 217, 143, 0.4); color: #BFE9C8; }
.tb-msg-tip  { background: rgba(245, 185, 66, 0.08); border-color: rgba(245, 185, 66, 0.4); color: #F0D9A8; }
.tb-msg-info { background: var(--panel); border-color: var(--line); color: var(--muted); }

.preset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.9rem; }
.preset-card {
  display: flex; flex-direction: column; gap: 0.5rem; text-align: left;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.9rem 1rem; color: var(--text); cursor: pointer;
  font-family: var(--font-body);
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.preset-card:hover { border-color: var(--accent); transform: translateY(-3px); }
.preset-name { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; }
.preset-minis { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.preset-mini {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 8px;
  border: 2px solid var(--line); background-color: var(--panel-2);
  background-size: cover; background-position: center top;
  font-family: var(--font-display); color: var(--muted); font-size: 0.9rem;
}
.preset-mini.r5, .preset-mini.r4, .preset-mini.r3 { border-color: rgba(var(--rc-glow), 0.6); }
.preset-desc { font-size: 0.82rem; color: var(--muted); }
.preset-load { color: var(--accent); font-size: 0.82rem; font-weight: 700; }

/* ---- modal (character picker) ---- */

body.modal-open { overflow: hidden; }
.modal-overlay {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 10, 0.72);
  backdrop-filter: blur(4px);
  padding: 1.2rem;
  opacity: 0; transition: opacity 0.18s ease;
}
.modal-overlay.open { opacity: 1; }
.modal-overlay[hidden] { display: none; }
.modal {
  width: 100%; max-width: 920px; max-height: 86vh; overflow-y: auto;
  background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  padding: 1rem 1.2rem 1.2rem;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
  transform: translateY(12px) scale(0.98);
  transition: transform 0.18s ease;
}
.modal-overlay.open .modal { transform: none; }
.modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.8rem; }
.modal-head h2 { font-size: 1.25rem; }
.modal-close {
  width: 34px; height: 34px; border-radius: 8px;
  background: none; border: 1px solid var(--line); color: var(--muted);
  cursor: pointer; font-size: 0.95rem;
}
.modal-close:hover { color: #F3555A; border-color: #F3555A; }
.modal-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 0.7rem; margin-top: 0.4rem;
}
.modal-card {
  display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
  background: var(--panel); border: 2px solid var(--line); border-radius: 10px;
  padding: 0 0 0.5rem; overflow: hidden; color: var(--text); cursor: pointer;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.modal-card:hover { transform: translateY(-3px); border-color: var(--dyn, var(--accent)); }
.modal-card.r5, .modal-card.r4, .modal-card.r3 { border-color: rgba(var(--rc-glow), 0.5); }
.modal-card .tb-portrait { width: 100%; border-radius: 0; }
.modal-card-name { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; padding: 0 0.3rem; }
/* ================= events page ================= */
.event-content { margin-top: 1.5rem; }
.event-blurb { font-size: 1.05rem; color: var(--text); margin-bottom: 1.2rem; }
.event-reqs { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 1.8rem; }
.event-req-chip {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: rgba(243, 85, 90, 0.1); border: 1px solid rgba(243, 85, 90, 0.3);
  color: #F8B4B6; padding: 0.35rem 0.8rem; border-radius: 8px;
  font-weight: 600; font-size: 0.85rem; letter-spacing: 0.04em;
}
.event-req-chip .el-dot { background: #F3555A; }
.event-teams-grid { display: grid; gap: 1.2rem; }
.event-team-card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 1.2rem;
}
.event-team-head { margin-bottom: 1rem; border-bottom: 1px solid var(--line); padding-bottom: 0.6rem; }
.event-team-head h3 { font-size: 1.15rem; color: var(--accent); margin: 0; }
.event-team-desc { display: block; font-size: 0.85rem; color: var(--muted); margin-top: 0.2rem; }
.event-team-roster { display: flex; flex-wrap: wrap; gap: 0.8rem; }
.event-empty-slot {
  width: 64px; height: 64px; border-radius: 8px;
  border: 2px dashed var(--line); background: var(--panel-2);
}
.event-note { margin-top: 1.5rem; }

/* ===== Resolved asset images (data-imgset) ===== */
/* When an image loads, hide the letter/emoji placeholder underneath it. */
.has-img { background-size: cover; background-position: center top; }
.has-img > .gcard-ph,
.has-img > .tl-avatar-ph,
.has-img > .preset-mini-ph,
.guide-thumb.has-img > span,
.article-thumb.has-img > span { display: none; }

/* Per-game logo swapped into the top-bar brand on game pages. */
.brand.has-logo { gap: 0; }
.brand-logo {
  display: block; height: 30px; width: auto;
  max-width: 190px; object-fit: contain;
}
@media (max-width: 720px) { .brand-logo { max-width: 130px; } }

/* ===== Animated logo ===== */
/* The diamond mark gently pulses/shimmers; a hover spins it. The per-game
   logo image drifts subtly and lifts on hover. All motion is disabled under
   prefers-reduced-motion (handled by the global rule above). */
@keyframes ld-mark-pulse {
  0%, 100% { transform: rotate(0deg) scale(1); box-shadow: 0 0 0 rgba(0,0,0,0); }
  50%      { transform: rotate(0deg) scale(1.08); box-shadow: 0 0 14px var(--accent-line); }
}
@keyframes ld-mark-sheen {
  0%   { background-position: -140% 0; }
  60%, 100% { background-position: 240% 0; }
}
.brand-mark {
  position: relative; overflow: hidden;
  background-size: 220% 100%;
  background-image: linear-gradient(115deg, var(--accent) 0%, var(--r4) 45%, #ffffff 52%, var(--accent) 60%, var(--r4) 100%);
  animation: ld-mark-pulse 3.4s ease-in-out infinite, ld-mark-sheen 4.6s ease-in-out infinite;
  transition: transform 0.5s cubic-bezier(.2,.8,.2,1);
}
.brand:hover .brand-mark { transform: rotate(180deg) scale(1.1); }
@keyframes ld-logo-float {
  0%, 100% { transform: translateY(0); filter: drop-shadow(0 0 0 rgba(0,0,0,0)); }
  50%      { transform: translateY(-2px); filter: drop-shadow(0 3px 8px rgba(0,0,0,0.45)); }
}
.brand-logo { animation: ld-logo-float 4s ease-in-out infinite; transition: transform 0.35s ease; }
.brand:hover .brand-logo { transform: scale(1.05); }

/* ===== Footer preferences: theme + language switchers ===== */
.footer-prefs {
  display: flex; flex-wrap: wrap; gap: 1rem 1.4rem; align-items: center;
  justify-content: flex-end;
}
.pref { display: flex; align-items: center; gap: 0.6rem; }
.pref-label {
  font-family: var(--font-display); font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; font-size: 0.72rem; color: var(--muted);
}
.theme-dots { display: flex; gap: 0.5rem; }
.theme-dot {
  width: 26px; height: 26px; min-width: 26px; border-radius: 50%;
  border: 2px solid var(--line); background: var(--dyn, var(--accent));
  cursor: pointer; padding: 0; transition: transform 0.15s ease, border-color 0.15s ease;
}
.theme-dot:hover { transform: scale(1.15); }
.theme-dot.active { border-color: var(--text); box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--dyn, var(--accent)); }
.lang-select {
  appearance: none; -webkit-appearance: none;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 0.5rem 2rem 0.5rem 0.75rem; font: inherit; font-size: 0.85rem; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 55%, calc(100% - 10px) 55%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.lang-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ===== Rendering-perf: skip layout/paint for offscreen sections ===== */
/* The home page is only a few sections tall, and the 640px placeholder each one
   reserved before it scrolled in was the main reason the page looked full of
   gaps. The perf win there was negligible, so home is off this list now. */
.role-group, .upg-grid { content-visibility: auto; contain-intrinsic-size: auto 640px; }

/* ===== Extra mobile tuning (small phones) ===== */
@media (max-width: 860px) {
  .footer-prefs { gap: 1rem 1.4rem; }
  .theme-dot { width: 30px; height: 30px; min-width: 30px; } /* larger touch target */
  .lang-select { padding-top: 0.6rem; padding-bottom: 0.6rem; }
  .nav-links a { padding: 0.6rem 0.75rem; } /* comfortable tap size */

  /* Three posters side by side on a 390px screen would be three 115px slivers,
     and two-up plus a full-width orphan underneath is what produced the ragged
     175/175/358 row in the tester's screenshot. So on phones each game is its
     own full-width banner: same poster, same badges, three identical rows. It
     still owns the first screenful, which is the part that matters, and there
     is no odd one out to explain.

     Nothing here is a pinned variant. The band scrolls away now (see the note
     on .qnav above), so the phone layout has exactly one state and there is
     nothing to animate, overflow or snap. */
  .qnav-row { flex-wrap: wrap; gap: 0.5rem; }
  .qnav-tile {
    flex: 1 1 100%; min-height: 96px; padding: 0.7rem 0.8rem; border-radius: 12px;
  }
  /* Positive gap, not the old margin-right: -32px. That negative margin existed
     only to tuck the icon behind the title while the tile was collapsing; with
     no collapse it just overlapped the text. */
  .qnav-ic { width: 32px; height: 32px; border-radius: 8px; margin-right: 0.55rem; }
  .qnav-inner { padding: 0.7rem 1rem 0.85rem; }
  .qnav-label { margin-bottom: 0.45rem; }
  .qnav-more { gap: 0.35rem 0.9rem; margin-top: 0.6rem; }

  /* ---- the topbar has to fit inside the phone, not merely look like it does ----
     Measured at 360 / 390 / 414 the account chip was landing at L338 R426 on a
     390px screen: 36px of it hanging off the right edge, which is what put a
     horizontal scrollbar on the whole document and shifted the home page left
     so "OUR GAMES" read as "JR GAMES". The bar is a zero-sum flex row, so the
     fix is to spend fewer pixels on it rather than to clip the overflow. */
  .nav-inner { padding: 0 0.9rem; gap: 0.5rem; min-width: 0; }
  /* Let the wordmark be the thing that gives, since it is the one item on the
     bar that is decoration rather than a destination. */
  .brand { flex: 0 1 auto; min-width: 0; }
  .brand-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Both Discord buttons keep a word on phones. Stripping them back to bare
     marks is what made the bar unreadable in the first place: two Discord
     glyphs, one blue and one yellow, with nothing to say which was which.
     The width comes back from a shorter join label and tighter padding. */
  .acct-slot { margin-left: 0.25rem; }
  .acct-login { padding: 0 0.6rem; height: 38px; border-radius: 999px; gap: 0.35rem; }
  .acct-login span { font-size: 0.82rem; }
  .btn-discord { height: 38px; padding: 0 0.6rem; gap: 0.35rem; font-size: 0.8rem; }
  .bd-long { display: none; }
  .bd-short { display: inline; }
  .acct-chip { padding: 0.28rem 0.5rem; }
  .acct-name { max-width: 68px; }
}
@media (max-width: 560px) {
  /* The merged game cards carry badges and a name, so one per row on a phone.
     The small grid is still fine two-up. */
  .gcard-grid { grid-template-columns: 1fr; }
  .gcard-grid-small { grid-template-columns: 1fr 1fr; }
  .home-hero-inner { padding: 0.95rem 1rem 0.9rem; }
  .home-hero h1 { font-size: 1.18rem; }
  .home-hero-blurb { font-size: 0.79rem; margin-top: 0.3rem; }
  .home-credits { margin-top: 0.55rem; }
  .qnav-t { font-size: 0.92rem; }
  .qnav-s { font-size: 0.66rem; }
  .qnav-tile { min-height: 98px; }
  .home-body { padding: 1.2rem 1rem 2.6rem; }
  .home-body > .section + .section { margin-top: 1.8rem; }
  .home-cols { gap: 1.6rem; }
  h1 { font-size: 1.5rem; }
  .page-pad { padding-left: 1rem; padding-right: 1rem; }
  .footer-prefs { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .tool-grid { grid-template-columns: 1fr; }
  .db-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
}
@media (max-width: 400px) {
  .gcard-grid-small { grid-template-columns: 1fr; }
  .brand-name { font-size: 0.92rem; }
}
/* Touch devices: char tooltips can sit under a persistent tap; keep them from blocking */
@media (hover: none) {
  .char-tip { display: none !important; }
}

/* ===== Content-translation popup / progress / settings ===== */
.ct-pop {
  position: fixed; left: 50%; bottom: 18px; transform: translate(-50%, 140%);
  z-index: 120; max-width: min(560px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--accent-line); border-radius: 12px;
  padding: 0.7rem 0.9rem; box-shadow: 0 14px 40px rgba(0,0,0,0.5);
  opacity: 0; pointer-events: none; transition: transform 0.35s cubic-bezier(.2,.8,.2,1), opacity 0.35s ease;
}
.ct-pop.show { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.ct-pop-text { font-weight: 600; font-size: 0.92rem; }
.ct-pop-actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
.ct-btn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  border-radius: 8px; padding: 0.45rem 0.8rem; font: inherit; font-size: 0.85rem;
  font-weight: 600; cursor: pointer; white-space: nowrap;
}
.ct-btn:hover { border-color: var(--accent-line); }
.ct-btn-accent { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.ct-x {
  border: none; background: transparent; color: var(--muted);
  font-size: 0.95rem; cursor: pointer; padding: 0.2rem 0.35rem; line-height: 1;
}
.ct-x:hover { color: var(--text); }

.ct-badge {
  position: fixed; right: 16px; bottom: 16px; z-index: 115;
  background: var(--panel); color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 0.4rem 0.85rem; font-size: 0.8rem; font-weight: 600;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.ct-badge.show { opacity: 1; transform: translateY(0); }

.ct-switch { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; font-size: 0.85rem; }
.ct-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.ct-switch-track {
  position: relative; width: 38px; height: 22px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); transition: background 0.2s ease, border-color 0.2s ease;
}
.ct-switch-thumb {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--muted); transition: transform 0.2s ease, background 0.2s ease;
}
.ct-switch input:checked + .ct-switch-track { background: var(--accent-soft); border-color: var(--accent-line); }
.ct-switch input:checked + .ct-switch-track .ct-switch-thumb { transform: translateX(16px); background: var(--accent); }
.ct-switch input:focus-visible + .ct-switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 560px) {
  .ct-pop { left: 12px; right: 12px; transform: translateY(140%); max-width: none; }
  .ct-pop.show { transform: translateY(0); }
  .ct-pop-actions { margin-left: 0; width: 100%; }
  .ct-pop-actions .ct-btn { flex: 1; }
}

/* ===== Light mode (data-mode="light") — surfaces come from CSS vars set in
   applyTheme(); these rules fix the few places with hardcoded dark colors. */
html[data-mode="light"] #site-nav { background: rgba(255, 255, 255, 0.9); }
html[data-mode="light"] #site-nav.scrolled { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); }
html[data-mode="light"] .nav-links { background: rgba(255, 255, 255, 0.98); }
html[data-mode="light"] .nav-panel { background: #fff; }
html[data-mode="light"] .char-tip { background: rgba(255, 255, 255, 0.98); color: var(--text); }
html[data-mode="light"] .acc-body,
html[data-mode="light"] .role-key-panel ul,
html[data-mode="light"] .upg-blurb { color: var(--muted); }
html[data-mode="light"] .role-duration .role-label { background: #E9ECF4; }
html[data-mode="light"] .role-legend-dur { background: #E1E5EF; }
html[data-mode="light"] .home-hero::before,
html[data-mode="light"] .hub-hero::before {
  background:
    radial-gradient(900px 380px at 75% 0%, var(--accent-soft), transparent 60%),
    linear-gradient(rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.82));
}
html[data-mode="light"] .home-hero-blurb,
html[data-mode="light"] .hub-hero p { color: var(--muted); }

/* ===== Appearance (light/dark) segmented toggle ===== */
.mode-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.mode-btn {
  border: none; background: var(--panel-2); color: var(--muted);
  font: inherit; font-size: 0.82rem; font-weight: 600; padding: 0.42rem 0.85rem; cursor: pointer;
}
.mode-btn + .mode-btn { border-left: 1px solid var(--line); }
.mode-btn.active { background: var(--accent); color: #0B0C10; }

.more-settings-btn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  border-radius: 8px; padding: 0.5rem 0.9rem; font: inherit; font-size: 0.85rem;
  font-weight: 600; cursor: pointer;
}
.more-settings-btn:hover { border-color: var(--accent-line); color: var(--accent); }

/* ===== Full settings overlay (bottom sheet) ===== */
.settings-overlay {
  position: fixed; inset: 0; z-index: 130;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(0, 0, 0, 0.55); opacity: 0; pointer-events: none;
  transition: opacity 0.25s ease;
}
.settings-overlay.open { opacity: 1; pointer-events: auto; }
.settings-panel {
  width: 100%; max-width: 640px; max-height: 82vh; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px 16px 0 0; padding: 1.1rem 1.35rem 1.7rem;
  transform: translateY(100%); transition: transform 0.32s cubic-bezier(.2,.8,.2,1);
  box-shadow: 0 -18px 50px rgba(0, 0, 0, 0.5);
}
.settings-overlay.open .settings-panel { transform: none; }
.settings-grabber {
  width: 42px; height: 5px; border-radius: 999px; background: var(--line);
  margin: 0 auto 0.7rem; flex: none;
}
.settings-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.4rem; }
.settings-head h2 { font-size: 1.3rem; }
.settings-body { display: flex; flex-direction: column; gap: 1.15rem; padding-top: 0.6rem; }
.settings-body .pref { justify-content: space-between; gap: 1rem; }
.settings-body .pref .pref-label { font-size: 0.78rem; }
.settings-hint {
  text-align: center; color: var(--muted); font-size: 0.76rem;
  margin-top: 1.1rem; opacity: 0.8;
}

body.modal-open { overflow: hidden; }

/* ===== PWA "new version available" update banner ===== */
.sw-pop {
  position: fixed; left: 50%; top: calc(var(--topbar-h) + 12px);
  transform: translate(-50%, -170%); z-index: 125;
  display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  max-width: min(520px, calc(100vw - 24px));
  background: var(--panel); color: var(--text);
  border: 1px solid var(--accent-line); border-radius: 12px;
  padding: 0.6rem 0.9rem; box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
  opacity: 0; pointer-events: none;
  transition: transform 0.35s cubic-bezier(.2,.8,.2,1), opacity 0.35s ease;
}
.sw-pop.show { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.sw-pop.busy { opacity: 0.7; pointer-events: none; }
.sw-pop-text { font-weight: 600; font-size: 0.92rem; }
.sw-pop-actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
@media (max-width: 560px) {
  .sw-pop { left: 12px; right: 12px; transform: translateY(-170%); max-width: none; }
  .sw-pop.show { transform: translateY(0); }
  .sw-pop-actions { margin-left: 0; width: 100%; }
  .sw-pop-actions .ct-btn { flex: 1; }
}
/* ============================================================
   BUILDS — recommended-build blocks (Builds page + character pages)
   ============================================================ */
.build-tier-head {
  font-family: var(--font-display); font-size: 1.15rem; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent);
  margin: 1.6rem 0 0.6rem; padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--accent-line);
}
.build-block {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.1rem 1.15rem;
  margin-bottom: 1.1rem;
}
.build-head { display: flex; align-items: center; gap: 0.85rem; margin-bottom: 0.9rem; }
.build-portrait {
  width: 56px; height: 56px; min-width: 56px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2);
  background-size: cover; background-position: center top;
  display: flex; align-items: center; justify-content: center;
}
.build-name {
  font-family: var(--font-display); font-size: 1.35rem; font-weight: 700;
  color: var(--text); display: inline-block;
}
a.build-name:hover { color: var(--accent); text-decoration: none; }
.build-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.3rem; }
.build-tier, .build-type, .build-prop {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; padding: 0.15rem 0.5rem; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted);
}
.build-type-attack { color: #F3555A; border-color: rgba(243,85,90,0.5); }
.build-type-magic  { color: #55A8F0; border-color: rgba(85,168,240,0.5); }

.build-grid { display: grid; gap: 0.8rem; }
.build-grid-top { grid-template-columns: 1.4fr 1fr 0.8fr; }
.build-grid-bottom { grid-template-columns: 1fr 1fr 1.4fr; margin-top: 0.8rem; }
.build-sec {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 0.7rem 0.8rem;
}
.build-sec-head {
  font-family: var(--font-display); font-size: 0.82rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent);
  margin-bottom: 0.55rem;
}
.build-trans { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.build-node {
  position: relative; display: inline-flex; align-items: center;
  padding: 0.3rem 0.55rem; border-radius: 6px; font-size: 0.78rem;
  background: var(--panel); border: 1px solid var(--line); color: var(--muted);
}
.build-node-up { border-color: var(--accent); color: var(--text); box-shadow: 0 0 0 1px var(--accent-line) inset; }
.build-node-up-tag {
  font-size: 0.55rem; font-weight: 800; color: var(--bg); background: var(--accent);
  border-radius: 4px; padding: 0.05rem 0.25rem; margin-right: 0.35rem; letter-spacing: 0.02em;
}
.build-skills { list-style: none; display: flex; flex-direction: column; gap: 0.25rem; }
.build-skills li { display: flex; align-items: center; gap: 0.45rem; font-size: 0.82rem; }
.build-skills li.off { color: var(--muted); opacity: 0.65; }
.build-skill-mark {
  width: 18px; height: 18px; min-width: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.7rem; font-weight: 700;
}
.build-skills li.on .build-skill-mark { background: rgba(90,217,138,0.18); color: #5AD98A; border: 1px solid rgba(90,217,138,0.5); }
.build-skills li.off .build-skill-mark { background: var(--panel); color: var(--muted); border: 1px solid var(--line); }
.build-pots { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.build-pot {
  flex: 1; min-width: 54px; text-align: center; font-size: 0.72rem; font-weight: 700;
  padding: 0.35rem 0.3rem; border-radius: 6px; border: 1px dashed var(--line);
  color: var(--muted); background: var(--panel);
}
.build-pot.on { border-style: solid; border-color: var(--accent-line); color: var(--accent); background: var(--accent-soft); }

.gear-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0.7rem; }
.gear-card { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 0.65rem 0.7rem; }
.gear-card-name {
  font-family: var(--font-display); font-weight: 700; font-size: 0.92rem;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--text);
  margin-bottom: 0.5rem; padding-bottom: 0.35rem; border-bottom: 1px solid var(--line);
}
.gear-slots { display: flex; flex-direction: column; gap: 0.25rem; margin-bottom: 0.55rem; }
.gear-slot { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; font-size: 0.8rem; }
.gear-slot-name { color: var(--muted); }
.gear-slot-main { font-weight: 600; color: var(--text); text-align: right; }
.gear-subs { margin-bottom: 0.5rem; }
.gear-subs-label {
  display: block; font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--muted); margin-bottom: 0.3rem;
}
.gear-subs ol { list-style: none; display: flex; flex-direction: column; gap: 0.2rem; }
.gear-subs li { display: flex; align-items: center; gap: 0.45rem; font-size: 0.8rem; }
.gear-sub-rank {
  width: 16px; height: 16px; min-width: 16px; border-radius: 4px; font-size: 0.62rem;
  font-weight: 700; display: inline-flex; align-items: center; justify-content: center;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.gear-set {
  font-size: 0.78rem; font-weight: 700; color: #F0C04E;
  background: rgba(240,192,78,0.08); border: 1px solid rgba(240,192,78,0.35);
  border-radius: 6px; padding: 0.35rem 0.5rem; margin-bottom: 0.5rem;
}
.gear-notes { font-size: 0.8rem; color: var(--muted); margin: 0; }
.gear-notes strong { color: var(--text); }

.build-dedeq .dedeq-name {
  display: inline-block; font-weight: 700; color: var(--text); margin-bottom: 0.35rem;
}
.build-dedeq ul { list-style: none; display: flex; flex-direction: column; gap: 0.2rem; }
.build-dedeq li { font-size: 0.8rem; color: var(--muted); }
.build-usage { display: flex; flex-direction: column; gap: 0.6rem; }
.usage-label {
  display: block; font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--muted); margin-bottom: 0.3rem;
}
.usage-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.usage-chip {
  font-size: 0.72rem; padding: 0.2rem 0.5rem; border-radius: 6px;
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.build-blurb { font-size: 0.84rem; color: var(--muted); margin: 0; line-height: 1.55; }

@media (max-width: 900px) {
  .build-grid-top, .build-grid-bottom { grid-template-columns: 1fr; }
}

/* ============================================================
   NEW MODULES: updates timeline, skill kits, pets, gear, rings
   ============================================================ */

/* --- shared section header with a trailing link --- */
.sec-head-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.sec-head-row .sec-head { margin-bottom: 0; }
.sec-head-link {
  font-family: var(--font-display); font-weight: 600; font-size: 0.85rem;
  color: var(--accent); text-decoration: none; white-space: nowrap;
}
.sec-head-link:hover { text-decoration: underline; }

/* --- update chips / tags (shared by hub + timeline) --- */
.upd-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.35rem; }
.upd-chip {
  font-size: 0.74rem; padding: 0.2rem 0.5rem; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.upd-chip-unit { border-color: var(--accent-line); background: var(--accent-soft); color: var(--text); font-weight: 600; }
.upd-chip-costume { color: var(--muted); }

/* --- unit chips with a face on them ---
   A unit name in an update file is a string, and a string is the one thing a
   reader has to stop and decode. The portrait is deliberately small: an update
   row is a headline, and full-size art would turn this block back into the
   half-screen wall the collapsed peek rows were built to replace. */
.upd-chips-art { gap: 0.35rem; }
.upd-chip-art {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.2rem 0.55rem 0.2rem 0.22rem;
  text-decoration: none; transition: border-color 0.16s ease, transform 0.16s ease;
}
a.upd-chip-art:hover, a.upd-chip-art:focus-visible {
  border-color: var(--accent); transform: translateY(-1px); text-decoration: none;
}
/* Portraits are framed art, not faces on a transparent background, so the crop
   is top-anchored: center/cover on a full-body portrait shows a torso. */
.upd-chip-ph {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 5px;
  background: var(--panel) center 12% / cover no-repeat;
  border: 1px solid var(--line);
  display: grid; place-items: center; overflow: hidden;
}
.upd-chip-ph-tx { font-family: var(--font-display); font-weight: 800; font-size: 0.7rem; color: var(--muted); }
.upd-chip-ph.has-img .upd-chip-ph-tx { display: none; }
.upd-chip-nm { line-height: 1.1; }

/* --- the game icon on an update row ---
   Same asset as the topbar chips, so "which game is this" is answered by the
   same picture in both places instead of by reading the subtitle. */
.upd-gic {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 6px;
  background: var(--panel-2) center/cover no-repeat;
  border: 1px solid var(--line);
  display: grid; place-items: center; overflow: hidden;
}
.upd-gic-ph { font-family: var(--font-display); font-weight: 800; font-size: 0.72rem; color: var(--muted); }
.upd-gic.has-img .upd-gic-ph { display: none; }

/* --- update filters ---
   Buttons rather than <select>s: on a phone a select opens a full system sheet
   for a three-item choice, and these double as a legend that says which games
   are even in the list. aria-pressed is what makes them announce as toggles. */
.upd-filters {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem;
  margin: 0 0 0.7rem;
}
.upd-fgroup { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.upd-fgroup-type { margin-left: auto; }
.upd-f {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font: inherit; font-size: 0.78rem; font-weight: 600;
  padding: 0.28rem 0.6rem 0.28rem 0.35rem; border-radius: 999px;
  background: var(--panel); color: var(--muted);
  border: 1px solid var(--line); cursor: pointer;
  transition: border-color 0.16s ease, color 0.16s ease, background 0.16s ease;
}
.upd-f:not(:has(.upd-gic)) { padding-left: 0.7rem; }
.upd-f:hover { border-color: var(--accent); color: var(--text); }
.upd-f:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.upd-f.is-on {
  background: var(--accent-soft); border-color: var(--accent-line); color: var(--text);
}
.upd-f .upd-gic { width: 22px; height: 22px; border-radius: 5px; }
.upd-off { display: none; }
.upd-empty { margin-top: 0.8rem; font-size: 0.85rem; color: var(--muted); text-align: center; }
.upd-tag-major, .upd-tag-banner {
  display: inline-block; font-family: var(--font-display); font-weight: 700;
  font-size: 0.66rem; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 0.14rem 0.45rem; border-radius: 5px;
}
.upd-tag-major { background: rgba(245,185,66,0.14); color: #F5B942; border: 1px solid rgba(245,185,66,0.4); }
.upd-tag-banner { background: rgba(94,217,138,0.12); color: #5AD98A; border: 1px solid rgba(94,217,138,0.35); }
.upd-badge {
  display: inline-block; font-family: var(--font-display); font-weight: 700;
  font-size: 0.68rem; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 0.16rem 0.5rem; border-radius: 5px; margin-bottom: 0.35rem;
  background: rgba(162,120,255,0.14); color: #B79BFF; border: 1px solid rgba(162,120,255,0.4);
}
.upd-event { font-family: var(--font-display); font-size: 1.02rem; margin: 0.2rem 0 0.4rem; color: var(--text); }
.upd-date { font-family: var(--font-display); font-weight: 700; color: var(--text); }
.upd-list { list-style: none; display: flex; flex-direction: column; gap: 0.22rem; margin-top: 0.3rem; }
.upd-list li { position: relative; padding-left: 0.9rem; font-size: 0.84rem; color: var(--muted); line-height: 1.45; }
.upd-list li::before { content: "▹"; position: absolute; left: 0; color: var(--accent); }
.upd-more-li { color: var(--accent) !important; font-weight: 600; }
.upd-more-li::before { content: "" !important; }
.upd-notes-link { display: inline-block; margin-top: 0.5rem; font-size: 0.82rem; font-weight: 600; color: var(--accent); text-decoration: none; }
.upd-notes-link:hover { text-decoration: underline; }
.upd-line { font-size: 0.85rem; color: var(--muted); margin-top: 0.3rem; }
.upd-line strong { color: var(--text); }

/* --- latest updates peek (game hub, sits at the very top) ---------------
   Three collapsed <details> rows. The point of this block is to answer "did
   anything change since I was last here" in one glance, so a closed row costs
   a single line and the detail is one click away. Native <details> keeps it
   CSP-safe, keyboard reachable, and findable with browser find-in-page. */
.upd-peek-sec { margin-top: 0; margin-bottom: 1.6rem; }
.upd-peek-sec .sec-head-row { margin-bottom: 0.7rem; }
.upd-peek {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
}
.upd-peek-row + .upd-peek-row { border-top: 1px solid var(--line); }
.upd-peek-sum {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.85rem; cursor: pointer; list-style: none;
  user-select: none; transition: background 0.16s ease;
}
.upd-peek-sum::-webkit-details-marker { display: none; }
.upd-peek-sum:hover { background: var(--panel-2); }
.upd-peek-sum:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.upd-peek-txt {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap;
}
.upd-peek-title {
  font-family: var(--font-display); font-size: 0.9rem; font-weight: 700;
  color: var(--text); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.upd-peek-sub { font-size: 0.74rem; color: var(--muted); line-height: 1.3; }
.upd-peek-date { flex: 0 0 auto; font-size: 0.74rem; color: var(--muted); }
.upd-peek-row[open] > .upd-peek-sum { background: var(--panel-2); border-bottom: 1px solid var(--line); }
.upd-peek-row[open] > .upd-peek-sum .dacc-chev { transform: rotate(-135deg) translate(-2px, -2px); border-color: var(--accent); }
.upd-peek-body { padding: 0.75rem 0.9rem 0.9rem; }
.upd-peek-body > .upd-block:first-child { margin-top: 0; }
.upd-peek-body .upd-list { margin-top: 0; }
@media (max-width: 560px) {
  .upd-peek-sum { padding: 0.5rem 0.65rem; gap: 0.45rem; }
  .upd-peek-title { font-size: 0.84rem; }
  .upd-peek-sub { display: none; }
  .upd-peek-date { font-size: 0.68rem; }
  .upd-peek-body { padding: 0.65rem 0.7rem 0.8rem; }
}

/* --- full timeline --- */
.upd-timeline { display: flex; flex-direction: column; gap: 0; position: relative; }
.upd-row {
  display: grid; grid-template-columns: 150px 1fr; gap: 1.2rem;
  padding: 1.1rem 0; border-bottom: 1px solid var(--line); position: relative;
}
.upd-row-side { display: flex; flex-direction: column; gap: 0.35rem; align-items: flex-start; }
.upd-row-date { font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; color: var(--text); }
.upd-row-day { font-size: 0.72rem; color: var(--muted); }
.upd-row-major .upd-row-date { color: #F5B942; }
.upd-row-body { min-width: 0; }
.upd-block { margin-bottom: 0.6rem; }
.upd-block:last-child { margin-bottom: 0; }
.upd-block-label {
  display: block; font-size: 0.66rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted); margin-bottom: 0.15rem;
}
@media (max-width: 640px) {
  .upd-row { grid-template-columns: 1fr; gap: 0.5rem; }
  .upd-row-side { flex-direction: row; align-items: center; flex-wrap: wrap; }
}

/* --- skill kit (character page) --- */
.kit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.9rem; }
.kit-col { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 0.9rem 1rem; }
.kit-col-head {
  font-family: var(--font-display); font-size: 0.92rem; color: var(--accent);
  margin-bottom: 0.5rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--line);
}
.kit-lines { list-style: none; display: flex; flex-direction: column; gap: 0.3rem; }
.kit-lines li { font-size: 0.82rem; color: var(--text); line-height: 1.45; padding-left: 0.9rem; position: relative; }
.kit-lines li::before { content: "•"; position: absolute; left: 0.15rem; color: var(--accent); }
.kit-sub { margin-top: 0.6rem; padding-top: 0.5rem; border-top: 1px dashed var(--line); }
.kit-sub-label { display: block; font-size: 0.64rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.25rem; }
.kit-sub-enh .kit-sub-label { color: #5AD98A; }
.kit-sub-tr .kit-sub-label { color: #B79BFF; }
.kit-sub ul { list-style: none; display: flex; flex-direction: column; gap: 0.2rem; }
.kit-sub li { font-size: 0.78rem; color: var(--muted); line-height: 1.4; }
.kit-effects { margin-top: 0.9rem; background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 0.9rem 1rem; }
.kit-effects dl { display: grid; grid-template-columns: minmax(150px, auto) 1fr; gap: 0.3rem 1rem; }
.kit-effects dt { font-weight: 700; font-size: 0.82rem; color: var(--text); }
.kit-effects dd { font-size: 0.82rem; color: var(--muted); }
@media (max-width: 560px) { .kit-effects dl { grid-template-columns: 1fr; gap: 0.1rem 0; } .kit-effects dd { margin-bottom: 0.4rem; } }

/* ============================================================
   UNIT KIT — the per-unit datasheet on a character page.
   Three stacked sections: "at a glance" (identity + a radar of
   the six core stats), "skills and levels" (one card per skill
   with every level inside it), and the shared progression
   paths. The wiki this mirrors uses tabs; stacking instead means
   nothing is hidden behind a click and the whole page prints,
   searches with ctrl-F, and works with no JS beyond render.
   ============================================================ */
.ukit-sub { color: var(--muted); font-size: 0.86rem; margin: -0.5rem 0 0.9rem; max-width: 70ch; }

.ukit-glance-grid { display: grid; grid-template-columns: minmax(240px, 0.85fr) 1.15fr; gap: 0.9rem; align-items: start; }
.ukit-card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.1rem;
}
.ukit-card-head {
  font-family: var(--font-display); font-size: 0.98rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--text);
  margin-bottom: 0.7rem; display: flex; align-items: baseline;
  justify-content: space-between; gap: 0.6rem;
}
.ukit-card-note { font-family: var(--font-body); font-size: 0.7rem; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--muted); }
.ukit-note { font-size: 0.78rem; color: var(--muted); line-height: 1.5; margin-bottom: 0.7rem; }

.ukit-dl { display: flex; flex-direction: column; }
.ukit-row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: 0.45rem 0; border-bottom: 1px dashed var(--line); }
.ukit-row:last-child { border-bottom: 0; }
.ukit-row dt { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.ukit-row dd { font-size: 0.88rem; font-weight: 600; color: var(--text); text-align: right; }

/* Base stat bars. Each row is: name, a track showing where the unit sits in the
   roster's range for that stat, the raw number, and the gap to the average unit
   of the same fighting type. Widths are set from JS (the CSP forbids inline
   style attributes) so they animate in when the panel opens. */
.ukit-bars { display: flex; flex-direction: column; gap: 0.5rem; }
.ukit-bar { display: grid; grid-template-columns: 46px 1fr auto 52px; gap: 0.6rem; align-items: center; }
.ukit-bar-k { font-size: 0.64rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.ukit-bar-track {
  position: relative; height: 9px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); overflow: hidden;
}
.ukit-bar-fill {
  position: absolute; inset: 0 auto 0 0; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, rgba(var(--rc-glow, 46, 155, 240), 0.55), var(--rc, var(--accent)));
  transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
/* The peer tick sits above the fill, so it stays visible whether the unit is
   above or below its type's average. */
.ukit-bar-peer {
  position: absolute; top: -2px; bottom: -2px; left: 0; width: 2px;
  background: var(--text); opacity: 0.55; transition: left 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.ukit-bar-v { font-family: var(--font-display); font-size: 0.86rem; font-weight: 700; color: var(--text); text-align: right; }
.ukit-bar-d { font-size: 0.7rem; font-weight: 700; text-align: right; }
.ukit-bar-d.up { color: #5AD98A; }
.ukit-bar-d.dn { color: #E8737D; }
.ukit-bar-legend { font-size: 0.72rem; color: var(--muted); line-height: 1.5; margin-top: 0.7rem; }
/* stats that never vary across the roster: listed once instead of six full bars */
.ukit-flat {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem;
  margin-top: 0.8rem; padding-top: 0.7rem; border-top: 1px solid var(--line);
}
.ukit-flat-c {
  font-size: 0.74rem; color: var(--muted); padding: 0.18rem 0.5rem; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.ukit-flat-c b { color: var(--text); font-weight: 700; margin-right: 0.15rem; }
.ukit-flat-n { font-size: 0.7rem; color: var(--muted); font-style: italic; margin-left: auto; }

.ukit-profile { display: grid; grid-template-columns: minmax(180px, 1fr) minmax(150px, 0.9fr); gap: 0.9rem; align-items: center; }
.ukit-radar { width: 100%; max-width: 260px; height: auto; display: block; margin: 0 auto; overflow: visible; }
.ukit-ring { fill: none; stroke: var(--line); stroke-width: 1; }
.ukit-spoke { stroke: var(--line); stroke-width: 1; }
.ukit-axis { fill: var(--muted); font-size: 9px; font-weight: 700; letter-spacing: 0.05em; font-family: var(--font-body); }
.ukit-peer { fill: none; stroke: var(--muted); stroke-width: 1.2; stroke-dasharray: 4 3; opacity: 0.8; }
.ukit-shape {
  fill: rgba(var(--rc-glow, 46, 155, 240), 0.22);
  stroke: var(--rc, var(--accent)); stroke-width: 2; stroke-linejoin: round;
}

.ukit-stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.4rem; }
.ukit-stat {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 0.45rem 0.6rem; display: flex; flex-direction: column; gap: 0.1rem;
}
.ukit-stat-k { font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); }
.ukit-stat-v { font-family: var(--font-display); font-size: 1.05rem; font-weight: 700; color: var(--text); line-height: 1.1; }

/* One card per skill. The left rail is coloured by skill kind so a page of
   six cards separates into Ultimates, Actives and Passives at a glance. */
/* align-items: start lets each card end where its text ends. Stretching them to
   a shared row height leaves a passive with three short lines sitting in a tall
   empty box next to an Ultimate with four long ones. */
.ukit-skill-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 0.9rem; align-items: start; }
.ukit-skill {
  background: var(--panel); border: 1px solid var(--line); border-left: 3px solid var(--uk, var(--accent));
  border-radius: var(--radius); padding: 0.9rem 1rem; transition: border-color 0.18s ease, transform 0.18s ease;
}
.ukit-skill:hover { transform: translateY(-2px); border-color: var(--uk, var(--accent)); border-left-color: var(--uk, var(--accent)); }
.ukit-skill.k-ult { --uk: #F7C64B; }
.ukit-skill.k-act { --uk: #47A6F2; }
.ukit-skill.k-pas { --uk: #5AD98A; }

.ukit-skill-head { display: flex; align-items: flex-start; gap: 0.65rem; padding-bottom: 0.6rem; border-bottom: 1px solid var(--line); margin-bottom: 0.6rem; }
.ukit-skill-ic {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center; font-size: 0.9rem;
  color: var(--uk, var(--accent)); background: var(--panel-2); border: 1px solid var(--uk, var(--line));
}
.ukit-skill-id { flex: 1 1 auto; min-width: 0; }
.ukit-skill-id h4 { font-family: var(--font-display); font-size: 1.02rem; font-weight: 700; color: var(--text); line-height: 1.25; }
.ukit-badges { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.25rem; }
.ukit-badge {
  font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 0.1rem 0.5rem;
}
.ukit-badge-kind { color: var(--uk, var(--accent)); border-color: var(--uk, var(--line)); }
.ukit-cd {
  flex: 0 0 auto; min-width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--font-display);
  font-size: 0.8rem; font-weight: 700; color: var(--text);
  background: var(--panel-2); border: 2px solid var(--uk, var(--line));
}

.ukit-levels { display: flex; flex-direction: column; gap: 0.4rem; }
.ukit-lv { display: grid; grid-template-columns: 44px 1fr; gap: 0.6rem; align-items: start; }
.ukit-lv + .ukit-lv { padding-top: 0.4rem; border-top: 1px dashed var(--line); }
.ukit-lv-n {
  font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--uk, var(--accent)); background: var(--panel-2); border-radius: 6px;
  padding: 0.15rem 0.3rem; text-align: center; margin-top: 0.12rem;
}
.ukit-lv p { font-size: 0.82rem; color: var(--muted); line-height: 1.5; }
/* Only the top level is full strength - the earlier rows are there for players
   still levelling, so they sit back a step and let the final row lead. */
.ukit-lv:last-child p { color: var(--text); }

.ukit-prog-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 0.9rem; align-items: start; }
.ukit-nodes { list-style: none; display: flex; flex-direction: column; max-height: 420px; overflow-y: auto; }
.ukit-nodes li { display: grid; grid-template-columns: 42px 1fr; gap: 0.6rem; align-items: baseline; padding: 0.35rem 0; border-bottom: 1px dashed var(--line); font-size: 0.82rem; color: var(--muted); }
.ukit-nodes li:last-child { border-bottom: 0; }
.ukit-node-n { font-family: var(--font-display); font-size: 0.75rem; font-weight: 700; color: var(--accent); text-align: right; }

@media (max-width: 900px) {
  .ukit-glance-grid { grid-template-columns: 1fr; }
  .ukit-profile { grid-template-columns: 1fr; }
  .ukit-stat-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 560px) {
  .ukit-skill-list { grid-template-columns: 1fr; }
  .ukit-stat-grid { grid-template-columns: repeat(2, 1fr); }
  .ukit-lv { grid-template-columns: 38px 1fr; gap: 0.45rem; }
  .ukit-cd { min-width: 38px; height: 38px; font-size: 0.72rem; }
}
@media (prefers-reduced-motion: reduce) { .ukit-skill:hover { transform: none; } }

/* ============================================================
   ACCORDION SECTIONS (character pages)
   Native <details>/<summary>. No JS widget, no inline handlers
   (the CSP forbids them), and the browser hands us keyboard
   support and find-in-page expansion for nothing. A full unit
   datasheet runs several screens tall, so every panel starts
   closed and the page opens as a short menu of its own contents.
   ============================================================ */
.dacc-stack { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1.1rem; }
.dacc {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  transition: border-color 0.18s ease;
}
.dacc[open] { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.dacc-sum {
  display: flex; align-items: center; gap: 0.8rem;
  padding: 0.85rem 1.1rem; cursor: pointer; list-style: none;
  user-select: none; transition: background 0.18s ease;
}
.dacc-sum::-webkit-details-marker { display: none; }
.dacc-sum:hover { background: var(--panel-2); }
.dacc-sum:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dacc-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.dacc-t {
  font-family: var(--font-display); font-size: 1rem; font-weight: 700;
  color: var(--text); letter-spacing: 0.02em; line-height: 1.25;
}
.dacc-s { font-size: 0.76rem; color: var(--muted); line-height: 1.45; }
.dacc-note {
  flex: 0 0 auto; font-size: 0.66rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 0.15rem 0.55rem;
}
.dacc-chev {
  flex: 0 0 auto; width: 9px; height: 9px; border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted); transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.2s ease, border-color 0.18s ease;
}
.dacc[open] > .dacc-sum .dacc-chev { transform: rotate(-135deg) translate(-2px, -2px); border-color: var(--accent); }
.dacc[open] > .dacc-sum { border-bottom: 1px solid var(--line); }
.dacc-body { padding: 1rem 1.1rem 1.15rem; }
/* Sections written for the old stacked layout brought their own panel chrome
   with them; inside an accordion the accordion is the panel. */
.dacc-body > .section { background: none; border: 0; padding: 0; margin: 0; }
.dacc-body > p { color: var(--muted); line-height: 1.65; }
@media (prefers-reduced-motion: reduce) {
  .dacc-chev, .ukit-bar-fill, .ukit-bar-peer { transition: none; }
}
@media (max-width: 560px) {
  .dacc-sum { padding: 0.75rem 0.85rem; gap: 0.55rem; }
  .dacc-body { padding: 0.85rem 0.85rem 1rem; }
  .dacc-note { display: none; }
  .ukit-bar { grid-template-columns: 40px 1fr auto; }
  .ukit-bar-d { display: none; }
}

/* --- rarity accents (pets + rings) --- */
.pet-legendary { --rar: #F5B942; }
.pet-rare { --rar: #A278FF; }
.pet-uncommon { --rar: #5AD98A; }
.pet-common { --rar: #9CA8C8; }

/* --- pets --- */
.pet-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 0.9rem; }
.pet-card { background: var(--panel); border: 1px solid var(--line); border-left: 3px solid var(--rar, var(--line)); border-radius: var(--radius); padding: 0.9rem 1rem; }
.pet-card-head { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.6rem; }
.pet-portrait { width: 52px; height: 52px; min-width: 52px; border-radius: 10px; }
.pet-name { display: block; font-family: var(--font-display); font-weight: 700; font-size: 1rem; color: var(--text); }
.pet-rarity { font-size: 0.72rem; font-weight: 700; color: var(--rar, var(--muted)); text-transform: uppercase; letter-spacing: 0.03em; }
.pet-passives { display: flex; flex-direction: column; gap: 0.5rem; }
.pet-passive { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 0.5rem 0.6rem; }
.pet-passive-name { display: block; font-weight: 700; font-size: 0.82rem; color: var(--accent); margin-bottom: 0.1rem; }
.pet-passive-base { display: block; font-size: 0.8rem; color: var(--text); line-height: 1.4; }
.pet-passive-enh { display: block; font-size: 0.72rem; color: var(--muted); margin-top: 0.2rem; }

/* --- gear sets --- */
.gearset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.9rem; }
.gearset-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 0.9rem 1rem; }
.gearset-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.6rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--line); }
.gearset-name { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; color: var(--text); }
.gearset-role { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); padding: 0.14rem 0.45rem; border-radius: 5px; }
.gearset-bonus { display: flex; gap: 0.6rem; align-items: baseline; font-size: 0.84rem; color: var(--text); margin-bottom: 0.35rem; line-height: 1.45; }
.gearset-bonus:last-child { margin-bottom: 0; }
.gearset-pc { font-family: var(--font-display); font-weight: 700; font-size: 0.72rem; color: var(--accent); min-width: 56px; }

/* --- stat tables --- */
.stat-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.stat-table { border-collapse: collapse; width: 100%; min-width: 420px; font-size: 0.82rem; }
.stat-table th, .stat-table td { padding: 0.5rem 0.7rem; text-align: left; border-bottom: 1px solid var(--line); }
.stat-table thead th { background: var(--panel-2); color: var(--accent); font-family: var(--font-display); font-weight: 700; position: sticky; top: 0; }
.stat-table tbody th { color: var(--text); font-weight: 600; background: var(--panel); }
.stat-table tbody td { color: var(--muted); }
.stat-table tbody tr:last-child th, .stat-table tbody tr:last-child td { border-bottom: 0; }

/* --- rings --- */
.ring-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.8rem; }
.ring-card { background: var(--panel); border: 1px solid var(--line); border-left: 3px solid var(--rar, var(--line)); border-radius: var(--radius); padding: 0.8rem 1rem; }
.ring-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.35rem; }
.ring-name { font-family: var(--font-display); font-weight: 700; font-size: 0.96rem; color: var(--text); }
.ring-rarity { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--rar, var(--muted)); }
.ring-effect { font-size: 0.82rem; color: var(--muted); line-height: 1.5; margin: 0; }

/* ============================================================
   RESPONSIVE FALLBACK: older tablet browsers (e.g. older Samsung
   Internet) that don't support `aspect-ratio`. Without this, cards
   whose children are all absolutely/flex-positioned collapse to
   zero height and appear to vanish. The padding-hack reserves the
   correct height so the cards stay visible.
   ============================================================ */
@supports not (aspect-ratio: 1 / 1) {
  .gcard { height: 0; padding-bottom: 43.75%; }        /* 16:7 */
  .db-portrait { height: 0; padding-bottom: 100%; }     /* 1:1  */
  .tb-portrait { height: 84px; }                        /* fixed 84px square */
  .pet-portrait { height: 52px; }
}

/* ============================================================
   CHARACTER BANNER BACKGROUND
   When a character has art in assets/<game>/characterbanners/,
   it is loaded into the shared site background layer and given a
   slightly stronger-but-still-transparent wallpaper treatment,
   anchored toward the top so the character reads behind the page.
   ============================================================ */
.char-banner-bg .site-bg-layer { background-position: center 6%; }
.char-banner-bg .site-bg-layer.show { opacity: 0.5; }
html[data-mode="light"] .char-banner-bg .site-bg-layer.show { opacity: 0.4; }

/* ============================================================
   UPCOMING GAMES TRACKER — overhauled
   ============================================================ */
.upg-hero {
  position: relative; overflow: hidden; border-bottom: 1px solid var(--line);
  background:
    radial-gradient(1100px 340px at 20% -10%, var(--accent-soft), transparent 60%),
    radial-gradient(900px 300px at 90% 0%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%),
    var(--panel-2);
  padding: 2.6rem 1.4rem 2.2rem;
}
.upg-hero-inner { max-width: 1400px; margin: 0 auto; }
.upg-hero h1 { font-size: clamp(1.7rem, 3.6vw, 2.6rem); }
.upg-hero p { color: var(--muted); margin-top: 0.5rem; max-width: 640px; }

/* ---- toolbar ---- */
.upg-toolbar { margin: 1.2rem 0 1.4rem; display: flex; flex-direction: column; gap: 0.8rem; }
.upg-search { width: 100%; margin: 0; display: block; }
.upg-filter-row { display: flex; flex-wrap: wrap; gap: 0.8rem; align-items: center; justify-content: space-between; }
.upg-pill-group { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.upg-fpill {
  display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  border-radius: 999px; padding: 0.34rem 0.7rem; font-size: 0.82rem; font-weight: 600;
  transition: border-color .15s, color .15s, background .15s;
}
.upg-fpill svg { width: 15px; height: 15px; fill: currentColor; }
.upg-fpill:hover { color: var(--text); border-color: var(--accent-line); }
.upg-fpill.active { color: #fff; background: var(--accent); border-color: var(--accent); }
html[data-mode="light"] .upg-fpill.active { color: #10121a; }
.upg-selects { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: flex-end; }
.upg-sel { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); font-weight: 700; }
.upg-sel select {
  font-family: var(--font-body); font-size: 0.84rem; font-weight: 600; color: var(--text);
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 0.4rem 0.6rem; cursor: pointer;
}
.upg-reset {
  align-self: flex-end; cursor: pointer; border: 1px solid var(--line); background: var(--panel-2);
  color: var(--muted); border-radius: 8px; padding: 0.45rem 0.8rem; font-size: 0.82rem; font-weight: 600;
}
.upg-reset:hover { color: var(--text); border-color: var(--accent-line); }

/* ---- recently released ticker ---- */
.upg-recent-hint { font-size: 0.78rem; color: var(--muted); }
.upg-ticker { overflow-x: auto; padding-bottom: 0.3rem; scrollbar-width: thin; }
.upg-ticker-track { display: flex; gap: 0.7rem; min-width: min-content; }
.upg-tick {
  display: flex; align-items: center; gap: 0.6rem; cursor: pointer; text-align: left;
  border: 1px solid var(--line); background: var(--panel); border-radius: 12px;
  padding: 0.55rem 0.9rem 0.55rem 0.55rem; min-width: 220px; white-space: nowrap;
  transition: border-color .15s, transform .15s;
}
.upg-tick:hover { border-color: var(--accent-line); transform: translateY(-2px); }
.upg-tick-txt { display: flex; flex-direction: column; line-height: 1.25; }
.upg-tick-txt strong { font-size: 0.9rem; color: var(--text); }
.upg-tick-txt span { font-size: 0.72rem; color: #7FD98F; }

/* ---- cards ---- */
.upg-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 0.9rem; }
.upg-card {
  display: flex; flex-direction: column; cursor: pointer; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.upg-card:hover, .upg-card:focus-visible {
  transform: translateY(-4px); border-color: var(--accent-line);
  box-shadow: 0 14px 34px rgba(0,0,0,0.45); outline: none;
}
.upg-banner {
  position: relative; height: 96px; display: block;
  background-color: var(--panel-2); background-size: cover; background-position: center;
}
.upg-banner:not(.has-img) {
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--dyn) 60%, #0c0e14) 0%,
      color-mix(in srgb, var(--dyn) 22%, #0c0e14) 70%);
}
.upg-banner::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,9,13,0.05) 40%, rgba(8,9,13,0.72) 100%);
}
.upg-tag {
  position: absolute; top: 0.6rem; z-index: 1;
  font-family: var(--font-display); font-weight: 800; font-size: 0.64rem;
  letter-spacing: 0.06em; text-transform: uppercase; padding: 0.24rem 0.55rem; border-radius: 999px;
  background: rgba(255,255,255,0.92); color: #14141c; box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
.upg-tag-status { right: 0.6rem; }
.upg-tag-released, .upg-tag-soon { left: 0.6rem; }
.upg-tag-quarter, .upg-tag-sched, .upg-tag-tba { left: 0.6rem; }
.upg-tag-released { background: #7FD98F; color: #08110a; }
.upg-tag-soon { background: #F5B942; color: #201700; }
.upg-tag-quarter { background: #7FB0F0; color: #06101f; }
/* status tag colors */
.upg-status-rel { background: #7FD98F; color: #08110a; }
.upg-status-prereg { background: #F5B942; color: #201700; }
.upg-status-dev { background: #8CA0C8; color: #0a0e18; }
.upg-status-beta { background: #B79BFF; color: #140a24; }
.upg-status-test { background: #6FD0D8; color: #041416; }
.upg-status-ann { background: #C3C9D8; color: #12141c; }
.upg-status-soon { background: #F0A24E; color: #201200; }

/* ============================================================
   Hype system (upcoming games) — meter, POPULAR tag, rank, buttons
   ============================================================ */
/* Tag rows pinned to the banner corners so tags never overlap. */
.upg-tagrow { position: absolute; top: 0.6rem; z-index: 2; display: flex; gap: 0.4rem; align-items: flex-start; flex-wrap: wrap; max-width: calc(100% - 1.2rem); }
.upg-tagrow-l { left: 0.6rem; }
.upg-tagrow-r { right: 0.6rem; flex-direction: column; align-items: flex-end; }
.upg-tagrow .upg-tag { position: static; top: auto; left: auto; right: auto; }
.upg-rank { position: static; }
.upg-tag-popular {
  color: #201200;
  background: linear-gradient(90deg, #F5B942, #F0A24E, #F5B942);
  background-size: 200% 100%;
  animation: hypePopGlow 2.2s ease-in-out infinite, hypePopShift 3s linear infinite;
}
@keyframes hypePopGlow {
  0%, 100% { box-shadow: 0 2px 8px rgba(0,0,0,0.3); transform: scale(1); }
  50%      { box-shadow: 0 0 14px rgba(245,185,66,0.75); transform: scale(1.06); }
}
@keyframes hypePopShift { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } }

/* Rank badge (#1, #2 ...) in the banner corner */
.upg-rank {
  position: absolute; top: 0.6rem; right: 0.6rem; z-index: 2;
  font-family: var(--font-display); font-weight: 800; font-size: 0.9rem;
  min-width: 2rem; text-align: center; padding: 0.2rem 0.5rem; border-radius: 9px;
  color: #fff; background: rgba(10,12,18,0.72); border: 1px solid rgba(255,255,255,0.14);
  backdrop-filter: blur(2px);
}
/* Inside a tag row the badge flows with its siblings instead of stacking on
   top of the status pill. */
.upg-tagrow .upg-rank { position: static; top: auto; right: auto; }

/* Hype meter block on each card */
.hype-block {
  display: flex; flex-direction: column; gap: 0.5rem;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 0.6rem 0.7rem; margin: -0.1rem 0 0.15rem;
}
.hype-block.hype-hot { border-color: rgba(245,185,66,0.55); box-shadow: 0 0 0 1px rgba(245,185,66,0.25) inset; }
.hype-meter { display: flex; flex-direction: column; gap: 0.32rem; }
.hype-meter-top { display: flex; align-items: baseline; justify-content: space-between; }
.hype-meter-label { font-family: var(--font-display); font-weight: 800; font-size: 0.72rem; letter-spacing: 0.05em; color: var(--muted); }
.hype-n { font-family: var(--font-display); font-weight: 800; font-size: 1.05rem; color: var(--text); }
.hype-hot .hype-n { color: #F5B942; }
.hype-bar { position: relative; height: 9px; border-radius: 999px; background: rgba(255,255,255,0.08); overflow: hidden; }
.hype-fill {
  position: absolute; inset: 0 auto 0 0; width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, #F0A24E, #F5B942);
  transition: width 1s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.hype-hot .hype-fill {
  background: linear-gradient(90deg, #F0A24E, #F5B942, #FFE08A, #F5B942);
  background-size: 200% 100%;
  animation: hypeFillShimmer 2.4s linear infinite;
}
@keyframes hypeFillShimmer { 0% { background-position: 0% 0; } 100% { background-position: 200% 0; } }
.hype-block.hype-pop { animation: hypePopPulse 0.5s ease; }
@keyframes hypePopPulse { 0% { transform: scale(1); } 40% { transform: scale(1.035); } 100% { transform: scale(1); } }

.hype-actions { display: flex; gap: 0.45rem; }
.hype-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
  font-family: var(--font-display); font-weight: 700; font-size: 0.82rem;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  border-radius: 9px; padding: 0.42rem 0.5rem; cursor: pointer;
  transition: border-color .15s, background .15s, transform .1s, filter .15s;
}
.hype-btn:hover { border-color: var(--accent-line); }
.hype-btn:active { transform: scale(0.97); }
.hype-vote:hover { border-color: rgba(245,185,66,0.6); background: rgba(245,185,66,0.08); }
.hype-vote.voted { color: #F5B942; border-color: rgba(245,185,66,0.5); background: rgba(245,185,66,0.1); cursor: default; }
.hype-vote:disabled { cursor: default; }
.hype-notify.on { color: #7FB0F0; border-color: rgba(127,176,240,0.5); background: rgba(127,176,240,0.1); }

/* Quota hint in section header */
.hype-quota { font-size: 0.8rem; color: var(--muted); }
.hype-quota b { color: var(--text); }
.hype-quota.spent b { color: #F0A24E; }
.hype-quota a { color: var(--accent); }
.hype-quota-up { opacity: 0.8; }

/* Release alert banner */
.hype-release-alert {
  display: flex; align-items: center; gap: 0.7rem; margin: 0 0 1.2rem;
  background: rgba(127,217,143,0.1); border: 1px solid rgba(127,217,143,0.4);
  border-radius: 12px; padding: 0.75rem 1rem; color: var(--text);
}
.hype-release-ic { font-size: 1.3rem; }
.hype-release-tx { flex: 1; font-size: 0.92rem; line-height: 1.4; }
.hype-release-tx b { color: #7FD98F; }
.hype-release-x { background: transparent; border: none; color: var(--muted); font-size: 1rem; cursor: pointer; }
.hype-release-x:hover { color: var(--text); }

/* Toast */
.hype-toast {
  position: fixed; left: 50%; bottom: 24px; transform: translate(-50%, 20px);
  z-index: 5000; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 999px; padding: 0.6rem 1.1rem;
  font-family: var(--font-display); font-weight: 700; font-size: 0.9rem;
  box-shadow: 0 12px 34px rgba(0,0,0,0.45); opacity: 0; pointer-events: none;
  transition: opacity .25s ease, transform .25s ease;
}
.hype-toast.show { opacity: 1; transform: translate(-50%, 0); }
.hype-toast-warn { border-color: rgba(240,162,78,0.5); color: #F0A24E; }

/* Join-server prompt */
.hype-join { max-width: 440px; text-align: center; }
.hype-join-ic { font-size: 2.4rem; margin-bottom: 0.3rem; }
.hype-join h3 { margin: 0 0 0.5rem; }
.hype-join p { color: var(--muted); font-size: 0.94rem; line-height: 1.55; margin: 0 0 1.2rem; }
.hype-join-btns { display: flex; gap: 0.7rem; justify-content: center; flex-wrap: wrap; }
.hype-join-go { margin-top: 0; }
.hype-join-later {
  font-family: var(--font-display); font-weight: 700; font-size: 0.9rem;
  background: transparent; border: 1px solid var(--line); color: var(--muted);
  border-radius: 10px; padding: 0.55rem 1.2rem; cursor: pointer;
}
.hype-join-later:hover { color: var(--text); border-color: var(--accent-line); }

@media (prefers-reduced-motion: reduce) {
  .upg-tag-popular, .hype-hot .hype-fill { animation: none; }
  .hype-fill { transition: none; }
}

.upg-body { display: flex; flex-direction: column; gap: 0.4rem; padding: 0.7rem 0.85rem 0.75rem; flex: 1; }
.upg-title-row { display: flex; gap: 0.55rem; align-items: center; }
.upg-ic {
  width: 40px; height: 40px; min-width: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 800; font-size: 1.25rem; color: #fff;
  background: linear-gradient(135deg, var(--dyn, var(--accent)), color-mix(in srgb, var(--dyn, var(--accent)) 40%, #0c0e14));
  background-size: cover; background-position: center; box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
.upg-ic.has-img { color: transparent; }
.upg-ic-sm { width: 34px; height: 34px; min-width: 34px; border-radius: 9px; font-size: 1rem; }
.upg-ic-lg { width: 56px; height: 56px; min-width: 56px; border-radius: 14px; font-size: 1.7rem; }
.upg-title-txt { min-width: 0; }
.upg-name { font-family: var(--font-display); font-size: 1.02rem; font-weight: 700; line-height: 1.15; }
.upg-dev { display: block; font-size: 0.72rem; color: var(--muted); margin-top: 0.05rem; }
.upg-chip {
  font-size: 0.7rem; padding: 0.18rem 0.5rem; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.upg-chip-region { background: var(--accent-soft); border-color: var(--accent-line); color: var(--text); font-weight: 600; }
.upg-blurb { font-size: 0.86rem; color: #C9CEE2; line-height: 1.5; flex: 1; }
.upg-release { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.upg-cal { font-size: 0.85rem; }
.upg-rel-date { font-family: var(--font-display); font-weight: 700; font-size: 0.92rem; color: var(--text); }
.upg-countdown {
  font-family: var(--font-display); font-weight: 700; font-size: 0.76rem; letter-spacing: 0.02em;
  padding: 0.16rem 0.5rem; border-radius: 6px; color: #F5B942;
  background: rgba(245,185,66,0.12); border: 1px solid rgba(245,185,66,0.35);
}
.upg-cd-done { color: #7FD98F; background: rgba(127,217,143,0.12); border-color: rgba(127,217,143,0.35); }
.upg-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding-top: 0.15rem; border-top: 1px solid var(--line); margin-top: 0.15rem; }
.upg-plats { display: flex; flex-wrap: wrap; gap: 0.3rem; padding-top: 0.35rem; }
.upg-plat {
  display: inline-flex; align-items: center; gap: 0.3rem; color: var(--muted);
  font-size: 0.72rem; font-weight: 600; padding: 0.2rem 0.45rem; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.upg-plat svg { width: 14px; height: 14px; fill: currentColor; }
.upg-engine {
  font-size: 0.7rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em;
  padding: 0.2rem 0.45rem; border-radius: 6px; background: var(--panel-2); border: 1px solid var(--line); align-self: flex-end;
}
.upg-more {
  padding: 0 0.85rem 0.7rem; font-size: 0.78rem; font-weight: 700; color: var(--accent);
  opacity: 0; transform: translateY(4px); transition: opacity .2s, transform .2s;
}
.upg-card:hover .upg-more, .upg-card:focus-visible .upg-more { opacity: 1; transform: none; }

/* ---- details modal ---- */
.upg-modal-overlay {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
  padding: 1.2rem; background: rgba(6,7,11,0.66); backdrop-filter: blur(4px);
  opacity: 0; transition: opacity .28s ease;
}
.upg-modal-overlay.open { opacity: 1; }
.upg-modal {
  width: min(560px, 100%); max-height: 88vh; overflow-y: auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: 16px; position: relative;
  transform: translateY(14px) scale(0.98); opacity: 0; transition: transform .28s ease, opacity .28s ease;
  box-shadow: 0 30px 80px rgba(0,0,0,0.6);
}
.upg-modal-overlay.open .upg-modal { transform: none; opacity: 1; }
.upg-modal-close {
  position: absolute; top: 0.7rem; right: 0.7rem; z-index: 3; cursor: pointer;
  width: 32px; height: 32px; border-radius: 50%; border: none; font-size: 0.9rem;
  background: rgba(0,0,0,0.45); color: #fff; display: flex; align-items: center; justify-content: center;
}
.upg-modal-close:hover { background: rgba(0,0,0,0.7); }
.upg-modal-banner {
  height: 170px; border-radius: 16px 16px 0 0; position: relative;
  background-color: var(--panel-2); background-size: cover; background-position: center;
}
.upg-modal-banner:not(.has-img) {
  background: linear-gradient(135deg, color-mix(in srgb, var(--dyn) 60%, #0c0e14), color-mix(in srgb, var(--dyn) 20%, #0c0e14));
}
.upg-modal-banner .upg-tag-status { position: absolute; top: 0.8rem; left: 0.8rem; right: auto; }
.upg-modal-body { padding: 1.1rem 1.2rem 1.3rem; display: flex; flex-direction: column; gap: 0.7rem; }
.upg-modal-meta { display: flex; flex-direction: column; gap: 0.4rem; background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 0.7rem 0.85rem; }
.upg-mrow { display: flex; gap: 0.8rem; align-items: baseline; font-size: 0.85rem; }
.upg-mlabel { font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); min-width: 74px; }
.upg-mval { color: var(--text); }
.upg-mhead { font-family: var(--font-display); font-size: 0.95rem; color: var(--accent); margin-top: 0.2rem; }
.upg-mdesc { font-size: 0.9rem; color: #C9CEE2; line-height: 1.55; }
.upg-ctas { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.3rem; }
.upg-cta { display: inline-flex; align-items: center; gap: 0.4rem; text-decoration: none; font-weight: 700; font-size: 0.9rem; padding: 0.6rem 1.1rem; border-radius: 10px; }
.upg-cta-primary { background: var(--accent); color: #10121a; }
.upg-cta-primary:hover { filter: brightness(1.08); }
.upg-cta-secondary { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); }
.upg-cta-secondary:hover { border-color: var(--accent-line); }
.upg-follow { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.2rem; }
.upg-socials { display: flex; gap: 0.5rem; }
.upg-social { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); }
.upg-social:hover { color: var(--text); border-color: var(--accent-line); }
.upg-social svg { width: 17px; height: 17px; fill: currentColor; }

@media (max-width: 560px) {
  .upg-filter-row { flex-direction: column; align-items: stretch; }
  .upg-selects { justify-content: space-between; }
  .upg-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   UPCOMING TRACKER v2 — compact top, banner images, read-more,
   per-card socials, collapsible sections
   ============================================================ */
/* compact hero + toolbar */
.upg-hero { padding: 1.5rem 1.4rem 1.25rem; }
.upg-hero h1 { font-size: clamp(1.5rem, 3vw, 2.1rem); }
.upg-hero p { margin-top: 0.35rem; font-size: 0.92rem; }
/* The filter controls used to float loose on the page with the selects shoved
   to the far right, which left a wide dead gap in the middle. They now sit in
   one bordered card: search and the three selects on the first line, the
   platform pills on a labelled second line. */
.upg-toolbar {
  display: block; margin: 1rem 0 1.2rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 0.7rem 0.8rem;
}
.upg-filters { display: flex; flex-direction: column; gap: 0.55rem; }
.upg-frow { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem; }
.upg-frow-plat { align-items: center; gap: 0.55rem; border-top: 1px solid var(--line); padding-top: 0.55rem; }
.upg-frow-label {
  font-size: 0.64rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); flex: none;
}
.upg-search { flex: 1 1 220px; min-width: 160px; margin: 0; }
.upg-pill-group { gap: 0.3rem; }
.upg-fpill { padding: 0.28rem 0.58rem; font-size: 0.78rem; }
.upg-sel { flex: none; gap: 0.15rem; }
.upg-sel select { padding: 0.36rem 0.5rem; }
.upg-reset { padding: 0.42rem 0.75rem; }

/* Banner art layer. It sits over the game's colour wash at a low opacity so the
   TAG pills stay legible, and fades in once loadImgEl finds a file. A game can
   override the level with bannerOpacity, which JS writes to the inline style. */
.upg-banner-img {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  opacity: 0; transition: opacity .35s ease;
}
.upg-banner-img.has-img { opacity: 0.42; }
.upg-card:hover .upg-banner-img.has-img { opacity: 0.6; }
/* The modal is a bigger surface with fewer things on top, so it can carry more. */
.upg-modal-banner { overflow: hidden; }
.upg-modal-banner .upg-banner-img.has-img { opacity: 0.7; }

/* ---- floating filter dock ----
   Appears once the top toolbar scrolls out of view. Pinned to the right edge by
   default; the ⇄ button in its header moves it to the left and remembers that.
   Sits below the topbar's z-index (59) so it never covers the nav panel. */
.upg-dock { position: fixed; top: 50%; transform: translateY(-50%); z-index: 45; display: flex; align-items: center; }
/* display:flex above would otherwise beat the UA rule for [hidden], leaving the
   dock on screen while the real toolbar is still in view. */
.upg-dock[hidden], .upg-dock-panel[hidden] { display: none; }
.upg-dock-right { right: 0; flex-direction: row-reverse; }
.upg-dock-left { left: 0; flex-direction: row; }
.upg-dock-in { animation: fadeIn 0.22s ease; }
.upg-dock-tab {
  display: flex; flex-direction: column; align-items: center; gap: 0.3rem; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); color: var(--muted);
  padding: 0.8rem 0.45rem; font-family: var(--font-display); font-weight: 700;
  font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.upg-dock-right .upg-dock-tab { border-right: 0; border-radius: 12px 0 0 12px; }
.upg-dock-left .upg-dock-tab { border-left: 0; border-radius: 0 12px 12px 0; }
.upg-dock-tab:hover { color: var(--text); border-color: var(--accent-line); }
.upg-dock.has-filters .upg-dock-tab { color: var(--accent); border-color: var(--accent-line); }
.upg-dock-ic { font-size: 1.05rem; letter-spacing: 0; }
/* Vertical label so the closed tab stays a thin sliver. */
.upg-dock-tab-tx { writing-mode: vertical-rl; }
.upg-dock-n {
  min-width: 18px; border-radius: 999px; background: var(--accent); color: #10121a;
  font-size: 0.66rem; letter-spacing: 0; padding: 0.05rem 0.3rem;
}
.upg-dock-panel {
  width: min(330px, 88vw); max-height: min(78vh, 620px); overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 18px 46px rgba(0, 0, 0, 0.55);
  animation: fadeIn 0.2s ease;
}
.upg-dock-right .upg-dock-panel { border-radius: 12px 0 0 12px; border-right: 0; }
.upg-dock-left .upg-dock-panel { border-radius: 0 12px 12px 0; border-left: 0; }
.upg-dock-head {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0.6rem 0.7rem; border-bottom: 1px solid var(--line);
}
.upg-dock-title {
  flex: 1 1 auto; font-family: var(--font-display); font-weight: 700; font-size: 0.72rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
}
.upg-dock-side, .upg-dock-x {
  cursor: pointer; background: none; border: 1px solid var(--line); border-radius: 7px;
  color: var(--muted); width: 26px; height: 26px; font-size: 0.8rem; flex: none;
  display: flex; align-items: center; justify-content: center;
}
.upg-dock-side:hover, .upg-dock-x:hover { color: var(--accent); border-color: var(--accent-line); }
.upg-dock-body { padding: 0.7rem; }
/* Stacked, because the dock is far narrower than the page toolbar. */
.upg-dock-body .upg-frow { flex-direction: column; align-items: stretch; }
.upg-dock-body .upg-frow-plat { flex-direction: row; flex-wrap: wrap; align-items: center; }
.upg-dock-body .upg-view { margin-left: 0; width: 100%; justify-content: center; }
.upg-dock-body .upg-view-btn { flex: 1; justify-content: center; }
.upg-dock-body .upg-search { flex: 1 1 auto; width: 100%; }
.upg-dock-body .upg-sel { width: 100%; }
.upg-dock-body .upg-sel select { width: 100%; }
.upg-dock-body .upg-reset { width: 100%; }

@media (max-width: 720px) {
  /* No room for an edge rail on a phone: the dock becomes a corner button and
     the panel opens as a sheet above it. */
  .upg-dock { top: auto; bottom: 0.9rem; transform: none; flex-direction: column-reverse; align-items: stretch; }
  .upg-dock-right { right: 0.9rem; }
  .upg-dock-left { left: 0.9rem; }
  .upg-dock-tab { flex-direction: row; border: 1px solid var(--line) !important; border-radius: 999px !important; padding: 0.6rem 0.9rem; }
  .upg-dock-tab-tx { writing-mode: horizontal-tb; }
  .upg-dock-panel { border: 1px solid var(--line) !important; border-radius: 12px !important; margin-bottom: 0.5rem; width: min(330px, 86vw); }
}

/* read more */
.upg-desc-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem; flex: 1; }
.upg-desc { font-size: 0.82rem; color: #C9CEE2; line-height: 1.45; margin: 0; }
.upg-desc.clamped {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.upg-readmore {
  background: none; border: none; color: var(--accent); font-weight: 700; font-size: 0.8rem;
  cursor: pointer; padding: 0.15rem 0 0; align-self: flex-start;
}
.upg-readmore:hover { text-decoration: underline; }
.upg-readmore.upg-hide { display: none; }
html[data-mode="light"] .upg-desc { color: var(--muted); }

/* per-card socials */
.upg-card-social { display: flex; flex-wrap: wrap; gap: 0.3rem; padding-top: 0.4rem; margin-top: 0; border-top: 1px solid var(--line); }
.upg-social-sm { width: 26px; height: 26px; border-radius: 7px; }
.upg-social-sm svg { width: 14px; height: 14px; }

/* ---- most hyped right now: compact spotlight row ---- */
.upg-spot-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 0.7rem;
}
.upg-spot {
  display: grid; grid-template-columns: auto auto 1fr auto auto; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.7rem; cursor: pointer; text-align: left;
  background: var(--panel); border: 1px solid rgba(245, 185, 66, 0.4); border-radius: 12px;
  box-shadow: 0 0 0 1px rgba(245, 185, 66, 0.1);
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.upg-spot:hover, .upg-spot:focus-visible {
  border-color: rgba(245, 185, 66, 0.8); transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0,0,0,0.32); outline: none;
}
.upg-spot-rank {
  font-family: var(--font-display); font-weight: 800; font-size: 0.86rem;
  color: #F5B942; min-width: 1.6em;
}
.upg-spot-txt { min-width: 0; overflow: hidden; display: flex; flex-direction: column; gap: 0.12rem; }
.upg-spot-name {
  font-family: var(--font-display); font-size: 0.95rem; font-weight: 700; line-height: 1.15; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.upg-spot-when {
  display: flex; align-items: center; gap: 0.35rem;
  font-size: 0.72rem; color: var(--muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.upg-spot-when .upg-countdown { font-size: 0.68rem; padding: 0.1rem 0.35rem; }
/* the meter is a number here, not a bar: the row has to stay one line tall */
.upg-spot-hype { display: flex; align-items: center; gap: 0.3rem; }
.upg-spot-hype .hype-bar { display: none; }
.upg-spot-hype .hype-n {
  font-family: var(--font-display); font-size: 0.8rem; font-weight: 800; color: #F5B942;
  padding: 0.16rem 0.45rem; border-radius: 999px;
  background: rgba(245,185,66,0.12); border: 1px solid rgba(245,185,66,0.3);
}
.upg-spot-hype .hype-n::before { content: "🔥 "; font-size: 0.72rem; }
.upg-spot-btns { display: flex; align-items: center; gap: 0.25rem; }
.upg-spot-btns .hype-btn { padding: 0.3rem 0.4rem; font-size: 0.8rem; line-height: 1; }
.upg-spot-btns .hype-vote-tx, .upg-spot-btns .hype-notify-tx { display: none; }

/* ---- grid / list layout toggle ---- */
.upg-view {
  display: inline-flex; align-items: center; gap: 2px; margin-left: auto;
  padding: 2px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel-2);
}
.upg-view-btn {
  display: inline-flex; align-items: center; gap: 0.3rem; cursor: pointer;
  background: none; border: none; border-radius: 7px; padding: 0.28rem 0.5rem;
  font-family: var(--font-display); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted);
  transition: background .15s ease, color .15s ease;
}
.upg-view-btn svg { width: 14px; height: 14px; fill: currentColor; }
.upg-view-btn:hover { color: var(--text); }
.upg-view-btn.active { background: var(--accent); color: #fff; }

.upg-grid.is-list { display: flex; flex-direction: column; gap: 0.5rem; }
.upg-grid.is-list .upg-card {
  display: grid; grid-template-columns: 160px minmax(0, 1fr); grid-template-rows: 1fr auto; border-radius: 12px;
}
.upg-grid.is-list .upg-card:hover, .upg-grid.is-list .upg-card:focus-visible { transform: translateY(-2px); }
.upg-grid.is-list .upg-banner { height: auto; grid-column: 1; grid-row: 1 / span 2; }
.upg-grid.is-list .upg-body { grid-column: 2; grid-row: 1; }
.upg-grid.is-list .upg-more { grid-column: 2; grid-row: 2; }
.upg-grid.is-list .upg-banner::after { background: linear-gradient(90deg, rgba(8,9,13,0.05) 40%, rgba(8,9,13,0.72) 100%); }
.upg-grid.is-list .upg-tag { top: 0.4rem; font-size: 0.58rem; }
.upg-grid.is-list .upg-tagrow-r, .upg-grid.is-list .upg-tag-popular { display: none; }
.upg-grid.is-list .upg-body {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-content: center; column-gap: 1rem; row-gap: 0.28rem;
  padding: 0.55rem 0.8rem;
}
.upg-grid.is-list .upg-title-row,
.upg-grid.is-list .upg-desc-wrap,
.upg-grid.is-list .upg-release { grid-column: 1; }
.upg-grid.is-list .hype-block { grid-column: 2; grid-row: 1 / -1; align-self: center; }
.upg-grid.is-list .upg-desc.clamped { -webkit-line-clamp: 1; }
.upg-grid.is-list .upg-more { padding: 0 0.8rem 0.55rem; font-size: 0.74rem; }
/* a list row is a scannable line, not a shrunken card: the extras live in the modal */
.upg-grid.is-list .upg-chips,
.upg-grid.is-list .upg-plats,
.upg-grid.is-list .upg-card-social,
.upg-grid.is-list .upg-readmore { display: none; }
.upg-grid.is-list .hype-block { padding: 0; border: 0; background: none; flex-direction: row; align-items: center; gap: 0.45rem; }
.upg-grid.is-list .hype-meter { width: 120px; }
.upg-grid.is-list .hype-btn { padding: 0.22rem 0.45rem; font-size: 0.7rem; }
.upg-grid.is-list .hype-vote-tx, .upg-grid.is-list .hype-notify-tx { display: none; }
.upg-grid.is-list .upg-ic { width: 32px; height: 32px; min-width: 32px; border-radius: 8px; font-size: 1rem; }
.upg-grid.is-list .upg-name { font-size: 0.95rem; }
@media (max-width: 620px) {
  .upg-grid.is-list .upg-card { grid-template-columns: 92px minmax(0, 1fr); }
  .upg-grid.is-list .upg-card-social, .upg-grid.is-list .upg-desc-wrap { display: none; }
  .upg-grid.is-list .upg-body { grid-template-columns: minmax(0, 1fr); }
  .upg-grid.is-list .hype-block { grid-column: 1; grid-row: auto; }
  .upg-grid.is-list .hype-meter { width: auto; flex: 1; min-width: 0; }
  .upg-spot { grid-template-columns: auto auto 1fr auto; }
  .upg-spot-hype { display: none; }
}

/* collapsible sections */
.upg-sec { margin-bottom: 1.6rem; }
.upg-sec .sec-head-row { margin-bottom: 0.9rem; }
.upg-sec-toggle {
  display: flex; align-items: center; gap: 0.55rem; background: none; border: none; cursor: pointer;
  font-family: var(--font-display); font-size: 1.2rem; font-weight: 700; color: var(--text); padding: 0;
}
.upg-sec-toggle:hover .upg-sec-title { color: var(--accent); }
.upg-sec-chev { font-size: 0.85rem; color: var(--muted); transition: transform .2s ease; }
.upg-sec.collapsed .upg-sec-chev { transform: rotate(-90deg); }
.upg-sec.collapsed .upg-sec-body { display: none; }

@media (max-width: 620px) {
  .upg-selects { margin-left: 0; width: 100%; justify-content: space-between; }
  .upg-search { flex-basis: 100%; }
}

/* ============================================================
   ACCOUNTS: login chip, favorites, supporter area, gating, ads
   ============================================================ */
.acct-slot { display: flex; align-items: center; flex-shrink: 0; margin-left: 0.4rem; }
.acct-btn {
  display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer;
  font-family: var(--font-display); font-weight: 600; font-size: 0.86rem;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  border-radius: 999px; padding: 0.32rem 0.7rem; line-height: 1;
}
.acct-btn:hover { border-color: var(--accent-line); }
.acct-login { color: var(--text); }
.acct-login svg { fill: #5865F2; }
.acct-wrap { position: relative; }
.acct-av { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; }
.acct-av-ph { width: 24px; height: 24px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--accent); color: #10121a; font-weight: 800; font-size: 0.8rem; }
.acct-name { max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-caret { font-size: 0.7rem; color: var(--muted); }
.acct-badge { font-size: 0.6rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.12rem 0.4rem; border-radius: 5px; }
.acct-badge-sup { background: rgba(245,185,66,0.16); color: #F5B942; border: 1px solid rgba(245,185,66,0.4); }
.acct-badge-boost { background: rgba(162,120,255,0.16); color: #B79BFF; border: 1px solid rgba(162,120,255,0.4); }
.acct-menu {
  position: absolute; right: 0; top: calc(100% + 0.5rem); min-width: 210px; z-index: 60;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 0.4rem;
  box-shadow: 0 18px 44px rgba(0,0,0,0.5); display: none; flex-direction: column; gap: 0.15rem;
}
.acct-menu.open { display: flex; }
.acct-mi {
  display: flex; align-items: center; gap: 0.55rem; text-decoration: none; cursor: pointer;
  font-size: 0.88rem; color: var(--text); background: none; border: none; text-align: left;
  padding: 0.5rem 0.6rem; border-radius: 8px; width: 100%;
}
.acct-mi:hover { background: var(--panel-2); }
.acct-mi-ic { width: 18px; text-align: center; color: var(--muted); }
.acct-mi-cta { color: #F5B942; }
.acct-logout { color: var(--muted); }

/* favorite button (guide header) */
.article-head { align-items: flex-start; }
.article-head-main { flex: 1; min-width: 0; }
.article-head-actions { flex-shrink: 0; }
.fav-btn {
  display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--muted);
  border-radius: 999px; padding: 0.4rem 0.8rem; font-weight: 700; font-size: 0.84rem; font-family: var(--font-display);
}
.fav-btn:hover { border-color: var(--accent-line); color: var(--text); }
.fav-btn.on { color: #F5B942; border-color: rgba(245,185,66,0.5); background: rgba(245,185,66,0.1); }
.fav-star { font-size: 0.95rem; }

/* guide flags + lock */
.guide-flag { font-size: 0.62rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.1rem 0.4rem; border-radius: 5px; margin-left: 0.3rem; }
.guide-flag-sup { background: rgba(245,185,66,0.16); color: #F5B942; }
.guide-flag-early { background: rgba(94,217,138,0.14); color: #5AD98A; }
.guide-lock { text-align: center; max-width: 520px; margin: 1.5rem auto; background: var(--panel-2); border: 1px solid var(--line); border-radius: 16px; padding: 2rem 1.4rem; }
.guide-lock-ic { font-size: 2.4rem; margin-bottom: 0.3rem; }
.guide-lock h2 { font-family: var(--font-display); margin-bottom: 0.5rem; }
.guide-lock p { color: var(--muted); line-height: 1.6; }
.perk-ctas { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; margin-top: 1.1rem; }
.perk-cta { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; text-decoration: none; font-weight: 700; font-size: 0.9rem; padding: 0.6rem 1.1rem; border-radius: 10px; border: 1px solid var(--line); }
.perk-cta-primary { background: #5865F2; color: #fff; border-color: #5865F2; }
.perk-cta-kofi { background: var(--panel); color: #F5B942; border-color: rgba(245,185,66,0.5); }
.perk-cta:hover { filter: brightness(1.08); }
.guide-lock-badge { position: absolute; top: 0.5rem; right: 0.5rem; font-size: 0.9rem; }
.guide-card { position: relative; }
.guide-card.is-locked .guide-card-title { color: var(--muted); }

/* favorites page */
.fav-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.8rem; margin-top: 1rem; }
.fav-card { position: relative; display: flex; align-items: stretch; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.fav-card-link { display: flex; flex-direction: column; gap: 0.2rem; padding: 0.85rem 2.2rem 0.85rem 1rem; text-decoration: none; flex: 1; min-width: 0; }
.fav-card-title { font-family: var(--font-display); font-weight: 700; color: var(--text); }
.fav-card-game { font-size: 0.76rem; color: var(--muted); }
.fav-remove { position: absolute; top: 0.4rem; right: 0.4rem; width: 26px; height: 26px; border-radius: 7px; border: none; cursor: pointer; background: var(--panel-2); color: var(--muted); }
.fav-remove:hover { color: #F3555A; background: rgba(243,85,90,0.12); }
.link-btn { background: none; border: none; color: var(--accent); cursor: pointer; font: inherit; padding: 0; text-decoration: underline; }

/* supporter area */
.perk-list { list-style: none; display: flex; flex-direction: column; gap: 0.45rem; margin: 1rem 0 0.5rem; }
.perk-list li { font-size: 0.92rem; color: var(--text); padding-left: 0.2rem; }
.supp-form { display: flex; flex-direction: column; gap: 0.6rem; max-width: 620px; }
.supp-text { font-family: var(--font-body); font-size: 0.9rem; color: var(--text); background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 0.7rem 0.8rem; min-height: 96px; resize: vertical; }
.supp-text:focus, .supp-form .search-input:focus { outline: none; border-color: var(--accent); }
.supp-actions { display: flex; align-items: center; gap: 0.8rem; }
.supp-status { font-size: 0.85rem; color: var(--muted); }

/* ad slots (only render when adsEnabled and viewer is not ad-free) */
.ad-slot { border: 1px dashed var(--line); border-radius: 12px; padding: 0.7rem; margin: 1.4rem 0; text-align: center; }
.ad-label { display: block; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin-bottom: 0.4rem; }
.ad-box { display: flex; align-items: center; justify-content: center; gap: 0.6rem; min-height: 90px; background: var(--panel-2); border-radius: 8px; color: var(--muted); font-size: 0.85rem; }
.ad-box a { color: var(--accent); }

@media (max-width: 640px) {
  .acct-name { display: none; }
  /* Guide/article header: let the title column take the row and drop the
     Save button to its own full-width line instead of crushing the title
     down to one word per line. */
  .article-head { flex-wrap: wrap; align-items: flex-start; gap: 0.75rem 0.9rem; }
  .article-thumb { width: 60px; height: 60px; font-size: 1.4rem; }
  .article-head-main { flex: 1 1 0; min-width: 0; }
  .article-head-main h1 { font-size: 1.45rem; line-height: 1.2; word-break: normal; overflow-wrap: break-word; }
  .article-head-actions { order: 3; flex-basis: 100%; width: 100%; }
  .article-head-actions .fav-btn { width: 100%; justify-content: center; }
}

/* ============================================================
   CookieRun: Crumble - class-based tier list (custom hook)
   ============================================================ */
.crt-banner {
  display: flex; align-items: flex-start; gap: 0.5rem; margin: 1rem 0 1.2rem;
  background: rgba(240,162,78,0.1); border: 1px solid rgba(240,162,78,0.4);
  color: #F0A24E; border-radius: 12px; padding: 0.75rem 1rem; font-size: 0.9rem; line-height: 1.5;
}
.crt-tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.1rem; }
.crt-tab {
  cursor: pointer; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted);
  border-radius: 999px; padding: 0.42rem 1rem; font-family: var(--font-display); font-weight: 700; font-size: 0.9rem;
  transition: color .15s, border-color .15s, background .15s;
}
.crt-tab:hover { color: var(--text); border-color: var(--accent-line); }
.crt-tab.active { color: #2a1600; border-color: transparent; background: linear-gradient(90deg, #F5A0C0, #F5B942); }
.crt-list { display: flex; flex-direction: column; gap: 0.7rem; }
.crt-row {
  display: grid; grid-template-columns: 44px 52px 1fr auto; align-items: center; gap: 0.9rem;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 0.8rem 1.1rem;
  text-decoration: none; transition: border-color .18s, transform .18s;
}
.crt-row:hover { border-color: var(--accent-line); transform: translateY(-2px); text-decoration: none; }
.crt-badge {
  width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 800; font-size: 1.35rem;
  color: #16110a; background: var(--dyn, #8B93B8);
}
.crt-portrait { width: 52px; height: 52px; min-width: 52px; border-radius: 50%; }
.crt-main { min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.crt-name { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; color: var(--text); }
.crt-desc { font-size: 0.86rem; color: var(--muted); line-height: 1.45; }
.crt-class { font-family: var(--font-display); font-weight: 700; font-size: 0.92rem; color: var(--dyn, var(--muted)); white-space: nowrap; }
@media (max-width: 560px) {
  .crt-row { grid-template-columns: 40px 44px 1fr; }
  .crt-class { grid-column: 2 / -1; font-size: 0.8rem; }
  .crt-badge { width: 40px; height: 40px; font-size: 1.15rem; }
}

/* ============================================================
   CookieRun: Crumble - rarity roster (crc-* custom hook)
   Cards grouped by rarity rank. Frame colour + effect scales with
   rarity: TSSR holographic sweep, SSR gold pulse, SR magenta glow,
   R/U/C progressively calmer. Meme cookies get their own section.
   ============================================================ */
.crc-rgroup { margin: 0 0 2rem; }
.crc-rgroup-h {
  font-family: var(--font-display); font-weight: 800; font-size: 1.5rem;
  display: flex; align-items: center; gap: 0.55rem; margin: 0 0 0.9rem;
  color: var(--dyn, var(--text));
}
.crc-rgroup-n {
  font-size: 0.9rem; font-weight: 700; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 0.08rem 0.6rem;
}
.crc-grid {
  display: grid; gap: 0.9rem;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}
.crc-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--panel); border: 2px solid var(--line); border-radius: 14px;
  overflow: hidden; color: var(--text); text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.crc-card:hover { transform: translateY(-4px) scale(1.02); text-decoration: none; z-index: 2; }
.crc-art {
  width: 100%; aspect-ratio: 1; background-color: var(--panel-2);
  background-size: cover; background-position: center top;
  display: flex; align-items: center; justify-content: center;
}
.crc-card .tl-avatar-ph { font-size: 2.4rem; }
.crc-badge {
  position: absolute; top: 8px; left: 8px; z-index: 3;
  font-family: var(--font-display); font-weight: 800; font-size: 0.72rem;
  letter-spacing: 0.02em; color: #16110a; background: var(--dyn, #8B93B8);
  border-radius: 7px; padding: 0.14rem 0.44rem; line-height: 1.1;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35);
}
.crc-cname {
  font-family: var(--font-display); font-weight: 700; font-size: 0.95rem;
  padding: 0.55rem 0.65rem 0.7rem; line-height: 1.25;
}

/* Rank frame colours + effects (higher rarity = more flair) */
.crc-c   { border-color: #8B93B8; }
.crc-u   { border-color: #3FC8A0; }
.crc-r   { border-color: #4F9DF0; box-shadow: 0 0 0 1px rgba(79,157,240,0.25); }
.crc-sr  { border-color: #E85AC0; box-shadow: 0 0 14px rgba(232,90,192,0.30); }
.crc-ssr {
  border-color: #F5B942;
  box-shadow: 0 0 16px rgba(245,185,66,0.34);
  animation: crcGold 2.6s ease-in-out infinite;
}
@keyframes crcGold {
  0%, 100% { box-shadow: 0 0 12px rgba(245,185,66,0.28); }
  50%      { box-shadow: 0 0 22px rgba(245,185,66,0.55); }
}
.crc-tssr {
  border-color: #B983FF;
  background:
    linear-gradient(var(--panel), var(--panel)) padding-box,
    linear-gradient(120deg, #B983FF, #F5B942, #E85AC0, #4F9DF0, #B983FF) border-box;
  border: 2px solid transparent;
  background-size: auto, 300% 300%;
  animation: crcHolo 5s linear infinite;
  box-shadow: 0 0 20px rgba(185,131,255,0.42);
}
@keyframes crcHolo {
  0%   { background-position: center, 0% 50%; }
  100% { background-position: center, 300% 50%; }
}
.crc-tssr::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.22) 48%, transparent 66%);
  background-size: 250% 250%;
  animation: crcSheen 3.4s ease-in-out infinite;
}
@keyframes crcSheen {
  0%   { background-position: 130% 0; }
  60%, 100% { background-position: -60% 0; }
}

/* Meme section */
.crc-meme-sec { margin-top: 2.6rem; padding-top: 1.6rem; border-top: 1px dashed var(--line); }
.crc-meme-text { color: #C9A227; }
.crc-meme-note { margin: -0.3rem 0 1rem; max-width: 62ch; font-size: 0.9rem; }
.crc-meme-sec .crc-card { border-style: dashed; }

/* Individual Cookie page */
.crc-char {
  display: flex; gap: 1.6rem; align-items: flex-start; margin-top: 1.2rem;
  background: var(--panel); border: 2px solid var(--line); border-radius: 18px;
  padding: 1.4rem; flex-wrap: wrap;
}
.crc-char-art {
  width: 240px; max-width: 100%; aspect-ratio: 1; border-radius: 14px;
  background-color: var(--panel-2); background-size: cover; background-position: center top;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.crc-char-art .tl-avatar-ph { font-size: 4rem; }
.crc-char-main { flex: 1 1 260px; min-width: 0; }
.crc-char-main h1 { margin: 0.5rem 0 0.6rem; }
.crc-char .crc-badge { position: static; display: inline-block; font-size: 0.8rem; padding: 0.2rem 0.6rem; }
@media (max-width: 560px) {
  .crc-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 0.7rem; }
  .crc-char-art { width: 100%; }
}

/* ============================================================
   Login landing (login.html) — our own Discord sign-in screen
   ============================================================ */
.login-wrap { max-width: 1100px; margin: 0 auto; }
.login-grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 2.4rem; align-items: start; margin-top: 0.6rem; }
.login-eyebrow { display: inline-block; font-family: var(--font-display); font-weight: 700; font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); background: var(--accent-line); border: 1px solid var(--accent-line); border-radius: 999px; padding: 0.25rem 0.7rem; margin-bottom: 1rem; }
.login-title { font-size: 2.5rem; line-height: 1.1; margin: 0 0 0.7rem; }
.login-accent { background: linear-gradient(90deg, #7A96F0, var(--accent)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.login-lede { color: var(--muted); font-size: 1.02rem; line-height: 1.55; max-width: 40ch; margin: 0 0 1.6rem; }
.login-perks { display: grid; gap: 0.7rem; }
.login-perk { display: flex; gap: 0.8rem; align-items: flex-start; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 0.85rem 1rem; }
.login-perk-ic { font-size: 1.25rem; line-height: 1.4; flex-shrink: 0; }
.login-perk-tx { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.login-perk-h { font-family: var(--font-display); font-weight: 700; font-size: 1rem; color: var(--text); display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.login-perk-d { font-size: 0.88rem; color: var(--muted); line-height: 1.45; }
.login-perk-tag { font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; border-radius: 999px; padding: 0.1rem 0.5rem; }
.login-perk-tag-free { color: #7FD98F; background: rgba(127,217,143,0.12); border: 1px solid rgba(127,217,143,0.35); }
.login-perk-tag-sup { color: #F0C04E; background: rgba(240,192,78,0.12); border: 1px solid rgba(240,192,78,0.35); }

.login-card { background: linear-gradient(180deg, var(--panel), var(--panel-2)); border: 1px solid var(--line); border-radius: 18px; padding: 1.7rem 1.6rem; position: sticky; top: 90px; box-shadow: 0 18px 50px rgba(0,0,0,0.35); }
.login-card h2 { font-size: 1.4rem; margin: 0 0 0.3rem; }
.login-card-sub { color: var(--muted); font-size: 0.9rem; margin: 0 0 1.2rem; }
.login-btn { display: flex; align-items: center; justify-content: center; gap: 0.6rem; width: 100%; box-sizing: border-box; font-family: var(--font-display); font-weight: 700; font-size: 1rem; border-radius: 12px; padding: 0.85rem 1rem; text-decoration: none; border: 1px solid transparent; transition: transform .12s ease, filter .12s ease, background .12s ease; }
.login-btn:hover { transform: translateY(-1px); filter: brightness(1.06); }
.login-btn-discord { background: #5865F2; color: #fff; }
.login-dico { flex-shrink: 0; }
.login-sep { display: flex; align-items: center; gap: 0.7rem; margin: 1.3rem 0 0.9rem; color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; }
.login-sep::before, .login-sep::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.login-notes { list-style: none; margin: 0 0 1.2rem; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.login-notes li { display: flex; gap: 0.55rem; align-items: flex-start; font-size: 0.86rem; color: var(--muted); line-height: 1.45; }
.login-kofi { display: block; text-align: center; font-size: 0.88rem; font-weight: 600; color: #F0C04E; background: rgba(240,192,78,0.08); border: 1px solid rgba(240,192,78,0.3); border-radius: 12px; padding: 0.65rem 0.8rem; text-decoration: none; margin-bottom: 1rem; }
.login-kofi:hover { background: rgba(240,192,78,0.14); }
.login-back { display: block; text-align: center; color: var(--muted); font-size: 0.86rem; text-decoration: none; }
.login-back:hover { color: var(--text); }

/* logged-in confirmation */
.login-card-solo { max-width: 460px; margin: 1.5rem auto 0; text-align: center; position: static; }
.login-check { width: 60px; height: 60px; margin: 0 auto 1rem; border-radius: 50%; background: rgba(127,217,143,0.14); border: 1px solid rgba(127,217,143,0.4); color: #7FD98F; font-size: 1.9rem; display: flex; align-items: center; justify-content: center; }
.login-hello { color: var(--muted); margin: 0.4rem 0 1.4rem; }
.login-badge { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; border-radius: 999px; padding: 0.15rem 0.55rem; margin-left: 0.3rem; }
.login-badge-sup { color: #F0C04E; background: rgba(240,192,78,0.12); border: 1px solid rgba(240,192,78,0.35); }
.login-badge-boost { color: #DA7AF0; background: rgba(218,122,240,0.12); border: 1px solid rgba(218,122,240,0.35); }
.login-actions { display: flex; gap: 0.7rem; margin-bottom: 1.2rem; }
.login-btn-alt { background: var(--panel); border: 1px solid var(--line); color: var(--text); flex: 1; }
.login-btn-alt:hover { border-color: var(--accent-line); }

@media (max-width: 860px) {
  .login-grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .login-card { position: static; order: -1; }
  .login-title { font-size: 2rem; }
  .login-lede { max-width: none; }
}
@media (max-width: 560px) {
  .login-title { font-size: 1.7rem; }
  .login-actions { flex-direction: column; }
}

/* ============================================================
   Guide comments (supporter discussion) — js/comments.js
   ============================================================ */
.guide-comments { margin-top: 2rem; }
.cmt-wrap { border-top: 1px solid var(--line); padding-top: 1.6rem; }
.cmt-title { font-size: 1.3rem; display: flex; align-items: center; gap: 0.5rem; margin: 0 0 1rem; }
.cmt-count { font-size: 0.85rem; font-weight: 700; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 0.1rem 0.6rem; }

.cmt-gate { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 1.1rem 1.2rem; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.8rem; margin-bottom: 1.4rem; }
.cmt-gate p { margin: 0; color: var(--muted); font-size: 0.92rem; max-width: 60ch; }
.cmt-gate-btn { flex-shrink: 0; font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; background: var(--accent); color: #fff; border-radius: 10px; padding: 0.55rem 1.1rem; text-decoration: none; }
.cmt-gate-btn:hover { filter: brightness(1.07); }

.cmt-composer { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 0.9rem; margin-bottom: 1.6rem; }
.cmt-input { width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 0.94rem; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 0.7rem 0.8rem; resize: vertical; min-height: 3.4rem; }
.cmt-input:focus { outline: none; border-color: var(--accent); }
.cmt-composer-foot { display: flex; align-items: center; justify-content: flex-end; gap: 0.8rem; margin-top: 0.6rem; }
.cmt-hint { font-size: 0.82rem; color: var(--muted); margin-right: auto; }
.cmt-submit { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; background: var(--accent); color: #fff; border: none; border-radius: 10px; padding: 0.55rem 1.2rem; cursor: pointer; }
.cmt-submit:hover { filter: brightness(1.07); }
.cmt-submit:disabled { opacity: 0.6; cursor: default; }
.cmt-submit-sm { padding: 0.4rem 0.9rem; font-size: 0.84rem; }

.cmt-thread { margin-bottom: 1.3rem; }
.cmt { display: flex; gap: 0.7rem; align-items: flex-start; }
.cmt-av { width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0; object-fit: cover; background: var(--panel-2); border: 1px solid var(--line); }
.cmt-av-ph { display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; color: var(--muted); }
.cmt-main { flex: 1 1 0; min-width: 0; }
.cmt-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cmt-name { font-family: var(--font-display); font-weight: 700; color: var(--text); font-size: 0.95rem; }
.cmt-role { font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; border-radius: 999px; padding: 0.08rem 0.45rem; }
.cmt-role-sup { color: #F0C04E; background: rgba(240,192,78,0.12); border: 1px solid rgba(240,192,78,0.35); }
.cmt-role-boost { color: #DA7AF0; background: rgba(218,122,240,0.12); border: 1px solid rgba(218,122,240,0.35); }
.cmt-time { font-size: 0.78rem; color: var(--muted); }
.cmt-body { color: var(--text); font-size: 0.94rem; line-height: 1.55; margin: 0.25rem 0 0.4rem; overflow-wrap: break-word; word-break: break-word; }
.cmt-removed { color: var(--muted); font-style: italic; font-size: 0.9rem; margin: 0.4rem 0; }
.cmt-deleted .cmt-av-ph { opacity: 0.5; }

.cmt-kids { margin: 0.8rem 0 0 1.4rem; padding-left: 1rem; border-left: 2px solid var(--line); display: flex; flex-direction: column; gap: 1rem; }
.cmt-reply { }

.cmt-reacts { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.3rem; }
.cmt-react { display: inline-flex; align-items: center; gap: 0.25rem; border: 1px solid var(--line); background: var(--panel); border-radius: 999px; padding: 0.12rem 0.55rem; cursor: pointer; font-size: 0.82rem; color: var(--text); transition: border-color .12s, background .12s; }
.cmt-react:hover { border-color: var(--accent-line); }
.cmt-react.on { border-color: var(--accent); background: var(--accent-line); }
.cmt-react-n { color: var(--muted); font-weight: 700; font-size: 0.76rem; }
.cmt-react.on .cmt-react-n { color: var(--text); }
.cmt-react-add { position: relative; }
.cmt-react-add-btn { width: 26px; height: 26px; border-radius: 999px; border: 1px dashed var(--line); background: transparent; color: var(--muted); cursor: pointer; font-size: 1rem; line-height: 1; }
.cmt-react-add-btn:hover { color: var(--text); border-color: var(--accent-line); }
.cmt-react-menu { position: fixed; z-index: 4000; display: flex; gap: 0.2rem; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 0.3rem; box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
.cmt-react-opt { border: none; background: transparent; cursor: pointer; font-size: 1.1rem; border-radius: 8px; padding: 0.2rem 0.3rem; }
.cmt-react-opt:hover { background: var(--panel-2); }

.cmt-actions { display: flex; gap: 0.9rem; margin-top: 0.4rem; }
.cmt-act { border: none; background: transparent; color: var(--muted); font-size: 0.8rem; font-weight: 600; cursor: pointer; padding: 0; }
.cmt-act:hover { color: var(--text); }
.cmt-act-del:hover { color: #F3555A; }
.cmt-replybox { margin-top: 0.7rem; }
.cmt-empty { color: var(--muted); font-size: 0.94rem; }

@media (max-width: 560px) {
  .cmt-kids { margin-left: 0.4rem; padding-left: 0.7rem; }
  .cmt-gate { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   Banners / Summons page + homepage active-summons + hub block
   ============================================================ */
.sec-head-row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin: 1.6rem 0 0.9rem; }
.sec-head-row .sec-head { margin: 0; }
.sec-head-link { font-size: 0.85rem; font-weight: 600; color: var(--accent); text-decoration: none; white-space: nowrap; }
.sec-head-link:hover { filter: brightness(1.1); }

.bnr-section { margin-bottom: 1.4rem; }
.bnr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; }
.bnr-card { border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: var(--panel); background-size: cover; background-position: center; position: relative; }
.bnr-card[data-bg] .bnr-card-in { background: linear-gradient(180deg, rgba(18,20,28,0.72), rgba(18,20,28,0.92)); }
.bnr-card-in { padding: 1.1rem 1.15rem; height: 100%; }
.bnr-ended { opacity: 0.62; }
.bnr-active { border-color: rgba(240,192,78,0.4); }
.bnr-head { display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.5rem; }
.bnr-rarity { font-family: var(--font-display); font-weight: 700; font-size: 0.8rem; letter-spacing: 0.04em; color: #12100A; background: var(--dyn, #F0C04E); border-radius: 6px; padding: 0.1rem 0.5rem; }
.bnr-type { font-size: 0.76rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
.bnr-live { margin-left: auto; font-size: 0.72rem; font-weight: 700; color: #7FD98F; text-transform: uppercase; letter-spacing: 0.05em; }
.bnr-name { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem; margin: 0 0 0.35rem; color: var(--text); line-height: 1.2; }
.bnr-when { display: block; font-size: 0.86rem; color: var(--muted); margin-bottom: 0.6rem; }
.bnr-when-standing { color: #7FD98F; }
.bnr-when-ended { color: var(--muted); }
.bnr-cd { color: var(--accent); font-weight: 700; }
.bnr-cd-end { color: #F0A24E; }
.bnr-feats { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-bottom: 0.6rem; }
.bnr-feats-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); width: 100%; }
.bnr-feat { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px; padding: 0.18rem 0.6rem; text-decoration: none; }
a.bnr-feat:hover { border-color: var(--accent-line); }
.bnr-feat-r { font-family: var(--font-display); font-weight: 700; font-size: 0.66rem; color: var(--dyn, #F0C04E); }
.bnr-pity { font-size: 0.85rem; color: var(--text); margin: 0 0 0.4rem; }
.bnr-note { font-size: 0.85rem; color: var(--muted); margin: 0; line-height: 1.45; }

/* homepage active-summons strip */
.home-banners { }
.home-banners-sub { color: var(--muted); font-size: 0.92rem; margin: 0 0 0.9rem; }
.hb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0.8rem; }
.hb-card { display: flex; flex-direction: column; gap: 0.25rem; border: 1px solid var(--line); border-radius: 14px; padding: 0.85rem 0.95rem; background: var(--panel); text-decoration: none; transition: border-color .12s, transform .12s; }
.hb-card:hover { border-color: var(--accent-line); transform: translateY(-2px); }
.hb-top { display: flex; align-items: center; justify-content: space-between; }
.hb-rarity { font-family: var(--font-display); font-weight: 700; font-size: 0.72rem; color: #12100A; background: var(--dyn, #F0C04E); border-radius: 5px; padding: 0.05rem 0.4rem; }
.hb-live { font-size: 0.66rem; font-weight: 700; color: #7FD98F; text-transform: uppercase; }
.hb-soon { font-size: 0.66rem; font-weight: 700; color: #F0A24E; text-transform: uppercase; }
.hb-name { font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; color: var(--text); line-height: 1.2; }
.hb-game { font-size: 0.76rem; color: var(--muted); }
.hb-cd { font-size: 0.78rem; font-weight: 700; color: var(--accent); margin-top: 0.15rem; }

@media (max-width: 560px) {
  .bnr-grid { grid-template-columns: 1fr; }
  .hb-grid { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   Supporter page revamp + supporter forum
   ============================================================ */
.sup-hero { background: linear-gradient(180deg, var(--panel), var(--panel-2)); border: 1px solid var(--line); border-radius: 18px; padding: 1.6rem 1.7rem; margin-bottom: 1.4rem; }
.sup-hero-eyebrow { display: inline-block; font-family: var(--font-display); font-weight: 700; font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; color: #F0C04E; background: rgba(240,192,78,0.12); border: 1px solid rgba(240,192,78,0.35); border-radius: 999px; padding: 0.22rem 0.7rem; margin-bottom: 0.7rem; }
.sup-hero h1 { margin: 0 0 0.35rem; font-size: 1.9rem; }
.sup-hero-lede { color: var(--muted); margin: 0; }
.sup-perks { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.8rem; margin-bottom: 1.8rem; }
.sup-perk { display: flex; gap: 0.75rem; align-items: flex-start; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 0.9rem 1rem; }
.sup-perk-ic { font-size: 1.3rem; }
.sup-perk-h { display: block; font-family: var(--font-display); font-weight: 700; color: var(--text); }
.sup-perk-d { display: block; font-size: 0.86rem; color: var(--muted); line-height: 1.4; }
.sup-forum-sub { color: var(--muted); font-size: 0.92rem; margin: 0 0 1rem; }
.cmt-role-staff { color: #4F9DF0; background: rgba(79,157,240,0.14); border: 1px solid rgba(79,157,240,0.4); }

/* ============================================================
   Staff control panel + maintenance
   ============================================================ */
.maint-screen { min-height: 60vh; display: flex; align-items: center; justify-content: center; padding: 3rem 1rem; }
.maint-card { text-align: center; max-width: 440px; }
.maint-ic { font-size: 3rem; margin-bottom: 0.6rem; }
.maint-card h1 { margin: 0 0 0.5rem; }
.maint-card p { color: var(--muted); }
.notfound { text-align: center; padding: 3rem 1rem; }
.notfound h1 { font-size: 3rem; margin: 0 0 0.4rem; }
.btn { display: inline-block; margin-top: 1rem; background: var(--accent); color: #fff; border-radius: 10px; padding: 0.55rem 1.2rem; text-decoration: none; font-family: var(--font-display); font-weight: 700; }

.panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.panel-who { color: var(--muted); font-size: 0.9rem; }
.panel-staff-tag { color: #4F9DF0; font-weight: 700; }
.panel-tabs { display: flex; gap: 0.4rem; flex-wrap: wrap; border-bottom: 1px solid var(--line); margin: 0.8rem 0 1.2rem; }
.panel-tab { background: transparent; border: none; border-bottom: 2px solid transparent; color: var(--muted); font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; padding: 0.55rem 0.8rem; cursor: pointer; }
.panel-tab:hover { color: var(--text); }
.panel-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.panel-note { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 0.85rem 1rem; color: var(--muted); font-size: 0.86rem; line-height: 1.5; margin-top: 1.2rem; }
.panel-hint { color: var(--muted); font-size: 0.85rem; margin: 0.2rem 0 0.8rem; }
.panel-sec { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 1.1rem 1.15rem; margin-bottom: 1.1rem; }
.panel-sec h3 { margin: 0 0 0.8rem; font-size: 1.05rem; }
.panel-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.8rem; margin-bottom: 1.2rem; }
.stat-card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 0.9rem 1rem; }
.stat-v { display: block; font-family: var(--font-display); font-weight: 700; font-size: 1.7rem; color: var(--text); }
.stat-k { display: block; font-size: 0.78rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }

.pv-row { display: grid; grid-template-columns: 64px 1fr auto; align-items: center; gap: 0.7rem; margin-bottom: 0.4rem; font-size: 0.84rem; }
.pv-day, .pv-path { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-path { max-width: 220px; }
.pv-bar { height: 8px; background: var(--panel-2); border-radius: 99px; overflow: hidden; }
.pv-bar-fill { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #7A96F0, var(--accent)); border-radius: 99px; }
.pv-num { font-family: var(--font-display); font-weight: 700; color: var(--text); }
.pv-uv { color: var(--muted); font-weight: 400; font-size: 0.76rem; }

.btn-sm { font-family: var(--font-display); font-weight: 700; font-size: 0.82rem; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); border-radius: 8px; padding: 0.35rem 0.8rem; cursor: pointer; }
.btn-sm:hover { border-color: var(--accent-line); }
.btn-sm:disabled { opacity: 0.55; cursor: default; }
.btn-good { background: rgba(127,217,143,0.14); border-color: rgba(127,217,143,0.4); color: #7FD98F; }
.btn-danger { background: rgba(243,85,90,0.12); border-color: rgba(243,85,90,0.4); color: #F3555A; }
.panel-filter { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
.chipf { border: 1px solid var(--line); background: var(--panel); color: var(--muted); border-radius: 999px; padding: 0.35rem 0.9rem; font-weight: 700; font-size: 0.85rem; cursor: pointer; }
.chipf.active { color: var(--text); border-color: var(--accent); background: var(--accent-line); }

.sub-card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 1rem 1.1rem; margin-bottom: 0.8rem; }
.sub-done { opacity: 0.6; }
.sub-top { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.sub-type { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; border-radius: 999px; padding: 0.12rem 0.5rem; }
.sub-type-suggestion { color: #7FD98F; background: rgba(127,217,143,0.12); border: 1px solid rgba(127,217,143,0.35); }
.sub-type-report { color: #F0A24E; background: rgba(240,162,78,0.12); border: 1px solid rgba(240,162,78,0.35); }
.sub-title { font-family: var(--font-display); font-weight: 700; }
.sub-when { margin-left: auto; font-size: 0.78rem; color: var(--muted); }
.sub-body { color: var(--text); font-size: 0.92rem; line-height: 1.5; margin: 0 0 0.5rem; white-space: pre-wrap; }
.sub-meta { font-size: 0.82rem; color: var(--muted); margin-bottom: 0.6rem; }
.sub-actions { display: flex; gap: 0.5rem; }

.chat-box { display: flex; flex-direction: column; height: 62vh; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); overflow: hidden; }
.chat-log { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.7rem; }
.chat-msg { display: flex; gap: 0.6rem; align-items: flex-start; }
.chat-av { width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; background: var(--panel-2); border: 1px solid var(--line); color: var(--accent); }
.chat-main { min-width: 0; }
.chat-meta { display: flex; align-items: baseline; gap: 0.5rem; }
.chat-name { font-family: var(--font-display); font-weight: 700; color: var(--text); font-size: 0.9rem; }
.chat-time { font-size: 0.72rem; color: var(--muted); }
.chat-text { color: var(--text); font-size: 0.92rem; line-height: 1.45; overflow-wrap: break-word; word-break: break-word; }
.chat-mine .chat-av { color: #7FD98F; }
.chat-input { display: flex; gap: 0.6rem; padding: 0.7rem; border-top: 1px solid var(--line); background: var(--panel-2); }
.chat-input input { flex: 1; font-family: var(--font-body); font-size: 0.92rem; color: var(--text); background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 0.6rem 0.8rem; }
.chat-input input:focus { outline: none; border-color: var(--accent); }

.block-form { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.block-form input { font-family: var(--font-body); font-size: 0.9rem; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 0.5rem 0.7rem; }
.blk-rows, .mod-row { display: flex; flex-direction: column; }
.blk-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.45rem 0; border-bottom: 1px solid var(--line); font-size: 0.88rem; }
.mod-row { flex-direction: row; align-items: flex-start; justify-content: space-between; gap: 0.8rem; padding: 0.6rem 0; border-bottom: 1px solid var(--line); }
.mod-deleted { opacity: 0.5; }
.mod-main { min-width: 0; }
.mod-name { display: block; font-size: 0.86rem; color: var(--text); }
.mod-role { font-size: 0.64rem; text-transform: uppercase; color: var(--accent); }
.mod-guide { display: block; font-size: 0.76rem; color: var(--muted); margin: 0.1rem 0; }
.mod-body { display: block; font-size: 0.9rem; color: var(--text); overflow-wrap: break-word; word-break: break-word; }
.mod-actions { display: flex; gap: 0.4rem; flex-shrink: 0; }
.maint-toggle { display: flex; align-items: center; gap: 1rem; }
.maint-state { font-weight: 700; }
.maint-state.on { color: #F3555A; }
.maint-state.off { color: #7FD98F; }

@media (max-width: 760px) {
  .panel-cols { grid-template-columns: 1fr; }
  .mod-row { flex-direction: column; }
  .pv-path { max-width: 140px; }
}

/* ============================================================
   Comments: captcha, forum channels; contribution bar; modals;
   tutorial; customize panel
   ============================================================ */
.cmt-cap { margin: 0.6rem 0; }
.cmt-cap-box { min-height: 78px; }
.cmt-cap-note { display: block; font-size: 0.8rem; color: var(--muted); margin-top: 0.4rem; }
.cmt-cap-note a { color: var(--accent); }

.forum-channels { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
.forum-chan { border: 1px solid var(--line); background: var(--panel); color: var(--muted); border-radius: 999px; padding: 0.35rem 0.9rem; font-family: var(--font-display); font-weight: 700; font-size: 0.86rem; cursor: pointer; }
.forum-chan:hover { color: var(--text); border-color: var(--accent-line); }
.forum-chan.active { color: #2a1600; border-color: transparent; background: linear-gradient(90deg, #F5A0C0, #F5B942); }

/* supporter contribution bar (fixed, bottom-right) */
.contrib-bar { position: fixed; right: 16px; bottom: 16px; z-index: 60; display: flex; gap: 0.5rem; }
.contrib-btn { display: inline-flex; align-items: center; gap: 0.4rem; font-family: var(--font-display); font-weight: 700; font-size: 0.84rem; border: 1px solid var(--line); border-radius: 999px; padding: 0.55rem 0.95rem; cursor: pointer; background: var(--panel); color: var(--text); box-shadow: 0 8px 24px rgba(0,0,0,0.4); }
.contrib-suggest { border-color: rgba(46,155,240,0.5); }
.contrib-report { border-color: rgba(240,162,78,0.5); color: #F0A24E; }
.contrib-btn:hover { filter: brightness(1.1); transform: translateY(-1px); }
@media (max-width: 560px) { .contrib-bar { right: 10px; bottom: 10px; } .contrib-btn span { display: none; } }

/* generic modal (ld- prefix avoids clashing with the team-builder modal) */
.ld-modal-ov { position: fixed; inset: 0; z-index: 4000; background: rgba(6,7,11,0.82); display: flex; align-items: center; justify-content: center; padding: 1.2rem; opacity: 1; }
.ld-modal-card { position: relative; width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto; background: var(--panel-2); background-image: linear-gradient(180deg, var(--panel), var(--panel-2)); border: 1px solid var(--line); border-radius: 18px; padding: 1.6rem 1.6rem 1.3rem; box-shadow: 0 30px 80px rgba(0,0,0,0.5); }
.ld-modal-card h2 { margin: 0 0 0.3rem; }
.modal-sub { color: var(--muted); font-size: 0.92rem; margin: 0 0 1rem; }
.modal-x { position: absolute; top: 0.8rem; right: 0.9rem; background: transparent; border: none; color: var(--muted); font-size: 1.1rem; cursor: pointer; }
.modal-x:hover { color: var(--text); }
.modal-text { width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 0.94rem; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 0.7rem 0.8rem; resize: vertical; }
.modal-text:focus { outline: none; border-color: var(--accent); }
.modal-foot { display: flex; align-items: center; justify-content: flex-end; gap: 0.8rem; margin-top: 0.9rem; }
.modal-status { margin-right: auto; font-size: 0.84rem; color: var(--muted); }
.modal-send { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; background: var(--accent); color: #fff; border: none; border-radius: 10px; padding: 0.55rem 1.2rem; cursor: pointer; text-decoration: none; display: inline-block; }
.modal-send:hover { filter: brightness(1.07); }

.tut-card { text-align: left; }
.tut-badge { display: inline-block; font-family: var(--font-display); font-weight: 700; font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: #F0C04E; background: rgba(240,192,78,0.12); border: 1px solid rgba(240,192,78,0.35); border-radius: 999px; padding: 0.2rem 0.6rem; margin-bottom: 0.6rem; }
.tut-list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.tut-list li { display: flex; gap: 0.6rem; align-items: flex-start; color: var(--text); font-size: 0.92rem; line-height: 1.4; }
.tut-foot { justify-content: space-between; }

.cz-card { max-width: 560px; }
.cz-sec { border-top: 1px solid var(--line); padding-top: 0.9rem; margin-top: 0.9rem; }
.cz-sec:first-of-type { border-top: none; margin-top: 0.4rem; padding-top: 0; }
.cz-sec h3 { margin: 0 0 0.5rem; font-size: 1rem; }
.cz-hint { color: var(--muted); font-size: 0.82rem; margin: 0 0 0.6rem; }
.cz-check { display: flex; align-items: center; gap: 0.5rem; font-size: 0.92rem; color: var(--text); margin-bottom: 0.6rem; }
.cz-select { width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 0.9rem; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 0.55rem 0.7rem; }
.cz-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.4rem 0; border-bottom: 1px solid var(--line); }
.cz-row .cz-check { margin: 0; }
.cz-move { display: flex; gap: 0.3rem; }

/* compact mode (supporter preference) */
.compact-mode .section { margin-bottom: 1rem; }
.compact-mode .page-pad { padding-top: 1rem; padding-bottom: 1rem; }
.compact-mode .home-hero-inner { padding-top: 1.1rem; padding-bottom: 1rem; }
.compact-mode .hub-hero { padding-top: 1.4rem; padding-bottom: 1.4rem; }

/* ============================================================
   Supporter deep customization: name colors, credits, wallpapers UI
   ============================================================ */
.cmt-name[data-clr] { color: var(--dyn); }

.home-credits { margin-top: 0.7rem; font-size: 0.78rem; color: var(--muted); display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.25rem 0.45rem; }
.credit-label { text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.64rem; font-weight: 700; color: var(--muted); }
.credit-name { font-family: var(--font-display); font-weight: 700; color: var(--text); font-size: 0.82rem; }
.credit-name[data-clr] { color: var(--dyn); }
.credit-name:not(:last-of-type)::after { content: "·"; color: var(--muted); margin-left: 0.5rem; font-weight: 400; }
.credit-join { color: var(--accent); font-weight: 700; text-decoration: none; margin-left: 0.3rem; }
.credit-join:hover { filter: brightness(1.1); }

.cz-colorrow { display: flex; flex-wrap: wrap; gap: 1rem; margin: 0.5rem 0; }
.cz-colorrow label { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; color: var(--text); }
.cz-colorrow input[type="color"] { width: 40px; height: 28px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); padding: 2px; cursor: pointer; }
.cz-wps { display: flex; flex-direction: column; gap: 0.4rem; }
.cz-wp { width: 100%; box-sizing: border-box; }
#cz-color-err { color: #F3555A; min-height: 0; }
#cz-color-err:empty { display: none; }


/* ============================================================
   PAGE HISTORY (community edit changelog)
   ------------------------------------------------------------
   Styled as a neutral control rather than an action: it is a record, not
   something you do to the page.

   The ldh- prefix is a third accordion system on purpose. .acc/.acc-body
   (guide pages) sets opacity: 0 and blanks any <details> body that borrows
   its names, and dacc- is taken by character pages.
   ============================================================ */
.contrib-history { border-color: rgba(139,147,184,0.5); }
.contrib-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 0.1rem;
  font-size: 0.7rem; line-height: 1; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent-line);
}

.ldh-card { max-width: 720px; }
.ldh-list { display: flex; flex-direction: column; gap: 0.5rem; }

.ldh-rev { border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); overflow: hidden; }
.ldh-sum {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  padding: 0.6rem 0.8rem; cursor: pointer; list-style: none;
  font-size: 0.88rem; min-height: 40px;
}
.ldh-sum::-webkit-details-marker { display: none; }
.ldh-sum:hover { background: var(--accent-soft); }

.ldh-act {
  font-family: var(--font-display); font-weight: 700; font-size: 0.66rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  border-radius: 999px; padding: 0.18rem 0.55rem;
  border: 1px solid var(--line); color: var(--muted); flex: none;
}
.ldh-a-new    { color: #5AD98A; border-color: rgba(90,217,138,0.45); background: rgba(90,217,138,0.1); }
.ldh-a-edit   { color: #5AA9F0; border-color: rgba(90,169,240,0.45); background: rgba(90,169,240,0.1); }
.ldh-a-revert { color: #F0A24E; border-color: rgba(240,162,78,0.45); background: rgba(240,162,78,0.1); }

.ldh-txt  { flex: 1 1 220px; min-width: 0; color: var(--text); }
.ldh-meta { color: var(--muted); font-size: 0.78rem; flex: 0 1 auto; }
.ldh-chev { color: var(--muted); transition: transform 0.18s ease; flex: none; }
.ldh-rev[open] .ldh-chev { transform: rotate(180deg); }

.ldh-body { padding: 0.2rem 0.8rem 0.8rem; border-top: 1px solid var(--line); }
.ldh-note { margin: 0.6rem 0; color: var(--muted); font-size: 0.86rem; font-style: italic; }
.ldh-nodiff { margin: 0.6rem 0 0; color: var(--muted); font-size: 0.86rem; }

/* The diff table can hold long values, so it scrolls sideways inside the
   card rather than widening the modal. */
.ldh-diff { width: 100%; border-collapse: collapse; margin-top: 0.6rem; font-size: 0.82rem; table-layout: fixed; }
.ldh-diff th, .ldh-diff td {
  text-align: left; vertical-align: top; padding: 0.4rem 0.5rem;
  border-top: 1px solid var(--line); word-break: break-word; overflow-wrap: anywhere;
}
.ldh-diff thead th { color: var(--muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; border-top: none; }
.ldh-diff tbody th { width: 26%; color: var(--text); font-weight: 600; }
.ldh-was { color: var(--muted); text-decoration: line-through; text-decoration-color: rgba(224,90,90,0.6); }
.ldh-now { color: var(--text); }

.ldh-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.9rem; }
.ldh-btn {
  font-family: var(--font-display); font-weight: 700; font-size: 0.8rem;
  background: transparent; color: var(--text);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 0.4rem 0.9rem; cursor: pointer; min-height: 34px;
}
.ldh-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.ldh-btn:disabled { opacity: 0.5; cursor: default; }
.ldh-undo { border-color: rgba(240,162,78,0.5); color: #F0A24E; }
.ldh-status { font-size: 0.8rem; color: var(--muted); }

/* The phone rule for .contrib-bar hides every span inside a button to save
   width. The count badge is the one span that IS the information, so it
   stays; the emoji and the words are what can go. */
@media (max-width: 560px) {
  .contrib-btn .contrib-count { display: inline-flex; }
  .ldh-meta { flex-basis: 100%; }
}


/* ============================================================
   EDIT MODE (community editing, lde- prefix)
   ------------------------------------------------------------
   Edit mode replaces #main, so it has to read as a different place. The
   eyebrow, role chip and accent border on each field say "you are editing"
   without a banner. Tier colours travel via data-clr and LD.paint(), same
   as everywhere else - no inline styles.
   ============================================================ */
body.ld-editing .contrib-bar { display: none; }
body.ld-editing .to-top { display: none; }

.lde-wrap { padding-bottom: 3rem; }

.lde-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  flex-wrap: wrap; gap: 0.8rem; margin-bottom: 1.4rem;
  padding-bottom: 1rem; border-bottom: 1px solid var(--line);
}
.lde-head h1 { margin: 0.1rem 0 0; }
.lde-eyebrow {
  font-family: var(--font-display); font-weight: 700; font-size: 0.7rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent);
}
.lde-sub { margin: 0.3rem 0 0; color: var(--muted); font-size: 0.9rem; }
.lde-role {
  font-size: 0.78rem; color: var(--muted); border: 1px solid var(--line);
  border-radius: 999px; padding: 0.35rem 0.8rem; white-space: nowrap;
}
.lde-role-staff { color: #5AD98A; border-color: rgba(90,217,138,0.45); background: rgba(90,217,138,0.08); }

.lde-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem 1.2rem; }
.lde-field {
  display: flex; flex-direction: column; gap: 0.35rem;
  padding-left: 0.8rem; border-left: 2px solid var(--line);
}
.lde-wide { grid-column: 1 / -1; }
.lde-field:focus-within { border-left-color: var(--accent); }
/* A field queued for reset is going to be thrown away on save, so it reads
   as struck out rather than merely highlighted. */
.lde-resetting { border-left-color: #F0A24E; opacity: 0.6; }
.lde-resetting .lde-input { text-decoration: line-through; }

.lde-label-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.lde-label { font-family: var(--font-display); font-weight: 700; font-size: 0.82rem; color: var(--text); }
.lde-help { margin: 0; color: var(--muted); font-size: 0.76rem; line-height: 1.35; }
.lde-reset {
  background: transparent; border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); font-size: 0.7rem; padding: 0.15rem 0.55rem; cursor: pointer; min-height: 24px;
}
.lde-reset:hover { color: #F0A24E; border-color: rgba(240,162,78,0.5); }

.lde-input {
  width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 0.9rem;
  color: var(--text); background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 0.5rem 0.7rem; min-height: 36px;
}
.lde-input:focus { outline: none; border-color: var(--accent); }
.lde-area { resize: vertical; line-height: 1.5; }
.lde-num { max-width: 130px; }
.lde-select { cursor: pointer; }
.lde-check { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; min-height: 36px; cursor: pointer; }
.lde-check input { width: 17px; height: 17px; accent-color: var(--accent); }
/* The label is inside the checkbox, so the row above it would be a duplicate. */
.lde-field:has(.lde-check) > .lde-label-row > .lde-label { display: none; }

.lde-subgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 0.6rem; }
.lde-sub { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.78rem; color: var(--muted); }
.lde-sub .lde-num { max-width: none; }

.lde-locked {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  font-size: 0.84rem; color: var(--muted); background: var(--panel-2);
  border: 1px dashed var(--line); border-radius: 12px; padding: 0.6rem 0.9rem; margin-bottom: 1rem;
}
.lde-locked strong { color: var(--text); }
.lde-locked-why {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em;
  border: 1px solid var(--line); border-radius: 999px; padding: 0.1rem 0.5rem;
}

.lde-sec { margin: 2rem 0 0.2rem; font-size: 1.05rem; }
.lde-sec-sub { margin: 0 0 1rem; color: var(--muted); font-size: 0.84rem; }

.lde-tiercats { display: flex; flex-wrap: wrap; gap: 0.9rem; }
.lde-tiercat {
  display: flex; flex-direction: column; gap: 0.4rem; min-width: 150px;
  border: 1px solid var(--line); border-radius: 12px; padding: 0.6rem 0.7rem;
}
.lde-tiercat-h { font-family: var(--font-display); font-weight: 700; font-size: 0.76rem; color: var(--text); }

/* repeating rows */
.lde-rows { display: flex; flex-direction: column; gap: 0.4rem; }
.lde-row { display: flex; gap: 0.4rem; align-items: center; }
.lde-rowin-k { flex: 0 0 30%; }
.lde-rowin { flex: 1 1 auto; min-width: 0; }
.lde-delrow {
  flex: none; width: 32px; height: 32px; border-radius: 8px; cursor: pointer;
  background: transparent; border: 1px solid var(--line); color: var(--muted);
}
.lde-delrow:hover { color: #E05A5A; border-color: rgba(224,90,90,0.5); }
.lde-addrow {
  align-self: flex-start; margin-top: 0.4rem; background: transparent;
  border: 1px dashed var(--line); border-radius: 999px; color: var(--muted);
  font-size: 0.78rem; padding: 0.35rem 0.8rem; cursor: pointer; min-height: 32px;
}
.lde-addrow:hover { color: var(--accent); border-color: var(--accent); }

/* footer */
.lde-foot { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
.lde-note-lb { display: block; font-family: var(--font-display); font-weight: 700; font-size: 0.82rem; margin-bottom: 0.35rem; }
.lde-note { margin-bottom: 0.9rem; }
.lde-actions { display: flex; align-items: center; justify-content: flex-end; gap: 0.7rem; flex-wrap: wrap; }
.lde-status { margin-right: auto; font-size: 0.84rem; color: var(--muted); }
.lde-status-bad { color: #E05A5A; }

/* ---- tier board ---- */
.lde-tabs { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.8rem; }
.lde-tabs-sub { margin-top: -0.4rem; }
.lde-tab {
  font-family: var(--font-display); font-weight: 700; font-size: 0.8rem;
  background: transparent; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 0.4rem 0.9rem; cursor: pointer; min-height: 34px;
}
.lde-tab.active { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

.lde-board { display: flex; flex-direction: column; gap: 0.5rem; }
.lde-tier { display: flex; align-items: stretch; gap: 0.5rem; }
.lde-tier-lb {
  flex: 0 0 64px; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 800; font-size: 1.05rem;
  color: #10131c; background: var(--dyn, var(--accent));
  border: none; border-radius: 12px; cursor: pointer; min-height: 62px;
}
.lde-tier-slot {
  flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; gap: 0.4rem;
  align-content: flex-start; padding: 0.45rem;
  border: 1px dashed var(--line); border-radius: 12px; min-height: 62px;
}
.lde-tier-slot.is-over { border-color: var(--accent); background: var(--accent-soft); border-style: solid; }
.lde-empty { color: var(--muted); font-size: 0.78rem; align-self: center; padding: 0 0.4rem; }
.lde-bench-h {
  display: flex; align-items: center; gap: 0.5rem; margin: 1.2rem 0 0.4rem;
  font-family: var(--font-display); font-weight: 700; font-size: 0.86rem;
}
.lde-bench-n { color: var(--muted); font-size: 0.78rem; }
.lde-bench-q { margin-left: auto; max-width: 220px; }
.lde-bench { max-height: 320px; overflow-y: auto; }

/* While a drag is live, units stop claiming the gesture so the browser does
   not try to scroll the bench out from under it. Set only during the drag:
   applied all the time it would make the bench unscrollable by touch. */
.is-dragmode .lde-unit, .is-dragmode .lde-tier-slot { touch-action: none; }
.is-dragmode { user-select: none; }

/* The chip that follows the pointer. pointer-events:none is what lets
   elementFromPoint see the drop zone underneath it rather than the ghost. */
.lde-ghost {
  position: fixed; left: 0; top: 0; z-index: 5000;
  pointer-events: none; opacity: 0.92;
  box-shadow: 0 12px 30px rgba(0,0,0,0.55);
  transform: scale(1.04);
}

.lde-unit {
  display: flex; align-items: center; gap: 0.45rem; cursor: grab;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 0.25rem 0.7rem 0.25rem 0.25rem;
  color: var(--text); font-size: 0.8rem; max-width: 190px; min-height: 38px;
}
.lde-unit:hover { border-color: var(--rc, var(--accent)); }
.lde-unit.is-sel { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 2px var(--accent-line); }
.lde-unit.is-dragging { opacity: 0.45; }
.lde-unit-art {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background-size: cover; background-position: center; overflow: hidden;
  border: 1px solid var(--rc, var(--line));
}
.lde-unit-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Once a unit is picked up, the drop zones are the only thing that matters,
   so they are the only thing that lights up. */
.is-picking .lde-tier-slot { border-color: var(--accent-line); }
.is-picking .lde-tier-lb { outline: 2px solid var(--accent-line); outline-offset: 2px; }

/* ============================================================
   GUIDE BLOCK EDITOR (ldb- prefix)
   ------------------------------------------------------------
   Plain inputs producing typed objects, not a rich-text surface. Each block
   is styled as the thing it will become - headings big and in the display
   font, notes tinted like notes, tables a grid of cells - so the form still
   reads as the shape of the page.
   ============================================================ */
.lde-blocks-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.6rem; }
.lde-blocks-head .lde-sec { margin-bottom: 0.6rem; }
.lde-modes { display: flex; gap: 0.4rem; }
.lde-preview { border: 1px dashed var(--line); border-radius: 14px; padding: 1.2rem 1.4rem; }
.lde-empty-blocks { color: var(--muted); font-size: 0.9rem; padding: 0.8rem 0; }

.ldb {
  position: relative; border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel-2); padding: 0.5rem 0.8rem 0.8rem;
}
.ldb:focus-within { border-color: var(--accent); }
.ldb-bar { display: flex; align-items: center; gap: 0.3rem; margin-bottom: 0.4rem; }
.ldb-kind {
  margin-right: auto; font-family: var(--font-display); font-weight: 700;
  font-size: 0.66rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.ldb-btn {
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
  background: transparent; border: 1px solid var(--line); color: var(--muted); font-size: 0.8rem;
}
.ldb-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.ldb-btn:disabled { opacity: 0.3; cursor: default; }
.ldb-btn-del:hover { color: #E05A5A; border-color: rgba(224,90,90,0.5); }
.ldb-body { display: flex; flex-direction: column; gap: 0.4rem; }

.ldb-in {
  width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 0.9rem;
  color: var(--text); background: var(--panel); border: 1px solid var(--line);
  border-radius: 8px; padding: 0.45rem 0.6rem; min-height: 34px; resize: vertical;
}
.ldb-in:focus { outline: none; border-color: var(--accent); }

/* Each block input dressed as its output. */
.ldb-h2 { font-family: var(--font-display); font-weight: 800; font-size: 1.15rem; }
.ldb-h3 { font-family: var(--font-display); font-weight: 700; font-size: 1rem; }
.ldb-p { line-height: 1.6; }
.ldb-note { border-left: 3px solid var(--accent); background: var(--accent-soft); }
.ldb-tip { border-left: 3px solid #5AD98A; background: rgba(90,217,138,0.08); }
.ldb-warn { border-left: 3px solid #F0A24E; background: rgba(240,162,78,0.08); }
.ldb-quote { border-left: 3px solid var(--line); font-style: italic; }
.ldb-by { font-size: 0.8rem; }
.ldb-list { line-height: 1.6; }
.ldb-divider { height: 1px; background: var(--line); margin: 0.6rem 0; }
.ldb-t-divider .ldb-body { padding: 0.3rem 0; }

.ldb-vrow { display: flex; gap: 0.4rem; }
.ldb-prov { flex: 0 0 130px; cursor: pointer; }

.ldb-table { display: flex; flex-direction: column; gap: 0.3rem; overflow-x: auto; }
.ldb-tr { display: flex; gap: 0.3rem; align-items: center; }
.ldb-cell { flex: 1 1 0; min-width: 90px; font-size: 0.84rem; }
.ldb-thead .ldb-cell { font-family: var(--font-display); font-weight: 700; }
.ldb-cellx {
  flex: none; width: 28px; height: 28px; border-radius: 6px;
  background: transparent; border: 1px solid transparent; color: var(--muted); font-size: 0.75rem;
}
button.ldb-cellx { cursor: pointer; border-color: var(--line); }
button.ldb-cellx:hover { color: #E05A5A; border-color: rgba(224,90,90,0.5); }
.ldb-tacts { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.4rem; }
.ldb-tbtn {
  background: transparent; border: 1px dashed var(--line); border-radius: 999px;
  color: var(--muted); font-size: 0.74rem; padding: 0.25rem 0.7rem; cursor: pointer; min-height: 30px;
}
.ldb-tbtn:hover { color: var(--accent); border-color: var(--accent); }

/* Insert points. At rest they are a hairline, so a long guide reads as a
   stack of blocks rather than a stack of buttons; they come forward on
   hover and focus. */
.ldb-insert { position: relative; display: flex; justify-content: center; padding: 0.25rem 0; }
.ldb-insert::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--line); opacity: 0.5;
}
.ldb-add {
  position: relative; background: var(--bg); border: 1px solid var(--line);
  border-radius: 999px; color: var(--muted); font-size: 0.74rem;
  padding: 0.2rem 0.8rem; cursor: pointer; min-height: 30px; opacity: 0.55;
}
.ldb-insert:hover .ldb-add, .ldb-add:focus { opacity: 1; color: var(--accent); border-color: var(--accent); }
.ldb-menu {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  z-index: 30; margin-top: 4px; width: min(420px, 90vw);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); gap: 0.25rem;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 0.4rem; box-shadow: 0 20px 50px rgba(0,0,0,0.45);
}
.ldb-menu[hidden] { display: none; }
.ldb-mi {
  display: flex; align-items: center; gap: 0.4rem; text-align: left;
  background: transparent; border: none; border-radius: 8px;
  color: var(--text); font-size: 0.8rem; padding: 0.4rem 0.5rem; cursor: pointer; min-height: 34px;
}
.ldb-mi:hover { background: var(--accent-soft); color: var(--accent); }
.ldb-mi-ic { width: 18px; text-align: center; color: var(--muted); }

/* ============================================================
   GUIDE BLOCKS AS RENDERED (gb- prefix)
   ============================================================ */
.gb-h3 { font-family: var(--font-display); font-size: 1.02rem; margin: 1.4rem 0 0.4rem; }
.gb-hr { border: none; border-top: 1px solid var(--line); margin: 1.6rem 0; }
.gb-quote {
  margin: 1.2rem 0; padding: 0.6rem 0 0.6rem 1rem;
  border-left: 3px solid var(--accent); color: var(--text); font-style: italic;
}
.gb-quote p { margin: 0; }
.gb-cite { display: block; margin-top: 0.4rem; font-style: normal; font-size: 0.84rem; color: var(--muted); }
.warn {
  margin: 1.2rem 0; padding: 0.8rem 1rem; border-radius: 12px;
  border: 1px solid rgba(240,162,78,0.35); background: rgba(240,162,78,0.08);
}
.warn p { margin: 0.3rem 0 0; }

.gb-fig, .gb-video { margin: 1.4rem 0; }
.gb-img { display: block; width: 100%; height: auto; border-radius: 12px; border: 1px solid var(--line); }
.gb-cap { margin-top: 0.4rem; color: var(--muted); font-size: 0.82rem; text-align: center; }
/* Fixed ratio so the page does not jump as the iframe loads. */
.gb-video-box { position: relative; width: 100%; padding-top: 56.25%; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); }
.gb-video-box iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.gb-table-wrap { overflow-x: auto; margin: 1.2rem 0; }
.gb-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.gb-table th, .gb-table td { text-align: left; padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--line); }
.gb-table thead th {
  font-family: var(--font-display); font-size: 0.74rem; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); background: var(--panel-2);
}
.gb-table tbody tr:hover { background: var(--accent-soft); }

.gb-unit {
  display: inline-flex; align-items: center; gap: 0.55rem; margin: 0.3rem 0.3rem 0.3rem 0;
  background: var(--panel-2); border: 1px solid var(--rc, var(--line));
  border-radius: 999px; padding: 0.3rem 0.9rem 0.3rem 0.3rem; text-decoration: none; color: var(--text);
}
.gb-unit:hover { border-color: var(--accent); }
.gb-unit-art {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  background-size: cover; background-position: center; overflow: hidden;
}
.gb-unit-tx { display: flex; flex-direction: column; line-height: 1.2; }
.gb-unit-n { font-family: var(--font-display); font-weight: 700; font-size: 0.86rem; }
.gb-unit-t { color: var(--muted); font-size: 0.72rem; }

/* ============================================================
   REVIEW QUEUE (control panel Edits tab, ed- prefix)
   ============================================================ */
.ed-card { border: 1px solid var(--line); border-radius: 14px; padding: 0.9rem 1rem; margin-bottom: 0.8rem; background: var(--panel-2); }
.ed-card-stale { border-color: rgba(240,162,78,0.5); }
.ed-top { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.5rem; }
.ed-kind {
  font-family: var(--font-display); font-weight: 700; font-size: 0.66rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  border: 1px solid var(--line); border-radius: 999px; padding: 0.18rem 0.55rem; color: var(--muted);
}
.ed-kind-character { color: #5AA9F0; border-color: rgba(90,169,240,0.45); }
.ed-kind-tierlist { color: #B07CFF; border-color: rgba(176,124,255,0.45); }
.ed-kind-guide { color: #5AD98A; border-color: rgba(90,217,138,0.45); }
.ed-kind-banners { color: #F0C04E; border-color: rgba(240,192,78,0.45); }
.ed-target { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; }
.ed-open { font-size: 0.78rem; color: var(--accent); }
.ed-when { margin-left: auto; color: var(--muted); font-size: 0.78rem; }
.ed-summary { margin: 0 0 0.4rem; font-size: 0.9rem; }
.ed-note { margin: 0 0 0.6rem; font-size: 0.86rem; color: var(--muted); }
.ed-warn { margin: 0 0 0.6rem; font-size: 0.84rem; color: #F0A24E; }
.ed-moved { margin: 0 0 0.6rem; font-size: 0.8rem; color: var(--muted); }
.ed-meta { color: var(--muted); font-size: 0.8rem; margin-top: 0.5rem; }

.ed-diff { width: 100%; border-collapse: collapse; font-size: 0.82rem; table-layout: fixed; margin: 0.4rem 0; }
.ed-diff th, .ed-diff td {
  text-align: left; vertical-align: top; padding: 0.35rem 0.5rem;
  border-top: 1px solid var(--line); word-break: break-word; overflow-wrap: anywhere;
}
.ed-diff thead th { color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; border-top: none; }
.ed-diff tbody th { width: 24%; color: var(--text); font-weight: 600; }
.ed-was { color: var(--muted); }
.ed-now { color: var(--text); }
.ed-conflict th { color: #F0A24E; }
.ed-flag { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: #F0A24E; }
.ed-move { display: inline-flex; flex-wrap: wrap; gap: 0.3rem; margin-right: 0.8rem; }
.ed-move-cat { color: var(--muted); }

.ed-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.8rem; }
.ed-reason { flex: 1 1 240px; min-width: 0; }
.ed-status { font-size: 0.8rem; color: var(--muted); }

.ed-backups { margin-top: 2rem; }
.ed-backup-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin: 0.6rem 0 1rem; }
.ed-snap-label { flex: 1 1 220px; min-width: 0; }
.ed-snap { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.5rem 0; border-top: 1px solid var(--line); }
.ed-snap-lb { font-family: var(--font-display); font-weight: 700; font-size: 0.86rem; }
.ed-snap-meta { flex: 1 1 auto; color: var(--muted); font-size: 0.76rem; }

.ed-exp { border-top: 1px solid var(--line); padding: 0.6rem 0; }
.ed-exp-top { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.ed-exp-src {
  margin: 0.6rem 0 0; max-height: 340px; overflow: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.7rem 0.9rem; font-size: 0.76rem; line-height: 1.5; white-space: pre;
}
.ed-exp-src[hidden] { display: none; }

/* Contributor byline on a guide. Quiet on purpose: it is credit, not a
   headline, and it sits under a line that already names the author. */
.article-contrib { margin: 0.35rem 0 0; color: var(--muted); font-size: 0.82rem; }

/* Owner-only fields, shown disabled rather than hidden. */
.lde-lockchip {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px; padding: 0.1rem 0.5rem;
}
.lde-input:disabled { opacity: 0.55; cursor: not-allowed; }
.lde-catnew { margin-top: 0.35rem; }
.lde-catnew[hidden] { display: none; }

/* Banner cards in the banners editor. */
.ldn {
  display: flex; flex-direction: column; gap: 0.45rem;
  border: 1px solid var(--line); border-radius: 14px; background: var(--panel-2);
  padding: 0.5rem 0.8rem 0.8rem; margin-bottom: 0.6rem;
}
.ldn:focus-within { border-color: var(--accent); }
.ldn-row { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: flex-end; }
.ldn-row .lde-sub { flex: 1 1 140px; }
.ldn-feats { display: flex; flex-direction: column; gap: 0.35rem; padding-top: 0.2rem; }
.ldn-feat { display: flex; gap: 0.4rem; align-items: center; }
.ldn-frar { flex: 0 0 90px; }
.ldn-feats .ldb-tbtn { align-self: flex-start; }

/* Colour swatches in the new-game element and rank rows. */
.lde-swatch { flex: 0 0 46px; padding: 2px; min-height: 34px; cursor: pointer; }

/* A short standing note at the top of a form, for a rule that applies to
   the whole thing rather than to one field. */
.lde-note-box {
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: 12px; padding: 0.7rem 0.9rem; margin-bottom: 1.2rem;
  font-size: 0.86rem; line-height: 1.5;
}

@media (max-width: 700px) {
  .lde-head { flex-direction: column; }
  .lde-tier-lb { flex-basis: 48px; font-size: 0.92rem; }
  .lde-unit { max-width: 100%; }
  /* Dragging across a phone screen is a coin toss, so the hint names the
     interaction that actually works there. */
  .lde-unit { cursor: pointer; }
  .ed-diff tbody th { width: 34%; }
}


/* ============================================================
   TAP TARGETS ON PHONES
   ------------------------------------------------------------
   Measured, not guessed. A 360 / 390 / 414 sweep over home, guides, upcoming,
   the game hub, the character index and a tier list reported the footer social
   links at 16px tall, the "Read more" toggle at 17px, the collapsible-section
   headers at 22px, the grid/list view buttons at 23px, the per-card socials at
   26px, the hype buttons at 30px, the theme swatches at 30px, breadcrumbs at
   16px and the region / status / sort selects at 31px. Anything under about
   34px on a touch screen is a coin toss for a thumb, and every one of these is
   a control a reader is meant to use one-handed.

   The fix is padding and min-height, never font-size. Growing the text would
   reflow the rows these sit in and change how the page reads; growing the box
   around the text changes only what a finger can hit.

   THIS BLOCK LIVES AT THE END OF THE FILE ON PURPOSE. Most of these selectors
   are single-class, so they tie on specificity with the rule they are
   correcting and the later one wins. Put this block higher up and roughly half
   of it silently stops applying - which is exactly what happened on the first
   attempt, and the audit caught it.
   ============================================================ */
@media (max-width: 860px) {
  .footer-social a {
    display: inline-flex; align-items: center;
    min-height: 34px; padding: 0.35rem 0.5rem; margin-right: 0.1rem;
  }
  .crumbs a { display: inline-flex; align-items: center; min-height: 32px; }
  .theme-dot { width: 34px; height: 34px; min-width: 34px; }
  .qnav-more a { min-height: 34px; padding: 0.25rem 0; }
  .sec-head-link, .upd-notes-link {
    display: inline-flex; align-items: center; min-height: 34px;
  }
  .upd-f { min-height: 34px; }
  .bnr-feat { min-height: 38px; }

  /* upcoming.html carries the densest cluster of controls on the site */
  .upg-fpill { min-height: 34px; padding-top: 0.45rem; padding-bottom: 0.45rem; }
  .upg-reset { min-height: 34px; }
  .upg-f-region, .upg-f-status, .upg-f-sort, .lang-select { min-height: 36px; }
  .upg-social-sm { width: 32px; height: 32px; }
  .upg-social { width: 36px; height: 36px; }
  .upg-view-btn { min-height: 34px; padding-top: 0.4rem; padding-bottom: 0.4rem; }
  .upg-sec-toggle { min-height: 40px; padding-top: 0.5rem; padding-bottom: 0.5rem; }
  .hype-btn { min-height: 36px; }
  .upg-readmore { display: inline-flex; align-items: center; min-height: 32px; }

  /* The collapse arrow is a desktop control: it slides the sidebar between full
     and icon width, and below 860px the sidebar is an off-canvas drawer with no
     width to collapse. It was still rendering, costing 42px of a topbar that had
     to ellipsize the wordmark to "LANCED..." to fit. The rule hiding it already
     existed in the 860px block near the top of this file, but the base rule
     further down ties on specificity and wins, so it never applied. */
  .side-collapse { display: none !important; }
}
