/* GachaData design system v2 — "datamine terminal meets game splash".
   Dark-native near-black + intentional light. Heavy condensed ITALIC display type (Archivo),
   hard edges + left accent bars + blueprint grid/scanline texture, saturated per-game accents.
   Re-skins the existing class vocabulary via tokens so every page adopts it. --game = per-game accent. */
:root{
  --sans:"Inter",system-ui,Segoe UI,Roboto,sans-serif;
  --disp:"Archivo","Space Grotesk","Inter",system-ui,sans-serif;   /* heavy condensed italic display */
  --alt:"Space Grotesk",system-ui,sans-serif;                       /* kickers / labels / numerals */
  --r:5px; --r-sm:4px; --maxw:1180px; --read:70ch;
  --t:.2s cubic-bezier(.22,.61,.36,1);
  --brand-ink:#03121b; --rarity:#ffd166;
  --game:#3b82f6; --g1:#3b82f6; --g2:#6366f1;   /* per-game accent, overridden per page/card */
  --good:#34be78; --bad:#ff5468; --neutral:#8791a4;
  --cut:10px;                                    /* default cut-corner size for clip-path motifs */
}
/* ---- DARK (default): rich near-black, saturated accents ---- */
:root,[data-theme="dark"]{
  --bg:#07080d; --bg-soft:#0d1017; --bg-sunk:#0a0c12;
  --panel:#0d1017; --card:#0d1017; --panel-2:#11141c;
  --ink:#e8ecf4; --mut:#aeb9cb; --faint:#8792a3; --dim:#5c6675; --line:rgba(255,255,255,.09);
  --line-strong:rgba(255,255,255,.18);
  --brand:#63e2ff; --brand-blue:#2e8bff; --brand-deep:#2e8bff; --brand-2:#b44cff; --link:#8ab8ff;
  --grid-line:rgba(255,255,255,.045); --scan:rgba(255,255,255,.02);
  --shadow:0 24px 60px -30px rgba(0,0,0,.85);
}
[data-theme="light"]{
  --bg:#eceef5; --bg-soft:#e6e9f1; --bg-sunk:#dfe3ee;
  --panel:#ffffff; --card:#ffffff; --panel-2:#f2f4fa;
  --ink:#0b0f22; --mut:#333a54; --faint:#616a78; --dim:#8791a4; --line:rgba(12,18,40,.14);
  --line-strong:rgba(12,18,40,.30);
  /* --brand carries TEXT (eyebrows, counts, "more" links) and is the fallback --gink resolves to on
     pages with no active game. #0e7fc4 measured 4.33:1 on white and only 3.73:1 on the page background,
     so those failed everywhere in light mode — a base-token defect, not a per-game one. #0069ad is the
     same hue moved along OKLab L until it clears 4.5:1 against bg-sunk (#dfe3ee), the DARKEST light
     surface, so it passes on every one of them: 4.51 sunk / 4.77 soft / 5.00 body / 5.79 white. */
  --brand:#0069ad; --brand-blue:#2064d6; --brand-deep:#2064d6; --brand-2:#8b3ce0; --link:#1662c7;
  --grid-line:rgba(12,18,40,.06); --scan:rgba(12,18,40,.02);
  --shadow:0 24px 50px -30px rgba(30,45,90,.4);
}
/* ---- --gink: the accent that is allowed to carry TEXT ----
   build.py stamps --gink-d/--gink-l on <body> for game pages: the game's accent moved along OKLab L
   until it clears 4.5:1 on that surface (all 23 raw accents fail on at least one; see build.py
   game_ink). These two rules pick the one matching the active theme. Pages with no active game
   (home, guides, about) stamp neither, so --gink falls back to the site brand and nothing changes.
   Use --gink for text; use --game for borders, glows, bars and fills, where contrast doesn't apply. */
body{--gink:var(--gink-d,var(--brand))}
[data-theme="light"] body{--gink:var(--gink-l,var(--brand))}
/* Furigana from the games' own strings (build.py strip_richtext turns <ruby=かんえん>寒炎</ruby> into
   real markup). Browsers render <ruby> natively; the default <rt> is large enough to stretch the line
   box, so damp it and let it overhang rather than reflow the paragraph around it. */
ruby{ruby-align:center}
rt{font-size:.58em;font-weight:400;opacity:.85;user-select:none}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.55 var(--sans);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden;position:relative}
/* fixed backdrop: fine blueprint grid + scanlines = "live index" texture */
body::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:linear-gradient(var(--grid-line) 1px,transparent 1px) 0 0/100% 56px,
            linear-gradient(90deg,var(--grid-line) 1px,transparent 1px) 0 0/56px 100%;
  mask:radial-gradient(135% 90% at 50% -6%,#000 42%,transparent 100%)}
body::after{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:repeating-linear-gradient(0deg,var(--scan) 0 1px,transparent 1px 3px);opacity:.7}
a{color:var(--link);text-decoration:none}a:hover{text-decoration:underline}
/* WCAG 1.4.1 (Use of Color): a link inside running text must be distinguishable WITHOUT colour, or a
   reader who can't separate the link hue from the body hue sees no link at all. Structural links keep
   text-decoration:none because they carry their own affordance — a card, a chip, a button, a nav item, a
   table row heading all read as clickable from their box. This underlines only links sitting in prose. */
p a,li a,dd a,figcaption a,blockquote a,.lead a,.g-body a,td a{text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:.06em;
  text-decoration-color:color-mix(in srgb,currentColor 45%,transparent)}
p a:hover,li a:hover,dd a:hover,.lead a:hover,.g-body a:hover,td a:hover{text-decoration-color:currentColor}
/* …but never on links that ARE a component — those live inside prose containers on some pages. */
p a.btn,li a.btn,td a.btn,p a.chip,li a.chip,td a.chip,p a.dschip,li a.dschip,td a.dschip,
p a.poolchip,li a.poolchip,td a.poolchip,p a.cmp,li a.cmp,p a.apilink,li a.apilink,td a.apilink,
p a.morelink,li a.morelink,p a.guide-c,li a.guide-c,p a.gdlink,li a.gdlink,p a.ccard,li a.ccard,
td a.ccard,p a.toolcard,li a.toolcard{text-decoration:none}
img{display:block}
main,nav,footer,section,header{position:relative;z-index:1}
/* faint game-art atmosphere behind inner game sub-pages (database, datasets, changelog, optimizer, detail):
   the game's own promo scene at the top, fading out, so every section feels like ITS game. */
.page-scene{position:absolute;top:0;left:0;right:0;height:520px;z-index:0;pointer-events:none;
  background-size:cover;background-position:center 22%;opacity:.20;filter:saturate(1.15) contrast(1.02);
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 30%,transparent 96%);
  mask-image:linear-gradient(180deg,#000 0,#000 30%,transparent 96%)}
[data-theme="light"] .page-scene{opacity:.14}
h1,h2,h3{font-family:var(--disp);font-weight:800;font-style:italic;text-transform:uppercase;
  line-height:.94;letter-spacing:-.015em;margin:0 0 .4em}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 26px}
.muted{color:var(--mut)}.faint{color:var(--faint)}
.disp{font-family:var(--disp);font-weight:800;font-style:italic;text-transform:uppercase;letter-spacing:-.015em;line-height:.92}
.eyebrow{display:inline-flex;align-items:center;gap:8px;font:600 12px/1 var(--alt);letter-spacing:.18em;
  text-transform:uppercase;color:var(--gink);padding:7px 12px;border:1px solid color-mix(in srgb,var(--gink) 40%,transparent);background:transparent;
  clip-path:polygon(8px 0,100% 0,100% 100%,0 100%,0 8px)}
.eyebrow::before{content:"";width:7px;height:7px;background:var(--gink);box-shadow:0 0 8px var(--gink)}
/* keep tight-line-height display headlines clear of the eyebrow chip above them (no glyph overlap) */
.eyebrow + h1,.eyebrow + h2{margin-top:.3em}

/* nav */
.nav{position:sticky;top:0;z-index:40;background:color-mix(in srgb,var(--bg) 74%,transparent);
  backdrop-filter:blur(16px) saturate(150%);border-bottom:1px solid var(--line)}
.nav .wrap{display:flex;align-items:center;gap:22px;height:60px}
.brand{font-family:var(--disp);font-weight:800;font-style:italic;text-transform:uppercase;font-size:20px;
  letter-spacing:-.02em;color:var(--ink);display:flex;gap:9px;align-items:center}
.brand .dot{width:16px;height:16px;flex:none;background:linear-gradient(135deg,var(--brand-blue),var(--brand-2));
  clip-path:polygon(0 0,100% 0,100% 70%,70% 100%,0 100%);box-shadow:0 0 16px -4px var(--brand-blue)}
.nav a.link{color:var(--mut);font:600 13px/1 var(--alt);letter-spacing:.03em;text-transform:uppercase}
.nav a.link:hover,.nav a.link[aria-current]{color:var(--ink);text-decoration:none}
.nav .spacer{flex:1}
/* Games dropdown — a single constant-width entry that scales to any number of games (scrollable menu).
   Hover / focus-within opens it; the trigger itself links to the full /games/ hub (mobile taps go there). */
.navdrop{position:relative;display:flex;align-items:center}
.navdrop .caret{font-size:7px;opacity:.7;margin-left:2px}
.navdrop .navmenu{position:absolute;top:100%;left:0;margin-top:9px;min-width:230px;max-height:70vh;overflow:auto;
  background:var(--panel);border:1px solid var(--line-strong);box-shadow:var(--shadow);padding:6px;
  display:flex;flex-direction:column;gap:1px;z-index:50;clip-path:polygon(9px 0,100% 0,100% 100%,0 100%,0 9px);
  opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .16s ease,transform .16s ease,visibility 0s .16s}
.navdrop .navmenu a{white-space:nowrap}
/* transparent hover bridge fills the 9px gap so trigger->menu keeps :hover (no flicker / dead zone) */
.navdrop .navmenu::before{content:"";position:absolute;left:0;right:0;top:-11px;height:12px}
.navdrop:hover .navmenu,.navdrop:focus-within .navmenu{opacity:1;visibility:visible;transform:none;transition:opacity .16s ease,transform .16s ease}
.navdrop .navmenu a{padding:9px 12px;color:var(--mut);font:600 12.5px/1.1 var(--alt);letter-spacing:.03em;text-transform:uppercase}
.navdrop .navmenu a:hover,.navdrop .navmenu a[aria-current]{color:var(--ink);background:var(--bg-sunk);text-decoration:none}
.navdrop .navmenu a.all{border-top:1px solid var(--line);margin-top:4px;padding-top:11px;color:var(--brand)}
.iconbtn{border:1px solid var(--line);background:var(--panel);color:var(--mut);border-radius:var(--r-sm);
  min-width:34px;height:34px;padding:0 10px;cursor:pointer;font:600 12px/1 var(--alt);letter-spacing:.05em;
  text-transform:uppercase;display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:var(--t)}
.iconbtn svg{width:15px;height:15px;display:block;flex:none}
.iconbtn:hover{color:var(--ink);border-color:var(--line-strong)}
/* language picker menu */
.langwrap{position:relative;display:inline-flex}
.langmenu{position:absolute;top:calc(100% + 8px);right:0;min-width:152px;z-index:60;background:var(--panel);
  border:1px solid var(--line-strong);box-shadow:var(--shadow);padding:6px;display:flex;flex-direction:column;gap:1px;
  opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .16s ease,transform .16s ease,visibility 0s .16s;
  clip-path:polygon(9px 0,100% 0,100% 100%,0 100%,0 9px)}
.langwrap.on .langmenu{opacity:1;visibility:visible;transform:none;transition:opacity .16s ease,transform .16s ease}
.langmenu button{text-align:left;background:none;border:0;color:var(--mut);cursor:pointer;
  font:600 13px/1.1 var(--alt);letter-spacing:.02em;padding:9px 12px}
.langmenu button:hover{background:var(--bg-sunk);color:var(--ink)}
.langmenu button[aria-current="true"]{color:var(--brand)}

/* buttons — hard clipped, display italic */
.btn{font-family:var(--disp);font-weight:800;font-style:italic;font-size:15px;text-transform:uppercase;letter-spacing:-.01em;
  display:inline-flex;align-items:center;gap:9px;padding:13px 22px;cursor:pointer;border:1px solid transparent;
  transition:var(--t);text-decoration:none;position:relative}
.btn svg{width:17px;height:17px}
/* On a game page the CTA wears that game's own gradient; --gon is the black-or-white foreground
   build.py picked by measuring BOTH gradient endpoints. --cta1/--cta2/--gon are stamped only when a
   game is active (they are absent from :root on purpose), so every other page keeps the brand blue. */
.btn.primary{color:var(--gon,#fff);background:linear-gradient(92deg,var(--cta1,var(--brand-blue)),var(--cta2,#4a6bff));
  clip-path:polygon(11px 0,100% 0,100% calc(100% - 11px),calc(100% - 11px) 100%,0 100%,0 11px)}
.btn.primary:hover{filter:brightness(1.12);text-decoration:none;
  box-shadow:0 10px 26px -10px color-mix(in srgb,var(--cta1,var(--brand-blue)) 70%,transparent)}
.btn.ghost{background:var(--panel);border-color:var(--line-strong);color:var(--ink);
  clip-path:polygon(9px 0,100% 0,100% 100%,0 100%,0 9px)}
.btn.ghost:hover{border-color:var(--brand);text-decoration:none}

/* hero (generic; homepage has its own richer hero) */
.hero{padding:56px 0 36px;position:relative}
.hero h1{font-size:clamp(38px,6.4vw,76px);max-width:15ch;margin:.2em 0 0}
.hero .grad,.grad{color:transparent;background:linear-gradient(96deg,var(--brand),var(--brand-deep) 80%);
  -webkit-background-clip:text;background-clip:text}
.hero p.lead,.lead{font-size:clamp(16px,2.1vw,19px);color:var(--mut);max-width:54ch;margin:1.1em 0 1.4em}
.lead b{color:var(--ink);font-weight:600}
.hero .cta,.cta{display:flex;gap:12px;flex-wrap:wrap}

/* sections + accent-bar section headers */
section{padding:42px 0}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:20px;
  padding-left:16px;border-left:3px solid var(--brand)}
.sec-head h2{font-size:clamp(24px,3.4vw,34px);margin:0}
h2,h3{position:relative}

/* game cards / hub */
.grid{display:grid;gap:16px}
.grid.cards{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px}
.grid.hub{grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:16px}
/* GAME BANNER (gachabase-style): the game's key art full-bleed, an angled dark name-tab on the left,
   accent gradient behind, a corner LIVE ribbon + arrow. The whole card IS the banner. */
.gbanner{position:relative;display:block;height:178px;overflow:hidden;text-decoration:none;color:#fff;
  background:linear-gradient(115deg,var(--g1),var(--g2));border:1px solid var(--line);transition:var(--t);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 16px),calc(100% - 16px) 100%,0 100%)}
.gbanner:hover{transform:translateY(-3px);text-decoration:none;border-color:var(--line-strong);
  box-shadow:0 20px 40px -18px color-mix(in srgb,var(--g1) 55%,#000)}
.gbanner::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background:repeating-linear-gradient(0deg,rgba(255,255,255,.045) 0 1px,transparent 1px 3px)}
/* the key art: the game's cover image, pinned to the right and bleeding off, upper body / face visible */
.gb-art{position:absolute;inset:0;overflow:hidden}
.gb-art.noart{display:none}
/* full landscape promo scene fills the whole banner (gachabase-style) */
.gb-art>img.gb-scene{width:100%;height:100%;object-fit:cover;object-position:center 28%;
  filter:saturate(1.06) contrast(1.02);transition:var(--t)}
/* single-character cover (fallback): pinned right, face-aligned */
.gb-art>img:not(.gb-scene){position:absolute;top:0;right:0;width:58%;height:100%;object-fit:cover;
  object-position:center top;filter:saturate(1.05) contrast(1.02);transition:var(--t)}
.gbanner:hover .gb-art>img{transform:scale(1.04)}
.gb-scrim{position:absolute;inset:0;z-index:1;
  background:linear-gradient(100deg,color-mix(in srgb,var(--g1) 94%,#05060a) 0,color-mix(in srgb,var(--g1) 60%,transparent) 38%,transparent 68%),
            linear-gradient(0deg,rgba(0,0,0,.42),transparent 45%)}
/* left name-tab (gachabase's black plate) */
.gb-tab{position:absolute;left:0;bottom:0;z-index:3;padding:16px 22px 14px 20px;max-width:74%}
.gb-name{display:block;font-family:var(--disp);font-weight:800;font-style:italic;text-transform:uppercase;
  font-size:clamp(20px,2.6vw,26px);line-height:.98;letter-spacing:-.01em;color:#fff;text-shadow:0 2px 14px rgba(0,0,0,.6)}
.gb-meta{display:block;margin-top:5px;font:600 12.5px/1 var(--alt);letter-spacing:.02em;color:rgba(255,255,255,.9);
  font-variant-numeric:tabular-nums;text-shadow:0 1px 8px rgba(0,0,0,.6)}
.gb-meta span{opacity:.8}
.gb-go{position:absolute;left:20px;top:16px;z-index:3;width:30px;height:30px;display:grid;place-items:center;
  font-size:16px;color:#fff;background:rgba(0,0,0,.32);border:1px solid rgba(255,255,255,.28);
  clip-path:polygon(6px 0,100% 0,100% 100%,0 100%,0 6px);transition:var(--t)}
.gbanner:hover .gb-go{background:rgba(0,0,0,.5);transform:translateX(3px)}
.gb-status{position:absolute;right:0;top:0;z-index:3;font:700 10px/1 var(--alt);text-transform:uppercase;
  letter-spacing:.1em;padding:6px 12px 6px 16px;color:#fff;
  clip-path:polygon(10px 0,100% 0,100% 100%,0 100%)}
.gb-status.live{background:color-mix(in srgb,var(--good) 82%,#000)}
.gb-status.soon{background:rgba(0,0,0,.4)}
/* art-less banner (no cover yet) — clean accent gradient + sheen, no character */
.gcover.plain{position:absolute;inset:0}
.gcover.plain .gcv-scrim{position:absolute;inset:0;background:
  radial-gradient(120% 140% at 90% -10%,color-mix(in srgb,#fff 20%,transparent),transparent 55%),
  linear-gradient(115deg,transparent 0 47%,rgba(255,255,255,.10) 48% 50%,transparent 51%)}
.status{display:none}  /* legacy card status pill — replaced by .gb-status */

/* steps / why-us */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.step{padding:20px;border:1px solid var(--line);border-left:3px solid var(--brand);background:var(--panel)}
.step .n{font:700 12px/1 var(--alt);color:var(--gink);letter-spacing:.06em;text-transform:uppercase}
.step h3{font-size:18px;margin:.5em 0 .3em}
@media(max-width:760px){.steps{grid-template-columns:1fr}}

/* character roster cards */
/* character card — v2 horizontal (portrait left, info right, left accent bar, top-right cut) */
.ccard{position:relative;display:flex;border:1px solid var(--line);border-left:3px solid var(--ac,var(--game));
  background:var(--card);overflow:hidden;transition:var(--t);text-decoration:none;color:var(--ink);min-height:104px;
  /* skip layout/paint for off-screen roster cards — large rosters (Dokkan ~2,100 cards) otherwise pay full
     render cost for the whole list up front. contain-intrinsic-size matches min-height so the scrollbar is stable. */
  content-visibility:auto;contain-intrinsic-size:auto 104px;
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,100% 100%,0 100%)}
.ccard:hover{border-color:var(--line-strong);border-left-color:var(--ac,var(--game));transform:translateY(-3px);
  text-decoration:none;box-shadow:0 10px 26px -12px color-mix(in srgb,var(--ac,var(--game)) 34%,#000)}
.ccard .mark{position:relative;flex:none;width:96px;overflow:hidden;display:grid;place-items:center;
  font-family:var(--disp);font-weight:800;font-style:italic;font-size:22px;color:#fff;
  background:linear-gradient(160deg,color-mix(in srgb,var(--ac,var(--game)) 30%,var(--card)),var(--card))}
.mark-img{width:100%;height:100%;object-fit:cover;object-position:top;display:block;filter:saturate(1.08)}
.ccard .mark::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent 55%,var(--card) 100%)}
.ccard .cc-info{flex:1;min-width:0;padding:11px 14px;display:flex;flex-direction:column;justify-content:center;gap:7px}
.ccard .cc-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.ccard .nm{font-size:14.5px;font-weight:650;letter-spacing:-.01em;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* per-card epithet/title (distinguishes same-named entries, e.g. Dokkan's many "Super Saiyan Goku") */
/* The epithet is TEXT on --card, which is WHITE in light mode -- so it takes the derived per-card
   ink, not the raw rarity colour (Dokkan SSR orange scored 2.16:1 there). --ac keeps the border. */
.ccard .cc-sub{font-size:11px;font-weight:600;line-height:1.15;margin-top:-3px;color:var(--acd,var(--gink));
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:.9}
[data-theme="light"] .ccard .cc-sub{color:var(--acl,var(--gink))}
.ccard .stars{color:var(--rarity);font-size:11.5px;letter-spacing:1px;flex:none}
.stars{color:var(--rarity);font-size:12.5px;letter-spacing:1px}
.cc-chips{display:flex;flex-wrap:wrap;gap:5px}
.chip{display:inline-block;font-size:11px;padding:2px 9px;border:1px solid var(--line);color:var(--mut);
  border-radius:2px;font-weight:500}
.cc-chips .chip{font-size:10px;padding:2px 7px;border-radius:0;clip-path:polygon(4px 0,100% 0,100% 100%,0 100%,0 4px)}
.cc-chips .chip.acc{color:var(--ac,var(--game));border-color:var(--ac,var(--game))}
.chip.solid{background:var(--bg-sunk);color:var(--ink)}

/* ---- .ccard.port — the CHARACTER roster tile ----
   The horizontal card above cropped a portrait illustration into a 96px strip and then faded half of
   it out, so a roster of drawn characters read as a list of text with a smudge beside it. Portrait
   tiles give the art the whole card and fit more units per screen. Every managed game is >=93% art-
   covered (checked before this was written), so the monogram path is the exception, not the norm.
   Scoped to `.port` on purpose: .ccard is shared with dataset entries, raid bosses and meta cards,
   which are genuinely textual and must keep the horizontal layout. */
/* SIX per row, pinned — not auto-fill. With a min track the column count floats with the window:
   6 at 1180 content but only 4 at ~800, which is what a normal laptop window gives. Shrinking the
   min track to force 6 there pushed wide screens to 9. An explicit count is 6 at every desktop
   width, and --maxw:1180 caps the container so the tiles never grow past ~187px. */
.grid.cards.roster{grid-template-columns:repeat(6,minmax(0,1fr));gap:12px}
@media(max-width:719px){.grid.cards.roster{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}}
@media(max-width:520px){.grid.cards.roster{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}}
@media(max-width:340px){.grid.cards.roster{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}}
.ccard.port{flex-direction:column;min-height:0;border-left-width:1px;
  contain-intrinsic-size:auto 268px;
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,100% 100%,0 100%)}
.ccard.port .mark{width:100%;aspect-ratio:3/4;height:auto;
  border-bottom:3px solid var(--ac,var(--game));font-size:34px}
.ccard.port .mark-img{object-position:top center}
/* bottom-up scrim so the rank badge and any art edge sit on something, replacing the side fade */
.ccard.port .mark::after{background:linear-gradient(to top,color-mix(in srgb,var(--card) 92%,transparent) 0,transparent 34%)}
.ccard.port .cc-info{flex:none;padding:9px 10px 10px;gap:5px;justify-content:flex-start}
.ccard.port .cc-top{display:block}
.ccard.port .nm{display:block;font-size:13.5px;font-weight:700}
.ccard.port .cc-sub{margin-top:1px}
/* rarity moves onto the art (top-right); the accent chip becomes a rank badge (top-left) */
.ccard.port .stars{position:absolute;top:6px;right:8px;z-index:2;font-size:11px;
  text-shadow:0 1px 3px rgba(0,0,0,.9)}
/* At this width a two-chip row wraps on longer labels ("Incantation Medic" + "Ranged"), which made
   card heights ragged and the grid look broken. Reserve the two-line height always, so a card that
   wraps and one that does not are the same height and the rows stay aligned. */
.ccard.port .cc-chips{gap:3px;min-height:29px;align-content:flex-start}
.ccard.port .cc-chips .chip{font-size:9.5px;padding:1.5px 6px;letter-spacing:.01em}
.ccard.port .cc-chips .chip.acc{position:absolute;top:5px;left:6px;z-index:2;font-size:10px;
  font-weight:800;padding:1px 6px;background:rgba(6,7,11,.74);backdrop-filter:blur(3px)}
.ccard.port:hover .mark-img{transform:scale(1.04)}
.ccard.port .mark-img{transition:transform .35s cubic-bezier(.22,.61,.36,1)}
@media(prefers-reduced-motion:reduce){.ccard.port:hover .mark-img{transform:none}}

/* data viz helpers */
.eff{font:700 11px/1 var(--alt);padding:2px 6px;border-radius:2px;margin-left:5px;vertical-align:middle}
.eff.x2{background:color-mix(in srgb,var(--good) 16%,transparent);color:var(--good)}
.eff.x05{background:color-mix(in srgb,var(--bad) 14%,transparent);color:var(--bad)}
.eff.x1{background:var(--bg-sunk);color:var(--mut)}
.bar{height:7px;background:var(--bg-sunk);overflow:hidden;border-radius:2px}
.bar>i{display:block;height:100%;background:linear-gradient(90deg,var(--game),color-mix(in srgb,var(--game) 40%,var(--good)))}
.count-lg{font-family:var(--disp);font-weight:800;font-style:italic;font-size:clamp(28px,4vw,44px);line-height:1;
  font-variant-numeric:tabular-nums}

/* filter bar */
.filters{position:sticky;top:60px;z-index:10;background:color-mix(in srgb,var(--bg-soft) 92%,transparent);
  backdrop-filter:blur(10px);border:1px solid var(--line);padding:14px;display:flex;gap:10px;flex-wrap:wrap;
  margin-bottom:16px;clip-path:polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)}
input[type=search]{flex:1}
select,input[type=search]{background:var(--panel);color:var(--ink);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:9px 14px;font:500 14px var(--sans);transition:var(--t)}
input[type=search]{min-width:220px}
select{appearance:none;-webkit-appearance:none;padding-right:32px;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--mut) 50%),linear-gradient(135deg,var(--mut) 50%,transparent 50%);
  background-position:calc(100% - 16px) 55%,calc(100% - 11px) 55%;background-size:5px 5px,5px 5px;background-repeat:no-repeat}
select:hover,input[type=search]:hover{border-color:var(--game)}
select:focus,input[type=search]:focus{border-color:var(--game);outline:none;
  box-shadow:0 0 0 3px color-mix(in srgb,var(--game) 20%,transparent)}
/* ---- DATABASE page ---- */
.db-head{border-bottom:1px solid var(--line);
  background:linear-gradient(120deg,color-mix(in srgb,var(--brand-blue) 12%,transparent),transparent 55%)}
.db-head .crumb{padding-top:22px}
.db-head h1{margin:.16em 0 0;font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;
  letter-spacing:-.02em;font-size:clamp(30px,5vw,44px);line-height:.95}
.db-head .db-sub{margin:8px 0 22px;color:var(--faint);font-size:14.5px;font-variant-numeric:tabular-nums}
.db-body{padding:22px 0 64px}
.db-count{display:flex;align-items:center;gap:12px;margin:4px 2px 16px}
.db-count #cnt{font-family:var(--alt);font-weight:700;font-size:13px;letter-spacing:.16em;text-transform:uppercase;color:var(--gink)}
.db-count .rule{flex:1;height:1px;background:var(--line)}

/* tables */
table.data{width:100%;border-collapse:collapse;font-size:14px}
table.data td,table.data th{border:1px solid var(--line);padding:8px 11px;text-align:center;font-variant-numeric:tabular-nums}
table.data th{font:700 11px/1.2 var(--alt);text-transform:uppercase;letter-spacing:.05em;color:var(--faint);background:var(--bg-sunk)}
table.data td:first-child,table.data th:first-child{text-align:left;color:var(--mut)}
table.data .best{color:var(--rarity);font-weight:700}

/* panels / optimizer */
.split{display:grid;grid-template-columns:1fr 360px;gap:20px;align-items:start}
.panel{border:1px solid var(--line);background:var(--panel);padding:18px;box-shadow:var(--shadow);
  position:sticky;top:84px;clip-path:polygon(10px 0,100% 0,100% 100%,0 100%,0 10px)}
.panel h3{font-size:17px;font-style:italic}
.fight{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px}
.fight label{display:block;font:600 11px/1 var(--alt);text-transform:uppercase;letter-spacing:.05em;color:var(--mut);margin-bottom:5px}
.fight select{width:100%}
.team{display:flex;flex-wrap:wrap;gap:6px;min-height:34px}
.slot{font-size:13px;background:var(--bg-sunk);border:1px solid var(--line);border-radius:var(--r-sm);padding:4px 9px;cursor:pointer}
/* game-formation slots: each shows its role label above the unit (or a "+ add" placeholder) */
.team .slot{display:flex;flex-direction:column;gap:1px;min-width:74px;line-height:1.15;padding:5px 9px}
.team .slot em{font-style:normal;font:700 9px/1 var(--alt);letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
.team .slot.filled{border-color:color-mix(in srgb,var(--game) 45%,var(--line));background:color-mix(in srgb,var(--game) 8%,var(--bg-sunk))}
.team .slot.filled .rm{color:var(--faint);font-weight:400;margin-left:2px}
.team .slot.filled:hover .rm{color:var(--gink)}
.team .slot.open{cursor:default;border-style:dashed;opacity:.72}
/* A pick seated in a slot its unit type cannot legally occupy (Blue Archive: a Special in a Striker
   slot). Marked rather than hidden — dropping it would make an illegal team look complete. */
.team .slot.filled.bad{border-color:color-mix(in srgb,var(--bad) 62%,transparent);
  background:color-mix(in srgb,var(--bad) 12%,var(--bg-sunk))}
.team .slot.filled.bad em{color:var(--bad)}
/* Verdict on the formation, in the game's own words — only rendered where a rule exists. */
.frm{flex-basis:100%;margin-top:8px;font:600 12.5px/1.35 var(--sans);display:flex;gap:7px;align-items:flex-start}
.frm.ok{color:var(--good)}
.frm.warn{color:var(--bad)}
.team .slot.open .ph{color:var(--faint);font-size:12px}
/* A/B team switch — which team the roster's "+" is filling. The builder holds two teams so it can
   answer "which of these is better"; the compare screen hides this (it has no teams, just units). */
.sides{display:flex;gap:4px;margin:0 0 8px}
.side{flex:1;font:600 12px/1 var(--alt);letter-spacing:.04em;text-transform:uppercase;padding:7px 6px;
  cursor:pointer;color:var(--faint);background:var(--bg-sunk);border:1px solid var(--line);
  border-radius:var(--r-sm);transition:color .15s,border-color .15s,background .15s}
.side:hover{color:var(--gink)}
.side.on{color:var(--gink);border-color:color-mix(in srgb,var(--game) 55%,var(--line));
  background:color-mix(in srgb,var(--game) 12%,var(--bg-sunk))}
/* Team A vs Team B verdict header — two scores side by side, the leader carrying the rarity accent
   already used for a winning cell in a compare table. */
.vs-score{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:14px}
.vs-score>div{text-align:center;padding:10px 6px;background:var(--bg-sunk);border:1px solid var(--line);
  border-radius:var(--r-sm)}
.vs-score>div.best{border-color:color-mix(in srgb,var(--rarity) 55%,var(--line))}
.vs-score b{display:block;font:700 30px/1 var(--disp)}
.vs-score>div.best b{color:var(--rarity)}
.vs-score span{font:600 10px/1 var(--alt);letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
table.vs-t td:first-child{white-space:nowrap}
.fit{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:center;padding:7px 0;border-bottom:1px solid var(--line);cursor:pointer}
.row{display:flex;justify-content:space-between;font-size:13px;color:var(--mut);padding:3px 0}
.ok{color:var(--good)}.warn{color:var(--bad)}
@media(max-width:860px){.split{grid-template-columns:1fr}.panel{position:static}
  /* the tool's controls/result live in the aside; on mobile the roster (main) is thousands of px tall, so
     without this the tool panel is buried far below the fold and every tool looks "dead". Surface it first. */
  .split>aside{order:-1;margin-bottom:6px}}

/* game header band — condensed italic splash, per-game accent */
.ghead{position:relative;overflow:hidden;color:#fff;padding:48px 0 40px;margin-bottom:8px;
  background:linear-gradient(120deg,color-mix(in srgb,var(--g1) 82%,#05060a),color-mix(in srgb,var(--g2) 78%,#05060a));
  border-bottom:1px solid var(--line)}
.ghead::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:repeating-linear-gradient(0deg,rgba(255,255,255,.05) 0 1px,transparent 1px 3px)}
.ghead .wrap{position:relative;z-index:2}
/* per-game header SCENE: the game's official landscape promo key visual, full-bleed behind the whole
   header, cropped to fill. Every game landing opens on ITS own key art. Absent -> plain accent gradient.

   The scrim's job is LEGIBILITY, not decoration. It used to be an accent wash — `--g1` at 82% opacity,
   i.e. flat opaque game-colour, only clearing at 66% across — laid over art that is already dark and
   already composed. The result read as an empty coloured gradient with the illustration lost inside it.
   Now the left edge is near-black (which is what white display type actually needs behind it) carrying
   only a hint of `--g1`, and it clears sooner so the art occupies the right half honestly.

   `--scene-y` anchors the vertical crop. The default was 22%, which framed the empty sky/ceiling most
   key visuals leave above their subject and cut the characters off; ~40% lands on the figures. Games
   whose art is composed differently override it per-slug below rather than by re-cropping the file. */
.ghead.has-scene{background:#0a0c14}
.ghead-scene{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.ghead-scene img{width:100%;height:100%;object-fit:cover;object-position:center var(--scene-y,40%);
  filter:saturate(1.06) contrast(1.02)}
.ghs-scrim{position:absolute;inset:0;
  background:linear-gradient(90deg,color-mix(in srgb,#05060a 82%,var(--g1)) 0,color-mix(in srgb,#05060a 34%,transparent) 30%,transparent 60%),
            linear-gradient(0deg,color-mix(in srgb,#05060a 82%,var(--g1)) 0,color-mix(in srgb,#05060a 26%,transparent) 20%,transparent 46%)}
/* The mobile header is shorter, so it shows a narrower band and wants to sit slightly higher than desktop
   — the same -6% offset the default pair (40/34) encodes. Deriving it keeps that relationship for the
   per-game overrides too; emitting an explicit --scene-y-sm alongside --scene-y silently dropped the
   offset and gave e.g. Dokkan the desktop 70% on a band that isn't the desktop band. */
/* max() clamps the derived value at 0: a game anchored at the very top (Wuthering Waves is 0%, its
   faces sit right under the cropped-off logo) would otherwise derive -6%, which pushes the image past
   its own edge. */
@media(max-width:640px){.ghead-scene img{object-position:center max(0%,calc(var(--scene-y,40%) - 6%))}}
.ghead{padding:60px 0 42px}
.ghead h1{color:#fff;margin:.28em 0 0;font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;
  letter-spacing:-.02em;line-height:.92;font-size:clamp(38px,7vw,80px);
  text-shadow:0 4px 40px color-mix(in srgb,var(--g1) 45%,transparent)}
/* The eyebrow sits high-left over whatever the scene happens to put there. On a dark key visual a
   transparent chip was fine; over Blue Archive's bright sky the patch/date line washed out entirely.
   It carries its own backdrop now (same treatment as .ghead-stats) so it stays readable on ANY scene
   instead of the hero having to be darkened globally to protect one line of text. */
/* The hero is dark in BOTH themes (white text over a key visual + a 66% scrim), so it takes the
   DARK-surface ink specifically -- plain --gink would hand light mode a dark gold on a dark hero. */
.ghead .eyebrow{color:var(--gink-d,#8fe0ff);background:rgba(7,8,13,.66);
  border-color:color-mix(in srgb,var(--gink-d,#8fe0ff) 42%,transparent)}
.ghead .eyebrow::before{background:var(--gink-d,#8fe0ff);box-shadow:0 0 8px var(--gink-d,#8fe0ff)}
.ghead .sub{color:rgba(255,255,255,.9);font-variant-numeric:tabular-nums;max-width:54ch;margin-top:16px}
.ghead .gh-countnote{margin-top:8px;font-size:13px;color:rgba(255,255,255,.72)}
.ghead-row{display:flex;align-items:flex-end;justify-content:space-between;gap:32px;flex-wrap:wrap}
.ghead-main{flex:1;min-width:320px}
.ghead-cta{display:flex;gap:12px;margin-top:24px;flex-wrap:wrap}
.ghead .btn.ghost{background:rgba(7,8,13,.45);border-color:rgba(255,255,255,.3);color:#fff}
.ghead .btn.ghost:hover{border-color:var(--gink-d,#63e2ff);color:var(--gink-d,#63e2ff)}
.ghead-stats{display:flex;flex:none;border:1px solid rgba(255,255,255,.18);background:rgba(7,8,13,.55);backdrop-filter:blur(8px);
  clip-path:polygon(14px 0,100% 0,100% 100%,0 100%,0 14px)}
.ghead-stats .s{padding:15px 22px;border-right:1px solid rgba(255,255,255,.12)}
.ghead-stats .s:last-child{border-right:0}
.ghead-stats .n{font-family:var(--alt);font-weight:700;font-size:26px;line-height:1;color:#fff;font-variant-numeric:tabular-nums}
.ghead-stats .n.hot{color:var(--gink-d,#63e2ff)}
.ghead-stats .k{font-family:var(--sans);font-weight:600;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(255,255,255,.6);margin-top:5px}
@media(max-width:760px){.ghead-stats{width:100%}.ghead-stats .s{flex:1}}
/* ---- GAME HUB main content: Tools / Datasets / Recently added ---- */
.hub-sec{padding:52px 0 0}
.hub-head{display:flex;align-items:baseline;gap:14px;margin-bottom:20px}
.hub-head.between{justify-content:space-between}
.hub-head h2{font-family:var(--disp);font-weight:900;font-style:italic;font-size:clamp(26px,3.6vw,32px);
  text-transform:uppercase;letter-spacing:-.01em;margin:0}
.hub-head .tag{font-family:var(--alt);font-weight:600;font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--gink)}
.hub-head .tag.ref{color:var(--faint)}
.toolgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
.toolcard{display:block;padding:20px;color:var(--ink);text-decoration:none;transition:var(--t);
  background:linear-gradient(160deg,color-mix(in srgb,var(--brand-blue) 12%,var(--panel)),var(--panel) 58%);
  border:1px solid color-mix(in srgb,var(--brand-blue) 26%,var(--line));
  clip-path:polygon(14px 0,100% 0,100% calc(100% - 14px),calc(100% - 14px) 100%,0 100%,0 14px)}
.toolcard:hover{border-color:color-mix(in srgb,var(--gink) 55%,transparent);transform:translateY(-2px);text-decoration:none}
.toolcard .th{display:flex;align-items:center;gap:10px;font-family:var(--sans);font-weight:700;font-size:16px}
.toolcard .th .ti{font-size:19px;line-height:1}
.toolcard .td{margin-top:7px;font-size:13.5px;color:var(--mut);line-height:1.5}
.dsgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
/* The home "See it" band: a FIXED, small set of cards (one per differentiator), unlike .dsgrid which holds
   however many datasets a game happens to have. That difference is auto-fit vs auto-fill: auto-fill keeps
   empty tracks, so 4 cards in a 1128px row left one column of dead space even at the 200px sizing — the
   band read as half-finished. auto-fit COLLAPSES the empty track and the cards stretch to fill the row. */
/* 205px, not 240px: the section now carries FIVE cards (one per stated differentiator, the Pull Planner
   included — see _home_showcase). At --maxw 1180 the content box is 1128px, so 5*205 + 4*14 = 1081 fits
   on one row, where 5*240 would wrap the fifth onto a row of its own. auto-fit still reflows below that. */
.seegrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(205px,1fr));gap:14px}
@media(max-width:860px){.seegrid{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}}
/* "Not a claim -- see it" used to be four text boxes with an emoji, which is itself a claim. Each card
   now shows the key art of the game it opens, under a scrim heavy enough that the copy keeps its
   normal contrast -- the art is atmosphere, never something text has to fight. --ac is that game's
   accent, used only on the edge and the name, so the four cards read as four different games. */
.seecard{position:relative;overflow:hidden;padding:0;min-height:190px;display:flex;
  border-color:color-mix(in srgb,var(--ac,var(--brand-blue)) 34%,var(--line))}
.seecard .see-art{position:absolute;inset:0;background-size:cover;background-position:center 22%;
  opacity:.5;transition:transform .5s cubic-bezier(.22,.61,.36,1),opacity var(--t)}
.seecard::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,color-mix(in srgb,var(--card) 55%,transparent) 0,var(--card) 78%)}
.seecard .see-body{position:relative;z-index:1;align-self:flex-end;padding:18px 20px 20px;width:100%}
/* The game NAME is text, so it takes the derived ink for the active surface -- NOT the raw --ac. Using
   --ac here reintroduced exactly the bug the ink system exists to prevent: FGO gold on a white card is
   ~1.8:1. --ac stays on the card edge, where contrast does not apply. */
.seecard .see-game{display:block;font:700 10.5px/1 var(--alt);letter-spacing:.16em;text-transform:uppercase;
  color:var(--acd,var(--gink));margin-bottom:7px}
[data-theme="light"] .seecard .see-game{color:var(--acl,var(--gink))}
.seecard:hover .see-art{transform:scale(1.05);opacity:.62}
.seecard:hover{border-color:color-mix(in srgb,var(--ac,var(--gink)) 70%,transparent)}
@media(prefers-reduced-motion:reduce){.seecard:hover .see-art{transform:none}}
.dschip{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:14px 16px;color:var(--ink);
  background:var(--panel);border:1px solid var(--line);font-weight:600;font-size:14px;text-decoration:none;transition:var(--t);
  clip-path:polygon(10px 0,100% 0,100% 100%,0 100%,0 10px)}
.dschip:hover{border-color:color-mix(in srgb,var(--gink) 45%,var(--line));color:var(--gink);text-decoration:none}
.dschip .dn{font-family:var(--alt);font-weight:600;font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
/* "Further reading" — the hand-written guide that explains the numbers on THIS page (see guides_for). */
.gdlinks{display:block;max-width:1200px;margin:34px auto 0;padding:0 22px}
.gdlab{font-family:var(--alt);font-size:12px;letter-spacing:.05em;text-transform:uppercase;color:var(--faint)}
.gdrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;margin-top:10px}
.gdlink{display:block;padding:14px 16px;background:var(--panel);border:1px solid var(--line);color:var(--ink);
  text-decoration:none;transition:var(--t);clip-path:polygon(10px 0,100% 0,100% 100%,0 100%,0 10px)}
.gdlink:hover{border-color:color-mix(in srgb,var(--gink) 45%,var(--line));text-decoration:none}
.gdlink b{display:block;font-size:14.5px;margin-bottom:3px}
.gdlink .muted{font-size:12.5px;line-height:1.45}
/* "Browse by" — one row per identity facet, its values wrapping as compact chips. A game can carry 68 of
   them (Arknights branches), so these are a dense flow, not the 200px .dsgrid used for datasets. */
.brs{display:grid;grid-template-columns:130px 1fr;gap:12px;align-items:baseline;padding:12px 0;border-top:1px solid var(--line)}
.brs:first-of-type{border-top:0}
.brs-k{font-family:var(--alt);font-size:12px;letter-spacing:.05em;text-transform:uppercase;color:var(--faint)}
.brs-v{display:flex;flex-wrap:wrap;gap:8px}
.brs-v .dschip{padding:7px 11px;font-size:13px;gap:7px;clip-path:polygon(7px 0,100% 0,100% 100%,0 100%,0 7px)}
@media(max-width:860px){.brs{grid-template-columns:1fr;gap:6px}}
.morelink{font-family:var(--alt);font-weight:700;font-size:13px;letter-spacing:.04em;text-transform:uppercase;color:var(--gink);white-space:nowrap}

/* breadcrumb */
.crumb{font:500 12px/1 var(--alt);letter-spacing:.04em;text-transform:uppercase;color:var(--faint);padding:16px 0}
.crumb a{color:var(--faint)}.crumb a:hover{color:var(--ink)}
/* ---- legal / policy pages ---- */
.legal{max-width:var(--read);padding:8px 0 64px}
.legal h1{font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;letter-spacing:-.02em;
  font-size:clamp(30px,5vw,44px);margin:.14em 0 4px}
.legal .upd{color:var(--faint);font-size:13px;font-variant-numeric:tabular-nums;margin:0 0 18px}
.legal .lead{color:var(--mut);font-size:16px;line-height:1.65;margin:0 0 8px}
.legal h2{font-family:var(--alt);font-weight:700;font-size:18px;letter-spacing:.01em;margin:30px 0 8px;color:var(--ink)}
.legal p{color:var(--mut);line-height:1.7;margin:0 0 12px}
.legal a{color:var(--link)}
.legal-list{margin:6px 0 14px;padding-left:20px;color:var(--mut);line-height:1.85}
.legal-list b{color:var(--ink)}
.legal code{background:var(--bg-sunk);border:1px solid var(--line);padding:1px 5px;border-radius:3px;font-size:.9em}
/* ---- API Pro / Patreon tiers ---- */
.pro-badge{display:inline-block;font-family:var(--alt);font-weight:700;font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--brand-2);border:1px solid color-mix(in srgb,var(--brand-2) 45%,transparent);
  padding:1px 6px;margin-left:6px;vertical-align:middle}
.pro{margin-top:44px}
.pro-pitch{border-left:3px solid var(--brand-blue);padding:2px 0 2px 18px;margin-bottom:22px}
.pro-pitch h2{font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;letter-spacing:-.01em;
  font-size:clamp(22px,3.4vw,30px);margin:8px 0;line-height:1.04}
.pro-pitch p{color:var(--mut);max-width:58ch;margin:0}
.tiers{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;align-items:start}
.tier{border:1px solid var(--line);background:var(--panel);padding:22px 22px 24px;
  clip-path:polygon(14px 0,100% 0,100% calc(100% - 14px),calc(100% - 14px) 100%,0 100%,0 14px)}
.tier.hot{border-color:color-mix(in srgb,var(--brand-blue) 45%,var(--line));
  background:linear-gradient(160deg,color-mix(in srgb,var(--brand-blue) 12%,var(--panel)),var(--panel) 60%);
  box-shadow:0 20px 50px -30px color-mix(in srgb,var(--brand-blue) 60%,#000)}
.tname{font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;font-size:22px;letter-spacing:-.01em}
.tier.hot .tname{color:var(--brand)}
.tprice{font-family:var(--alt);font-weight:600;font-size:13px;letter-spacing:.02em;color:var(--faint);margin-top:2px}
/* Pro tile: lead BLUNTLY with the price so it's the first thing you see */
.tier.hot .tprice{margin-top:6px}
.tier.hot .tprice .tp-amt{display:block;font-family:var(--disp);font-style:italic;font-weight:900;
  font-size:34px;line-height:1;letter-spacing:-.01em;color:var(--brand)}
.tier.hot .tprice .tp-via{font-size:12px;color:var(--faint)}
/* AUTO dataset/tool catalog on the API docs page */
.ds-catalog{display:flex;flex-direction:column;gap:12px;margin-top:14px}
.ds-row{display:grid;grid-template-columns:minmax(120px,170px) 1fr;gap:12px;align-items:start;
  padding-bottom:12px;border-bottom:1px solid var(--line)}
.ds-g{font-family:var(--disp);font-weight:900;font-style:italic;font-size:15px;color:var(--fg);text-decoration:none}
.ds-g:hover{color:var(--gink)}
.ds-chips{display:flex;flex-wrap:wrap;gap:6px}
.ds-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border:1px solid var(--line);
  background:var(--panel);text-decoration:none;font-size:12px;color:var(--faint)}
.ds-chip code{font-family:ui-monospace,monospace;color:var(--gink);font-size:11.5px}
.ds-chip:hover{border-color:var(--game);color:var(--fg)}
@media(max-width:640px){.ds-row{grid-template-columns:1fr;gap:6px}}
.tlist{list-style:none;margin:16px 0 18px;padding:0;display:flex;flex-direction:column;gap:9px}
.tlist li{position:relative;padding-left:24px;font-size:14px;line-height:1.45;color:var(--mut)}
.tlist li b{color:var(--ink)}
.tlist li::before{position:absolute;left:0;top:0;font-weight:700}
.tlist li.on::before{content:"\2713";color:var(--good)}
.tlist li.off{color:var(--faint)}
.tlist li.off::before{content:"\2715";color:var(--bad);opacity:.75}
.tier .btn{width:100%;justify-content:center}
@media(max-width:640px){.tiers{grid-template-columns:1fr}}
/* ---- request / newsletter forms ---- */
.reqwrap{padding-bottom:64px}
.reqnote{border:1px solid color-mix(in srgb,var(--brand) 30%,var(--line));
  background:color-mix(in srgb,var(--brand) 7%,transparent);color:var(--mut);padding:14px 16px;margin:18px 0 24px;
  font-size:14px;line-height:1.6;max-width:62ch;clip-path:polygon(10px 0,100% 0,100% 100%,0 100%,0 10px)}
.reqnote b{color:var(--ink)}
.reqform{display:flex;flex-direction:column;gap:16px;max-width:560px}
.reqform label{display:flex;flex-direction:column;gap:7px;font-family:var(--alt);font-weight:600;font-size:13px;
  letter-spacing:.02em;color:var(--mut)}
.reqform .req{color:var(--brand)}
.reqform .opt{color:var(--faint);font-weight:500;text-transform:none;letter-spacing:0}
.reqform input,.reqform textarea{background:var(--panel);color:var(--ink);border:1px solid var(--line);
  padding:11px 14px;font:400 15px var(--sans);width:100%;border-radius:var(--r-sm);transition:var(--t)}
.reqform textarea{resize:vertical;min-height:96px;line-height:1.5}
.reqform input:focus,.reqform textarea:focus{border-color:var(--game);outline:none;
  box-shadow:0 0 0 3px color-mix(in srgb,var(--game) 20%,transparent)}
.reqform .hint{font-weight:400;font-size:12.5px;color:var(--faint);letter-spacing:0;font-family:var(--sans)}
.formrow{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.reqform.sub .formrow input{flex:1;min-width:220px}
.formmsg{font-size:13.5px;min-height:1.2em}
.formmsg.ok{color:var(--good)}
.formmsg.err{color:var(--bad)}
.reqform .hint.ok{color:var(--good)}
.reqform .hint.err{color:var(--bad)}
.gamepick{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:9px 16px;max-width:560px;
  padding:15px 16px;border:1px solid var(--line);border-radius:12px;background:var(--panel)}
.gp-item{display:flex;align-items:center;gap:9px;font-family:var(--sans);font-weight:500;font-size:14px;
  color:var(--ink);cursor:pointer}
.gp-item input{flex:none;width:17px;height:17px;min-width:0;padding:0;border:0;border-radius:0;background:none;
  accent-color:var(--brand);cursor:pointer}
.gp-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.formhr{height:1px;background:var(--line);margin:44px 0 26px;max-width:560px}
.reqh2{font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;letter-spacing:-.01em;
  font-size:clamp(22px,3.4vw,28px);margin:8px 0}

/* modal */
.modal{display:none;position:fixed;inset:0;background:rgba(3,5,10,.6);z-index:50;align-items:center;justify-content:center;padding:20px}
.modal.open{display:flex}
.modalc{background:var(--panel);border:1px solid var(--line-strong);max-width:520px;width:100%;padding:22px;
  max-height:86vh;overflow:auto;position:relative;box-shadow:var(--shadow);clip-path:polygon(12px 0,100% 0,100% 100%,0 100%,0 12px)}
.modalc .x{position:absolute;top:12px;right:16px;cursor:pointer;color:var(--mut);font-size:18px}

/* character detail — dramatic hero */
.chero{position:relative;overflow:hidden;color:#f4f5f8;margin-bottom:6px;
  background:radial-gradient(130% 150% at 84% -10%,color-mix(in srgb,var(--game) 42%,#06070b),#06070b 62%);
  border-bottom:1px solid color-mix(in srgb,var(--game) 32%,transparent)}
.chero::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.6;
  background:repeating-linear-gradient(115deg,transparent 0 40px,color-mix(in srgb,var(--game) 7%,transparent) 40px 41px)}
.chero-wm{position:absolute;inset:0;z-index:0;display:flex;align-items:center;pointer-events:none;overflow:hidden;
  padding-left:30px;font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;
  font-size:clamp(120px,20vw,230px);line-height:1;white-space:nowrap;color:rgba(255,255,255,.035);
  -webkit-mask-image:linear-gradient(90deg,#000 40%,transparent 92%);mask-image:linear-gradient(90deg,#000 40%,transparent 92%)}
.chero-in{position:relative;z-index:1;display:flex;align-items:center;justify-content:space-between;gap:26px;padding:44px 26px 36px;
  max-width:var(--maxw);margin:0 auto}
.chero-main{min-width:0}
.chero-eyebrow{font:600 12px/1 var(--alt);letter-spacing:.16em;text-transform:uppercase;color:color-mix(in srgb,var(--game) 62%,#fff)}
.chero-name{font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;
  font-size:clamp(36px,7vw,72px);line-height:.92;letter-spacing:-.02em;margin:.26em 0 .2em;color:#fff}
/* per-card epithet/title under the hero name (Dokkan leader-skill title, etc.) */
.chero-title{font:700 clamp(15px,2.2vw,20px)/1.2 var(--alt);color:color-mix(in srgb,var(--game) 68%,#fff);
  letter-spacing:.01em;margin:-.05em 0 .3em}
/* selected-card epithet in the stat calculator header */
.calc-title{font-weight:600;font-size:.62em;color:var(--gink);opacity:.9;font-style:italic}
.chero-tags{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:.2em 0}
.chero-tags .stars{font-size:17px}
.chero-sub{color:rgba(255,255,255,.6);font-size:14px;margin-top:9px}
.chero .tbadge{color:color-mix(in srgb,var(--bc,#fff) 55%,#fff);border-color:color-mix(in srgb,var(--bc,#fff) 45%,transparent);
  background:color-mix(in srgb,var(--bc,#fff) 16%,transparent)}
.chero .chip.solid{background:rgba(255,255,255,.13);color:#fff;border-color:transparent}
/* level dial */
.cdial{position:relative;width:148px;height:148px;flex:none}
.cdial svg{width:100%;height:100%;transform:rotate(-90deg)}
.cdial-track{fill:none;stroke:rgba(255,255,255,.11);stroke-width:6}
.cdial-arc{fill:none;stroke:var(--game);stroke-width:6;stroke-linecap:round;stroke-dasharray:326.7;
  stroke-dashoffset:calc(326.7 * (1 - var(--p,1)));filter:drop-shadow(0 0 6px color-mix(in srgb,var(--game) 75%,transparent));
  transition:stroke-dashoffset .12s linear}
.cdial-c{position:absolute;inset:0;display:grid;place-content:center;text-align:center}
.cdial-lbl{display:block;font:600 10px/1 var(--alt);letter-spacing:.22em;color:rgba(255,255,255,.5)}
.cdial-n{display:block;font-family:var(--disp);font-weight:800;font-style:italic;font-size:42px;color:#fff;line-height:1;margin-top:4px}
.cdial-mono{font-family:var(--disp);font-weight:800;font-style:italic;font-size:34px;color:#fff}
/* portrait hero variant */
.cportrait{position:relative;width:150px;height:150px;flex:none;overflow:hidden;
  background:rgba(255,255,255,.06);box-shadow:0 6px 24px rgba(0,0,0,.4);
  clip-path:polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px);
  border:1px solid color-mix(in srgb,var(--game) 40%,transparent)}
.cportrait img{width:100%;height:100%;object-fit:cover;display:block}
.cportrait-lvl{position:absolute;left:8px;bottom:8px;font:600 12px/1 var(--alt);color:#fff;
  background:rgba(0,0,0,.6);padding:4px 8px;backdrop-filter:blur(4px)}
.cportrait-lvl b{display:inline;font-size:14px;line-height:1;margin-top:0;font-family:var(--disp);font-weight:800;font-style:italic}
/* Large full-character hero art (V2 look): tall frame, cut corner, left edge fades into the hero. */
.chero-art{position:relative;flex:none;width:300px;height:360px;align-self:flex-end;margin:0 0 -36px 0}
.chero-art img{width:100%;height:100%;object-fit:cover;object-position:center 8%;display:block;
  clip-path:polygon(22px 0,100% 0,100% 100%,0 100%,0 22px);
  -webkit-mask-image:linear-gradient(95deg,transparent 0,#000 20%);mask-image:linear-gradient(95deg,transparent 0,#000 20%);
  filter:drop-shadow(0 12px 34px rgba(0,0,0,.5))}
/* nowrap: at 158px art the label broke onto two lines ("LV." / "100"), tripling its height to 55px
   and turning a small tag into a slab over the character. */
.chero-lvl{position:absolute;top:14px;left:16px;white-space:nowrap;font:600 12px/1 var(--alt);letter-spacing:.05em;color:#fff;
  background:rgba(7,8,13,.72);border:1px solid color-mix(in srgb,var(--game) 55%,transparent);
  padding:5px 11px;backdrop-filter:blur(4px);clip-path:polygon(5px 0,100% 0,100% 100%,0 100%,0 5px)}
/* The number carries class="cdial-n", which is the big LEVEL DIAL style: display:block, 42px (30px
   on mobile). Inside this small tag that forced "LV." and "100" onto separate lines and blew the
   badge up to 79x55 — the slab that covered the character's face. Pin it back to inline text. */
.chero-lvl b{display:inline;font-size:15px;line-height:1;margin-top:0;font-family:var(--disp);font-weight:800;font-style:italic;margin-left:3px}
@media(max-width:640px){.chero-in{flex-direction:column-reverse;align-items:flex-start;padding:26px 16px}
  .cdial,.cportrait{width:104px;height:104px}.cdial-n{font-size:30px}
  .chero-art{width:158px;height:210px;align-self:center;margin:0 auto 6px}
  /* The level badge is pinned top-left of the art frame. At 300px wide that lands on the masked,
     faded left edge; at 158px it lands squarely on the character's FACE, because the art is
     object-position:center 8% so the head sits top-centre. Move it to the bottom-left corner,
     which is background on a full-body crop, and shrink it to match the smaller frame. */
  .chero-lvl{top:auto;bottom:8px;left:8px;font-size:10px;padding:3px 7px}
  .chero-lvl b{font-size:13px}}

/* numbered display-font section headers */
.detail-body{counter-reset:sec;padding-bottom:14px}
.detail-body .shead{font-family:var(--disp);font-style:italic;font-size:20px;margin:26px 0 12px;display:flex;
  align-items:baseline;gap:11px;counter-increment:sec;padding-left:13px;border-left:3px solid var(--game)}
.detail-body .shead::before{content:counter(sec,decimal-leading-zero);font:700 12px/1 var(--alt);
  color:var(--gink);letter-spacing:.05em;flex:none}
.detail-body .shead .lvl-badge{font:400 13px/1 var(--sans);color:var(--mut)}
.detail-body .shead .muted{font-family:var(--sans);font-style:normal}
.shead{font-family:var(--disp);font-style:italic;text-transform:uppercase}

/* stat grid + grades */
.statgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px 24px;margin:10px 0}
@media(max-width:560px){.statgrid{grid-template-columns:1fr}}
.statcell{display:grid;grid-template-columns:84px 1fr 64px;gap:10px;align-items:center;font-size:14px;padding:3px 0}
.statcell .lbl{color:var(--mut);font-size:13px}
.statcell .val{text-align:right;font-variant-numeric:tabular-nums;font-weight:700;font-family:var(--alt)}
.typebadges{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0}
.tbadge{display:inline-flex;align-items:center;gap:5px;font:600 12.5px/1 var(--sans);padding:4px 11px;
  color:var(--bc,var(--ink));border:1px solid color-mix(in srgb,var(--bc,var(--line)) 45%,transparent);
  background:color-mix(in srgb,var(--bc,var(--line)) 12%,transparent);border-radius:2px}
.tbadge .ic{font-size:12px;line-height:1}
.grades{display:flex;flex-wrap:wrap;gap:8px;margin:6px 0}
.gpill{display:inline-flex;align-items:center;gap:6px;font-size:13px;padding:5px 11px;border:1px solid var(--line);
  background:var(--panel);border-radius:2px}
.gpill .gl{color:var(--mut);font-size:12px}
.gpill b{color:var(--gc,var(--ink));font-weight:700;font-family:var(--alt)}

/* awakening form switcher (Prev/Next steps through a card's other forms) */
.formswitch{margin:6px 0 12px}
.fs-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px}
.fs-label{font:700 13px/1 var(--alt);color:var(--gink);text-align:center;flex:1}
.fs-prev,.fs-next{font:600 12.5px/1 var(--sans);padding:8px 14px;border:1px solid var(--line);
  background:var(--panel);color:var(--ink);border-radius:2px;cursor:pointer;white-space:nowrap}
.fs-prev:hover:not(:disabled),.fs-next:hover:not(:disabled){border-color:var(--game);color:var(--gink)}
.fs-prev:disabled,.fs-next:disabled{opacity:.35;cursor:default}

/* skills */
.skills{display:flex;flex-direction:column;gap:9px;margin:8px 0}
.skillcard{padding:13px 15px;border:1px solid var(--line);background:var(--panel);
  clip-path:polygon(8px 0,100% 0,100% 100%,0 100%,0 8px)}
.skillcard.accent{border-color:color-mix(in srgb,var(--game) 38%,var(--line));
  background:linear-gradient(180deg,color-mix(in srgb,var(--game) 9%,var(--panel)),var(--panel))}
.sk-head{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.sk-head b{font-size:15px}
.sk-meta{color:var(--mut);font:600 12px/1 var(--alt);white-space:nowrap}
.sk-desc{color:var(--mut);font-size:13.5px;margin-top:6px;line-height:1.55}
/* Max-rank variant of a skill's effect. Tinted and keyed rather than run on as another grey paragraph,
   so the eye can compare it against .sk-desc above instead of reading both to find the difference. */
.sk-max{margin-top:7px;padding-left:10px;font-size:13.5px;line-height:1.55;
  color:color-mix(in srgb,var(--game,#8fe0ff) 34%,var(--fg));
  border-left:2px solid color-mix(in srgb,var(--game,#8fe0ff) 45%,transparent)}
.sk-maxk{display:block;font:700 10.5px/1 var(--alt);letter-spacing:.13em;text-transform:uppercase;
  color:color-mix(in srgb,var(--game,#8fe0ff) 62%,var(--mut));margin-bottom:3px}
.sk-slider,.stat-lvl{width:100%;margin:8px 0 2px;accent-color:var(--game)}
.stat-lvl{max-width:340px}
.sk-lvl{font-weight:700;font-family:var(--alt)}
.sk-slider:focus-visible,.stat-lvl:focus-visible{outline:2px solid var(--game);outline-offset:3px}

/* dossier profile grid */
.dossier{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:1px;margin:6px 0;
  background:var(--line);border:1px solid var(--line);overflow:hidden}
.dcell{background:var(--panel);padding:11px 14px;display:flex;flex-direction:column;gap:3px;min-width:0}
.dk{font:600 10px/1 var(--alt);letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.dv{font-size:14px;font-weight:600;overflow-wrap:anywhere}

/* pool grid (gacha) */
.poolgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:6px;margin:8px 0}
.poolchip{display:flex;justify-content:space-between;gap:8px;padding:7px 11px;border:1px solid var(--line);
  background:var(--panel);font-size:13px;border-radius:2px}
.poolchip .rt{color:var(--mut);font-variant-numeric:tabular-nums}
.poolchip:hover{border-color:var(--game)}
.poolchip.has-ico{justify-content:flex-start;align-items:center}

/* dataset entry ART — official self-hosted icons on data pages (mystic codes, items, bosses, …) */
.ds-ico{width:100%;aspect-ratio:1/1;object-fit:contain;background:var(--panel);border-radius:4px;display:block}
.ds-ico-sm{width:26px;height:26px;object-fit:contain;border-radius:4px;background:var(--panel);
  flex:0 0 auto;vertical-align:middle}
.ds-namecell{display:inline-flex;align-items:center;gap:8px}
.ccard.has-ico{padding-top:10px}
.ccard .ds-ico{margin-bottom:8px;aspect-ratio:4/3;object-fit:cover}
/* art-forward tile grid (grid-kind datasets: mystic codes, echoes, command codes, materials…).
   NAMED .dstiles, NOT .dsgrid. It was called .dsgrid, which is also the dataset-CARD grid defined ~270
   lines above at minmax(200px,1fr) — same class, two components, and being later in the file this one won
   everywhere. Every .toolcard and .dschip grid on 56 pages was silently laid out at 120px, which is how
   the home page's "See it" band ended up as four 132x364px ribbons wrapping two words per line. A
   duplicate selector is invisible to the build and to the gate; only rendered output shows it. */
.dstiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;margin:12px 0}
.dstile{position:relative;display:flex;flex-direction:column;align-items:center;gap:7px;text-align:center;
  padding:11px 9px;border:1px solid var(--line);background:var(--card);border-radius:3px;font-size:12.5px;
  font-weight:600;line-height:1.25;transition:border-color .12s,transform .12s}
.dstile:hover{border-color:var(--game);transform:translateY(-2px)}
.dstile .ds-ico{width:64px;height:64px;aspect-ratio:auto}
.dstile .rt{color:var(--mut);font-size:11px}
.dstile.no-ico{flex-direction:row;justify-content:space-between;text-align:left;min-height:0}

/* API link (replaced the raw-JSON dump panel — it duplicated the whole page's facts) */
.rawlink{margin-top:26px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px}
.apilink code{background:var(--bg-sunk);border:1px solid var(--line);border-radius:2px;padding:3px 8px;
  font:12px/1 ui-monospace,monospace;color:var(--link)}
/* Underlined on purpose: .muted drops it to body colour, and a link distinguished from its surrounding
   text by colour alone fails WCAG 1.4.1 — the same defect the tools pass already fixed. */
.rawkey{text-decoration:underline;text-underline-offset:2px}

/* cohort standing — computed percentile / rank / median-gap per stat */
.standing{display:grid;gap:14px;margin-top:14px}
.st-row{border:1px solid var(--line);background:var(--bg-soft);padding:12px 14px;
  clip-path:polygon(8px 0,100% 0,100% 100%,0 100%,0 8px)}
.st-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.st-lbl{font:600 13px/1.2 var(--sans);color:var(--mut);text-transform:uppercase;letter-spacing:.04em}
.st-val{font:800 19px/1.1 var(--disp);color:var(--ink)}
.st-bar{height:6px;background:var(--bg-sunk);border-radius:3px;overflow:hidden;margin:9px 0 7px}
.st-bar>i{display:block;height:100%;background:var(--game);border-radius:3px}
.st-bar>i.hi{background:#34be78}
.st-bar>i.lo{background:#e0364a}
.st-note{font-size:12.5px;line-height:1.5}
.st-note .up{color:#34be78}
.st-note .dn{color:#e0364a}

/* nearest comparables */
.cmprow{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-top:14px}
.cmp{display:flex;align-items:center;gap:11px;border:1px solid var(--line);background:var(--bg-soft);
  padding:10px 12px;text-decoration:none;color:var(--ink);transition:border-color .12s,transform .12s;
  clip-path:polygon(8px 0,100% 0,100% 100%,0 100%,0 8px)}
.cmp:hover{border-color:var(--game);transform:translateY(-2px)}
.cmp img{width:40px;height:40px;object-fit:cover;border-radius:3px;flex:0 0 auto}
.cmp-n{font:600 13.5px/1.25 var(--sans);flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cmp-v{font:700 12.5px/1.2 var(--disp);color:var(--mut);white-space:nowrap}
.cmp-v .up{color:#34be78}
.cmp-v .dn{color:#e0364a}

/* changelog + visual diff */
.cl-build{border:1px solid var(--line);border-left:3px solid var(--game);background:var(--panel);margin:14px 0}
.cl-bhead{cursor:pointer;list-style:none;display:flex;align-items:center;gap:14px;padding:16px 18px}
.cl-bhead::-webkit-details-marker{display:none}
.cl-bhead:hover{background:var(--bg-sunk)}
.cl-build[open]>.cl-bhead{border-bottom:1px solid var(--line)}
.cl-bdl{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;flex:1;min-width:0}
.cl-title{font-family:var(--disp);font-style:italic;text-transform:uppercase;font-size:19px}
.cl-date{font:500 12px/1 var(--alt);letter-spacing:.04em;color:var(--faint)}
.cl-preview{font-size:12px;white-space:nowrap}
.cl-chev{width:16px;height:16px;color:var(--faint);flex:none;transition:transform .2s}
.cl-build[open] .cl-bhead .cl-chev{transform:rotate(180deg)}
.cl-body{padding:14px 18px 18px}
.cl-counts{display:flex;flex-wrap:wrap;gap:6px;flex:none}
.cl-pill{font:700 11px/1 var(--alt);text-transform:uppercase;letter-spacing:.04em;padding:5px 10px;border:1px solid var(--line);border-radius:2px}
.cl-pill.add{color:#34be78;border-color:color-mix(in srgb,#34be78 45%,transparent);background:rgba(52,190,120,.10)}
.cl-pill.chg{color:#e2c078;border-color:color-mix(in srgb,#e2c078 45%,transparent);background:rgba(224,160,32,.10)}
.cl-pill.rem{color:#f08a95;border-color:color-mix(in srgb,#f08a95 45%,transparent);background:rgba(224,54,74,.10)}
.cl-line{margin:8px 0;display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.cl-k{font:700 11px/1 var(--alt);text-transform:uppercase;letter-spacing:.08em;margin-right:2px}
.cl-k.add{color:#34be78}.cl-k.rem{color:#f08a95}
.cl-diff{border-top:1px solid var(--line);margin-top:10px;padding-top:8px}
.cl-diff>summary{cursor:pointer;list-style:none;font-weight:600;font-size:14px}
.cl-diff>summary::-webkit-details-marker{display:none}
.cl-diff>summary::before{content:"►";color:var(--mut);margin-right:7px;font-size:9px}
.cl-diff[open]>summary::before{content:"▼"}
.cl-name{color:var(--ink)}
.cl-field{margin:8px 0 8px 18px}
.cl-fk{display:block;font:600 12px/1.3 var(--alt);color:var(--mut);margin-bottom:3px}
.cl-fv{font-size:13.5px;line-height:1.55}
.d-del{background:rgba(224,54,74,.18);color:#f08a95;border-radius:2px;padding:0 2px;text-decoration:line-through}
.d-ins{background:rgba(52,190,120,.18);color:#5fd39a;border-radius:2px;padding:0 2px}
/* dataset-level changes (banners / materials / NPs / …) within a build */
.cl-pill.ds{color:var(--gink);border-color:color-mix(in srgb,var(--gink) 45%,transparent);background:color-mix(in srgb,var(--gink) 10%,transparent)}
.cl-k.ds{color:var(--gink)}.cl-k.chg{color:#e2c078}
.cl-ds{margin-top:12px;padding-top:10px;border-top:1px dashed var(--line)}
.cl-ds-head{margin-bottom:4px;display:flex;align-items:center;gap:6px}
.cl-mini{font:700 10px/1 var(--alt);padding:2px 5px;border-radius:2px}
.cl-mini.add{color:#34be78;background:rgba(52,190,120,.12)}
.cl-mini.chg{color:#e2c078;background:rgba(224,160,32,.12)}
.cl-mini.rem{color:#f08a95;background:rgba(224,54,74,.12)}
/* COVERAGE block — changes to what OUR data carries, not to the game. Deliberately muted and boxed off:
   it must never be mistaken at a glance for a patch note, which is the exact failure it exists to fix. */
.cl-pill.cov{color:var(--mut);border-style:dashed}
.cl-k.cov{color:var(--mut)}
.cl-cov{margin-top:12px;padding:8px 10px;border:1px dashed var(--line);border-radius:3px;background:color-mix(in srgb,var(--mut) 5%,transparent)}
.cl-cov-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:4px;font-size:12px}
.cl-cov .cl-line{opacity:.92}
.cl-covnote{font-size:12.5px;color:var(--mut);border-left:2px solid var(--line);padding-left:8px}
.cl-sub{margin:6px 0 2px 4px}
.cl-sub>.cl-k{display:block;margin-bottom:2px}
.cl-sub .cl-diff{margin-top:4px;padding-top:4px;border-top:none;margin-left:10px}
/* multiplicity marker: N separate records whose displayed detail is identical, collapsed to one row */
.cl-dup{display:inline-block;font-size:11px;font-weight:700;line-height:1;padding:3px 5px;border-radius:5px;
        background:var(--chip,rgba(127,127,127,.16));color:var(--mut);vertical-align:middle}

/* ---- DPS calculator (Arknights) ---- */
.dps-layout{display:grid;grid-template-columns:1fr 340px;gap:20px;margin-top:16px;align-items:start}
.dps-layout .dps-result{order:2;position:sticky;top:78px}
.dps-layout .dps-pick{order:1;min-width:0}
@media(max-width:860px){.dps-layout{grid-template-columns:1fr}.dps-layout .dps-result{order:1;position:static}.dps-layout .dps-pick{order:2}}
.dps-chart-wrap{background:var(--bg-sunk);border:1px solid var(--line);border-radius:8px;padding:6px}
#dpschart{display:block;width:100%;height:auto}
.dps-grid{stroke:var(--grid-line);stroke-width:1}
.dps-axl{fill:var(--faint);font:10px var(--mono,var(--sans))}
.dps-axt{fill:var(--mut);font:11px var(--alt);letter-spacing:.06em}
.dps-ops{margin-top:12px;display:flex;flex-direction:column;gap:8px}
.dps-op{border:1px solid var(--line);border-left:3px solid var(--c,var(--game));border-radius:6px;padding:8px 10px;background:var(--panel-2)}
.dps-op-h{display:flex;align-items:center;gap:7px;font-size:13px}
.dps-op-h b{font-size:13.5px}.dps-op-h .muted{font-size:11px;margin-left:auto}
.dps-swatch{display:inline-block;width:11px;height:11px;border-radius:2px;background:var(--c,var(--game));flex:none}
.dps-x{margin-left:6px;border:none;background:none;color:var(--faint);cursor:pointer;font-size:15px;line-height:1;padding:0 2px}
.dps-x:hover{color:var(--bad)}
.dps-fields{display:grid;grid-template-columns:1fr 1fr;gap:6px 10px;margin-top:7px}
.dps-fields label{display:flex;flex-direction:column;gap:2px;font-size:10.5px;color:var(--faint);text-transform:uppercase;letter-spacing:.05em}
.dps-fields input,.dps-fields select{font:inherit;font-size:13px;padding:4px 6px;background:var(--bg-sunk);border:1px solid var(--line);border-radius:4px;color:var(--ink)}
.dps-table th,.dps-table td{padding:4px 7px;text-align:right;font-size:12.5px}
.dps-table th{color:var(--faint);font-weight:600;border-bottom:1px solid var(--line)}
.dps-table .dps-swatch{margin-right:5px;vertical-align:-1px}
.ccard.on{border-color:var(--game);box-shadow:0 0 0 1px var(--game) inset}

/* ---- Blue Archive boss counter ---- */
.boss-pick{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0}
.boss-btn{display:flex;flex-direction:column;gap:2px;text-align:left;cursor:pointer;padding:8px 13px;
  border:1px solid var(--line-strong);border-radius:8px;background:var(--panel-2);color:var(--ink);font:inherit;transition:var(--t)}
.boss-btn b{font-size:14px}
.boss-btn .boss-meta{font-size:11px;color:var(--faint)}
.boss-btn:hover{border-color:var(--gink)}
.boss-btn.on{border-color:var(--game);background:color-mix(in srgb,var(--game) 16%,var(--card));
  box-shadow:0 2px 12px -6px color-mix(in srgb,var(--game) 60%,#000)}
.boss-head{margin:8px 0 12px}
.boss-summary{font-size:15px;line-height:1.5}
.boss-summary .b-armor,.boss-summary .b-terr{color:var(--mut);font-weight:600}
.boss-sort{margin-top:10px;font-size:12px;color:var(--faint);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.boss-sort .seg{cursor:pointer;padding:4px 10px;border:1px solid var(--line);border-radius:6px;background:transparent;color:var(--mut);font:inherit;font-size:12px}
.boss-sort .seg.on{background:color-mix(in srgb,var(--game) 20%,var(--card));border-color:var(--game);color:var(--ink)}
.boss-list{display:flex;flex-direction:column;gap:5px}
.boss-row{display:grid;grid-template-columns:26px 40px 1fr auto auto;align-items:center;gap:12px;
  padding:6px 12px;border:1px solid var(--line);border-radius:7px;background:var(--panel);text-decoration:none;color:var(--ink);transition:var(--t)}
.boss-row:hover{border-color:var(--line-strong);transform:translateX(2px);text-decoration:none}
.br-rank{font:700 13px var(--alt);color:var(--faint);text-align:center}
.br-img{width:40px;height:40px;border-radius:6px;overflow:hidden;background:var(--bg-sunk)}
.br-img img{width:100%;height:100%;object-fit:cover;object-position:top}
.br-name b{font-size:14px;display:block}
.br-name .br-sub{font-size:11px;color:var(--faint)}
.br-badges{display:flex;align-items:center;gap:6px}
.atk-chip{font:600 11px var(--alt);padding:2px 8px;border-radius:3px;color:#fff;background:var(--c,var(--game))}
.mult{font:700 12px var(--mono,var(--sans));padding:2px 7px;border-radius:3px;border:1px solid var(--line)}
.mult.adv-good{color:#5fd39a;border-color:color-mix(in srgb,#34be78 45%,transparent);background:rgba(52,190,120,.12)}
.mult.adv-bad{color:#f08a95;border-color:color-mix(in srgb,#e0364a 45%,transparent);background:rgba(224,54,74,.12)}
.mult.adv-neu{color:var(--mut)}
.mult.terr{color:var(--faint);font-weight:600}
.br-score{font:700 15px var(--alt);color:var(--ink);text-align:right;min-width:64px}
@media(max-width:620px){.boss-row{grid-template-columns:22px 34px 1fr auto;gap:8px}.br-badges{display:none}}

/* ---- Dokkan link optimizer ---- */
.link-layout{display:grid;grid-template-columns:1fr 380px;gap:20px;margin-top:16px;align-items:start}
.link-layout .link-result{order:2;position:sticky;top:78px;max-height:calc(100vh - 96px);overflow:auto}
.link-layout .link-pick{order:1;min-width:0}
@media(max-width:900px){.link-layout{grid-template-columns:1fr}.link-layout .link-result{order:1;position:static;max-height:none}.link-layout .link-pick{order:2}}
.link-head{margin-bottom:10px}
.link-sel{display:flex;gap:10px;align-items:flex-start;padding:10px;border:1px solid var(--line-strong);border-radius:8px;background:var(--panel-2)}
.link-sel-img{width:52px;height:52px;border-radius:6px;object-fit:cover;flex:none}
.link-sel-nm{font-weight:700;font-size:15px;margin-bottom:4px}
.link-sel-links{display:flex;flex-wrap:wrap;gap:4px}
.link-filter{display:block;font-size:11px;color:var(--faint);margin-top:6px;cursor:pointer;white-space:nowrap}
.lchip{font-size:10.5px;padding:2px 6px;border:1px solid var(--line);border-radius:3px;color:var(--mut);white-space:nowrap}
.lchip.on{color:var(--ink);border-color:color-mix(in srgb,var(--game) 55%,var(--line));background:color-mix(in srgb,var(--game) 15%,transparent)}
.link-list{display:flex;flex-direction:column;gap:5px}
.link-row{display:grid;grid-template-columns:24px 38px 1fr auto;align-items:center;gap:10px;padding:6px 10px;
  border:1px solid var(--line);border-radius:7px;background:var(--panel);text-decoration:none;color:var(--ink);transition:var(--t)}
.link-row:hover{border-color:var(--line-strong);transform:translateX(2px);text-decoration:none}
.link-shared{display:flex;flex-wrap:wrap;gap:3px;justify-content:flex-end;max-width:220px}
.link-count{font:700 13px var(--alt);color:var(--gink);min-width:42px;text-align:right}
@media(max-width:640px){.link-shared{display:none}.link-row{grid-template-columns:22px 34px 1fr auto}}

/* ---- FGO material / ascension planner ---- */
.mat-layout{display:grid;grid-template-columns:1fr 400px;gap:20px;margin-top:16px;align-items:start}
.mat-layout .mat-result{order:2;position:sticky;top:78px;max-height:calc(100vh - 96px);overflow:auto}
.mat-layout .mat-pick{order:1;min-width:0}
@media(max-width:920px){.mat-layout{grid-template-columns:1fr}.mat-layout .mat-result{order:1;position:static;max-height:none}.mat-layout .mat-pick{order:2}}
.mat-chips{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:12px;min-height:8px}
.mat-chip{display:inline-flex;align-items:center;gap:4px;font-size:12px;padding:3px 4px 3px 9px;border-radius:20px;
  background:color-mix(in srgb,var(--game) 16%,var(--card));border:1px solid color-mix(in srgb,var(--game) 40%,var(--line))}
.mat-chip button{border:none;background:none;color:var(--faint);cursor:pointer;font-size:14px;line-height:1;padding:0 3px}
.mat-chip button:hover{color:var(--bad)}
.mat-qp{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;margin-bottom:10px;border-radius:8px;
  background:color-mix(in srgb,var(--game) 12%,var(--panel-2));border:1px solid color-mix(in srgb,var(--game) 30%,var(--line));font-size:14px}
.mat-qp>b{font:700 18px var(--alt);color:var(--ink)}
.mat-qp label{font-size:11px;color:var(--faint);display:flex;align-items:center;gap:4px}
.mat-qp .mat-left{margin-left:auto;color:var(--mut);font-size:13px}
.mat-table{width:100%;border-collapse:collapse}
.mat-table th{font:600 11px var(--alt);color:var(--faint);text-transform:uppercase;letter-spacing:.05em;padding:4px 8px;text-align:right;border-bottom:1px solid var(--line)}
.mat-table td{padding:4px 8px;text-align:right;font-size:13px;border-bottom:1px solid var(--grid-line)}
.mat-table input{width:66px;font:inherit;font-size:12.5px;padding:3px 6px;text-align:right;background:var(--bg-sunk);border:1px solid var(--line);border-radius:4px;color:var(--ink)}
.mat-qp input{width:110px;font:inherit;font-size:12.5px;padding:3px 6px;text-align:right;background:var(--bg-sunk);border:1px solid var(--line);border-radius:4px;color:var(--ink)}
.mat-leftcell b{color:var(--ink)}
.mat-table tr.mat-done{opacity:.5}.mat-table tr.mat-done .mat-leftcell b{color:var(--good)}
.d-arw{color:var(--mut);margin:0 2px}
[data-theme=light] .d-del{color:#a5253a}[data-theme=light] .d-ins{color:#0a7d38}
[data-theme=light] .cl-pill.add{color:#0a7d38}[data-theme=light] .cl-pill.rem{color:#c0392b}

/* per-unit patch history (character detail) */
.phist{display:flex;flex-direction:column;gap:10px;margin:6px 0}
.ph-row{border:1px solid var(--line);border-left:3px solid var(--game);background:var(--panel);padding:12px 15px}
.ph-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.ph-build{font-family:var(--disp);font-style:italic;text-transform:uppercase;font-size:15px}
.ph-date{font:500 12px/1 var(--alt);letter-spacing:.04em;color:var(--faint)}

/* search command-palette */
.cmdk{display:none;position:fixed;inset:0;background:rgba(3,5,10,.55);z-index:60;padding:10vh 16px 16px;justify-content:center}
.cmdk.open{display:flex}
.cmdk-box{background:var(--panel);border:1px solid var(--line-strong);max-width:560px;width:100%;height:max-content;
  box-shadow:var(--shadow);overflow:hidden;clip-path:polygon(12px 0,100% 0,100% 100%,0 100%,0 12px)}
.cmdk-box input{width:100%;border:none;border-bottom:1px solid var(--line);border-radius:0;padding:15px 18px;font-size:16px;background:transparent;color:var(--ink)}
/* The palette input is the one control that had outline:none with NOTHING replacing it — every other
   `outline:none` here swaps in a 3px ring. Keep the ring inside the box so it reads as one field. */
.cmdk-box input:focus{outline:none;box-shadow:inset 0 0 0 2px var(--brand)}
.cmdk-res{max-height:54vh;overflow:auto}
.cmdk-res a{display:flex;align-items:center;gap:10px;padding:10px 16px;color:var(--ink);border-top:1px solid var(--line)}
.cmdk-res a:hover,.cmdk-res a.sel{background:var(--bg-sunk);text-decoration:none}
.cmdk-res .mk{width:28px;height:28px;overflow:hidden;display:grid;place-items:center;font:800 11px/1 var(--disp);font-style:italic;
  color:#fff;background:linear-gradient(135deg,var(--game),var(--brand));border-radius:2px}
.cmdk-res .g{font:600 11px/1 var(--alt);text-transform:uppercase;letter-spacing:.05em;color:var(--mut);margin-left:auto;flex:none;text-align:right}
.cmdk-hint{padding:9px 16px;font-size:12px;color:var(--faint);border-top:1px solid var(--line)}
/* 2-section palette: a labelled Games section, then a gap + an "Everything else" section */
.cmdk-sec{font:700 10.5px/1 var(--alt);text-transform:uppercase;letter-spacing:.11em;color:var(--faint);
  padding:11px 16px 6px;background:var(--panel);position:sticky;top:0;z-index:1}
.cmdk-sec-2{margin-top:8px;border-top:3px solid var(--line)}
.cmdk-res .cmdk-nm{display:flex;flex-direction:column;gap:1px;min-width:0}
.cmdk-res .cmdk-nm b{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-res .cmdk-sub2{font-size:11px;color:var(--gink);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* code block */
.codeblk{background:var(--bg-sunk);border:1px solid var(--line);padding:14px 16px;border-radius:2px;
  font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--ink);overflow:auto}

/* footer */
footer.site{border-top:1px solid var(--line);background:var(--bg-soft);margin-top:56px;padding:40px 0}
/* 5 columns since the LANGUAGE column joined: brand, Games, Tools, About, Language. */
footer.site .cols{display:grid;grid-template-columns:2fr 1fr 1fr 1fr 1fr;gap:24px}
footer.site h2{font:700 11px/1 var(--alt);text-transform:uppercase;letter-spacing:.08em;color:var(--faint);margin:0 0 12px}
footer.site a{display:block;color:var(--mut);font-size:14px;padding:3px 0}
footer.site a:hover{color:var(--ink)}
footer.site .brand{margin-bottom:10px}
.footer .disclaimer,footer.site .disclaimer{margin-top:24px;padding-top:16px;border-top:1px solid var(--line);
  font-size:12px;line-height:1.55;max-width:none;opacity:.72}
@media(max-width:760px){footer.site .cols{grid-template-columns:1fr 1fr}}
#langBtn{font:600 12px/1 var(--alt);letter-spacing:.05em;width:auto;padding:0 10px;gap:5px}

/* disabled */
.btn[aria-disabled="true"],button:disabled,select:disabled,input:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}

/* a11y */
.skip{position:absolute;left:-999px;top:8px;background:var(--brand);color:#001018;padding:9px 14px;z-index:70;font-weight:700}
.skip:focus{left:8px}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* The result panel takes focus when a card is picked by keyboard (see base.html). tabindex=-1 targets
   don't match :focus-visible, so it needs its own ring or the landing is silent as well as invisible. */
.split > aside:focus{outline:2px solid var(--brand);outline-offset:3px}

/* motion — always end visible */
.reveal{opacity:1;transform:none}
@media(prefers-reduced-motion:no-preference){.reveal{animation:rvl .45s ease both}}
@keyframes rvl{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}

/* responsive */
@media(max-width:760px){
  .wrap{padding:0 16px}
  .nav .wrap{gap:14px;height:56px}
  .nav a.gamelink{display:none}
  .hero{padding:40px 0 24px}
  .sec-head{flex-direction:column;align-items:flex-start;gap:6px}
  /* Phone tables. Previously this was `display:block;overflow-x:auto;white-space:nowrap` and nothing else:
     you swiped right, the row label scrolled away with everything else, and by column four you no longer
     knew which unit/item the numbers belonged to. Three changes fix that:
       1. the label column is STICKY, so the row identity is always on screen;
       2. only the data cells stay nowrap — the label wraps inside a bounded width instead of forcing a
          single enormous line;
       3. tighter padding and a scroll-hint shadow off the sticky edge, so it reads as scrollable. */
  table.data{display:block;overflow-x:auto;font-size:13px;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;-ms-overflow-style:none}
  table.data::-webkit-scrollbar{display:none}
  table.data td,table.data th{padding:7px 9px;white-space:nowrap}
  table.data td:first-child,table.data th:first-child{position:sticky;left:0;z-index:2;
    white-space:normal;min-width:96px;max-width:44vw;
    box-shadow:6px 0 8px -6px rgba(0,0,0,.55);background:var(--bg)}
  table.data th:first-child{z-index:3;background:var(--bg-sunk)}
  .ghead .tiles,.steps{grid-template-columns:1fr}
}
@media(max-width:520px){
  .grid.cards{grid-template-columns:1fr 1fr;gap:10px}
  .nav a.link{font-size:12px}
  footer.site .cols{grid-template-columns:1fr 1fr}
}

/* ---- Support page + nav link ---- */
.nav-support span{color:#ff5c8a}
.nav-support:hover span{color:#ff85a6}
.support-page h1{margin:.3em 0 .1em}
.support-card{margin:26px 0 6px;padding:26px 28px;border:1px solid var(--line);border-radius:16px;
  background:linear-gradient(180deg,rgba(180,76,255,.09),rgba(46,139,255,.045))}
.support-card h2{font-size:22px;line-height:1.22;margin:0 0 10px}
.support-list{margin:12px 0 20px;padding:0;list-style:none;display:grid;gap:9px}
.support-list li{padding-left:26px;position:relative}
.support-list li::before{content:"\2665";position:absolute;left:2px;top:1px;color:#ff5c8a}
.support-cta{margin-top:4px}
.support-thanks{margin:22px auto 0;font-size:15px;text-align:center;max-width:54ch}
.support-perks{display:grid;grid-template-columns:1fr 1fr;gap:14px 30px;margin:14px 0 18px}
.support-col h3{font-size:13px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);margin:0 0 8px}
.support-perks .support-list{margin:0}
.support-list.perks li::before{content:"\2713";color:#3fbf7f}
@media(max-width:640px){.support-perks{grid-template-columns:1fr;gap:6px 0}}

.navlinks{display:flex;align-items:center;gap:22px;min-width:0}
/* Hamburger toggle: hidden on desktop, opens the mobile nav drawer (below). */
.navtoggle{display:none;align-items:center;justify-content:center;background:transparent;border:0;
  cursor:pointer;padding:6px;color:var(--ink);border-radius:9px}
.navtoggle:hover,.nav.open .navtoggle{background:var(--bg-sunk)}
.navtoggle svg{width:23px;height:23px;display:block}
/* On mobile the horizontal link row would overflow and clip, so collapse it behind the hamburger into a
   full-width dropdown drawer with the links stacked vertically (Games links straight to /games/). */
@media(max-width:700px){
  .nav .spacer{display:none}
  .navtoggle{display:inline-flex}
  .navlinks{position:absolute;top:100%;left:0;right:0;z-index:39;display:none;
    flex-direction:column;align-items:stretch;gap:0;overflow:visible;
    background:color-mix(in srgb,var(--bg) 97%,transparent);backdrop-filter:blur(10px);
    border-top:1px solid var(--line);border-bottom:1px solid var(--line-strong);
    box-shadow:0 16px 30px -16px rgba(0,0,0,.6);padding:4px 16px 12px}
  .nav.open .navlinks{display:flex}
  .navlinks .link,.navlinks .drop-t{display:block;width:100%;padding:14px 2px;font-size:14px;
    border-bottom:1px solid var(--line)}
  .navlinks .nav-support{border-bottom:0}
  .navdrop{display:block;position:static}
  .navdrop .caret{display:none}
  /* The game list used to be display:none on phones, so the site's single most common navigation task —
     "take me to game X" — cost a trip through /games/ on the device where most readers are. The hover
     dropdown genuinely cannot work on touch, so on mobile the same list is stacked INSIDE the drawer as
     a scrollable section instead of being hidden. Capped so it cannot push the rest of the menu off
     screen, and it keeps its own scroll. No JS and no markup change: the desktop popover styles above
     are simply unwound here. */
  .navdrop .navmenu{display:block;position:static;opacity:1;visibility:visible;transform:none;
    margin:0 0 4px;padding:2px 0 4px;min-width:0;max-height:40vh;overflow-y:auto;
    background:transparent;border:0;border-bottom:1px solid var(--line);box-shadow:none;border-radius:0;
    -webkit-overflow-scrolling:touch}
  .navdrop .navmenu::before{display:none}
  .navdrop .navmenu a{display:block;white-space:normal;padding:11px 2px 11px 14px;font-size:13px;
    border-bottom:0}
  .navdrop .navmenu a.all{border-top:1px solid var(--line);margin-top:2px;padding-top:12px}
}

/* ---- regional game versions: the Global/Japan switch + a per-card exclusive badge ---- */
.rgn-switch{display:inline-flex;align-items:stretch;gap:4px;margin:14px 0 2px;padding:4px;
  border:1px solid var(--line-strong);border-radius:12px;background:var(--panel-2);max-width:100%;
  flex-wrap:wrap}
.rgn-switch .rgn-lead{display:inline-flex;align-items:center;padding:0 10px 0 6px;font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.rgn-opt{display:inline-flex;flex-direction:column;justify-content:center;gap:1px;cursor:pointer;
  padding:6px 14px;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--mut);
  font:inherit;line-height:1.15;transition:var(--t);text-align:left}
.rgn-opt b{font-size:13.5px;font-weight:650}
.rgn-opt i{font-style:normal;font-size:10.5px;color:var(--dim)}
.rgn-opt:hover{color:var(--ink);border-color:var(--line)}
.rgn-opt[aria-selected="true"]{background:color-mix(in srgb,var(--game) 20%,var(--card));
  border-color:color-mix(in srgb,var(--game) 55%,var(--line-strong));color:var(--ink);
  box-shadow:0 2px 10px -6px color-mix(in srgb,var(--game) 60%,#000)}
.rgn-opt[aria-selected="true"] i{color:color-mix(in srgb,var(--gink) 45%,var(--mut))}
/* small "JP"-style badge on cards that only exist on a later region's server */
.rgn-badge{position:absolute;top:6px;left:6px;z-index:2;font:600 10px/1 var(--mono,var(--sans));
  letter-spacing:.06em;padding:3px 5px;border-radius:5px;color:#fff;
  background:color-mix(in srgb,var(--game) 78%,#000);border:1px solid rgba(255,255,255,.28);
  box-shadow:0 1px 4px rgba(0,0,0,.4)}
/* detail-page notice for a unit that only exists on a later region's server */
.rgn-note{display:inline-flex;align-items:center;gap:6px;margin-top:10px;padding:5px 11px;font-size:12.5px;
  border-radius:8px;color:var(--ink);background:color-mix(in srgb,var(--game) 14%,var(--panel-2));
  border:1px solid color-mix(in srgb,var(--game) 40%,var(--line))}

/* ---- What's New (site-level product updates / release notes) ---- */
.wn-head{position:relative;overflow:hidden;padding:54px 0 32px;margin-bottom:8px;
  background:linear-gradient(150deg,color-mix(in srgb,var(--brand) 15%,var(--bg-soft)),var(--bg-soft) 64%);
  border-bottom:1px solid var(--line)}
.wn-head h1{margin:.28em 0 0;font-family:var(--disp);font-weight:900;font-style:italic;text-transform:uppercase;
  font-size:clamp(30px,5vw,46px);line-height:1.02;letter-spacing:-.01em;color:var(--ink)}
.wn-head .sub{color:var(--mut);max-width:58ch;margin-top:14px;font-size:clamp(15px,2vw,17px)}
.wn-wrap{max-width:840px;padding-top:28px;padding-bottom:24px}
/* collapsible date TIMELINE — newest date open, older dates collapse to a compact bar (kept short as it grows) */
.wn-timeline{position:relative;padding-left:30px}
.wn-timeline::before{content:"";position:absolute;left:5px;top:8px;bottom:8px;width:2px;
  background:linear-gradient(var(--line-strong),var(--line) 55%,transparent)}
.wn-group{position:relative;margin:0 0 10px}
.wn-datebar{list-style:none;cursor:pointer;display:flex;align-items:center;gap:14px;padding:13px 16px;
  border:1px solid var(--line);background:var(--panel);border-radius:12px;transition:border-color .15s,background .15s}
.wn-datebar::-webkit-details-marker{display:none}
.wn-datebar:hover{border-color:var(--line-strong)}
.wn-group[open]>.wn-datebar{border-color:var(--line-strong);border-radius:12px 12px 0 0;background:var(--bg-sunk)}
.wn-node{position:absolute;left:-30px;top:50%;transform:translateY(-50%);width:12px;height:12px;border-radius:50%;
  background:var(--game);box-shadow:0 0 0 4px color-mix(in srgb,var(--game) 20%,var(--bg))}
.wn-group[open] .wn-node{box-shadow:0 0 0 4px color-mix(in srgb,var(--game) 36%,var(--bg))}
.wn-dbl{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.wn-datebar .wn-date{position:static;padding:0}
.wn-datebar time{font:800 14px/1.2 var(--disp);font-style:italic;color:var(--ink)}
.wn-preview{font-size:12.5px;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wn-preview .wn-more{color:var(--gink);font-weight:600}
.wn-group[open] .wn-preview{display:none}
.wn-tags{display:flex;align-items:center;gap:9px;flex:none}
.wn-count{font:700 11px/1 var(--alt);color:var(--faint);background:var(--bg-sunk);border:1px solid var(--line);
  border-radius:20px;padding:4px 9px;min-width:20px;text-align:center}
.wn-dots{display:flex;gap:4px}
.wn-dot{width:7px;height:7px;border-radius:50%;background:var(--faint)}
.wn-dot.wn-tool{background:#a855f7}.wn-dot.wn-feature{background:#34be78}.wn-dot.wn-game{background:#3b82f6}
.wn-dot.wn-data{background:#14b8a6}.wn-dot.wn-fix{background:#e2a04a}
.wn-chev{width:17px;height:17px;color:var(--faint);flex:none;transition:transform .2s}
.wn-group[open] .wn-chev{transform:rotate(180deg)}
.wn-items{display:flex;flex-direction:column;gap:14px;padding:18px 16px 22px;
  border:1px solid var(--line-strong);border-top:none;border-radius:0 0 12px 12px;background:var(--panel)}
.wn-item{position:relative;border:1px solid var(--line);border-radius:10px;background:var(--bg-sunk);
  padding:15px 18px 16px 20px;transition:var(--t);overflow:hidden}
.wn-item:hover{border-color:var(--line-strong);box-shadow:0 10px 26px -18px color-mix(in srgb,var(--game) 34%,#000)}
.wn-item::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--game)}
.wn-top{margin-bottom:9px}
.wn-badge{display:inline-block;font:700 10.5px/1 var(--alt);text-transform:uppercase;letter-spacing:.07em;
  padding:5px 10px;border-radius:999px;border:1px solid var(--line);color:var(--mut)}
.wn-title{font-family:var(--disp);font-weight:700;font-size:18px;line-height:1.25;margin:0 0 6px;color:var(--ink)}
.wn-body{color:var(--mut);font-size:14.5px;line-height:1.6;margin:0}
.wn-link{display:inline-flex;align-items:center;gap:3px;margin-top:12px;font:600 13px/1 var(--alt);
  letter-spacing:.02em;color:var(--gink)}
.wn-link:hover{text-decoration:none;filter:brightness(1.12)}
/* type badge colours + matching timeline dot */
.wn-badge.wn-tool{color:#a855f7;border-color:color-mix(in srgb,#a855f7 45%,transparent);background:color-mix(in srgb,#a855f7 12%,transparent)}
.wn-badge.wn-feature{color:#34be78;border-color:color-mix(in srgb,#34be78 45%,transparent);background:color-mix(in srgb,#34be78 12%,transparent)}
.wn-badge.wn-game{color:#3b82f6;border-color:color-mix(in srgb,#3b82f6 45%,transparent);background:color-mix(in srgb,#3b82f6 12%,transparent)}
.wn-badge.wn-data{color:#14b8a6;border-color:color-mix(in srgb,#14b8a6 45%,transparent);background:color-mix(in srgb,#14b8a6 12%,transparent)}
.wn-badge.wn-fix{color:#e2a04a;border-color:color-mix(in srgb,#e2a04a 45%,transparent);background:color-mix(in srgb,#e2a04a 12%,transparent)}
.wn-item:has(.wn-tool)::before{background:#a855f7;box-shadow:0 0 0 3px color-mix(in srgb,#a855f7 22%,transparent)}
.wn-item:has(.wn-feature)::before{background:#34be78;box-shadow:0 0 0 3px color-mix(in srgb,#34be78 22%,transparent)}
.wn-item:has(.wn-game)::before{background:#3b82f6;box-shadow:0 0 0 3px color-mix(in srgb,#3b82f6 22%,transparent)}
.wn-item:has(.wn-data)::before{background:#14b8a6;box-shadow:0 0 0 3px color-mix(in srgb,#14b8a6 22%,transparent)}
.wn-item:has(.wn-fix)::before{background:#e2a04a;box-shadow:0 0 0 3px color-mix(in srgb,#e2a04a 22%,transparent)}
[data-theme=light] .wn-badge.wn-tool{color:#7c3aed}
[data-theme=light] .wn-badge.wn-feature{color:#0a7d38}
[data-theme=light] .wn-badge.wn-game{color:#1d4ed8}
[data-theme=light] .wn-badge.wn-data{color:#0e7490}
[data-theme=light] .wn-badge.wn-fix{color:#b06d15}
@media(max-width:680px){
  .wn-head{padding:40px 0 24px}
  .wn-timeline{padding-left:22px}
  .wn-timeline::before{left:4px}
  .wn-node{left:-22px;width:10px;height:10px}
  .wn-datebar{gap:10px;padding:12px 13px}
  .wn-preview{display:none}
  .wn-tags{gap:7px}
}

/* Gacha Pull Planner (gachacalc.js) */
.gc-app{display:grid;grid-template-columns:minmax(260px,340px) 1fr;gap:18px;align-items:start;margin-top:6px}
.gc-controls{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:16px 16px 18px;display:flex;flex-direction:column;gap:16px}
.gc-field{display:flex;flex-direction:column;gap:8px;font-size:13px;color:var(--muted)}
.gc-field b{color:var(--fg);font-variant-numeric:tabular-nums}
.gc-field input[type=range]{width:100%;accent-color:var(--game,#a855f7)}
.gc-select{width:100%;padding:9px 10px;background:var(--bg,#0b0b0f);color:var(--fg);border:1px solid var(--line);border-radius:10px;font:inherit;font-size:14px}
.gc-toggle{display:flex;border:1px solid var(--line);border-radius:10px;overflow:hidden}
.gc-toggle button{flex:1;padding:9px 8px;background:transparent;border:0;color:var(--muted);font:inherit;font-size:13px;font-weight:600;cursor:pointer}
.gc-toggle button.on{background:var(--game,#a855f7);color:#0b0b0f}
.gc-check{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--muted);cursor:pointer;line-height:1.4}
.gc-check input{accent-color:var(--game,#a855f7);flex:none}
/* share-this-result row — the planner's state lives in the query string (gachacalc.js syncUrl) */
.gc-sharerow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.gc-share{font:600 12px/1 var(--alt);letter-spacing:.03em;color:var(--muted);background:transparent;
  border:1px solid var(--line);border-radius:9px;padding:8px 11px;cursor:pointer}
.gc-share:hover{color:var(--ink);border-color:var(--game,#a855f7)}
.gc-share:focus-visible{outline:2px solid var(--game,#a855f7);outline-offset:2px}
.gc-result{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:16px 18px}
.gc-out{display:grid;grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:10px}
.gc-stat{display:flex;flex-direction:column;gap:1px;background:var(--bg,#0b0b0f);border:1px solid var(--line);border-radius:12px;padding:11px 12px 10px}
.gc-stat.hl{border-color:var(--game,#a855f7)}
.gc-stat-k{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.gc-stat-v{font-size:25px;font-weight:800;color:var(--fg);font-variant-numeric:tabular-nums;line-height:1.15;font-family:'Space Grotesk',sans-serif}
.gc-stat.hl .gc-stat-v{color:var(--game,#a855f7)}
.gc-stat-u{font-size:11.5px;color:var(--muted)}
.gc-chart-wrap{margin-top:14px;color:var(--fg);background:var(--bg,#0b0b0f);border:1px solid var(--line);border-radius:12px;padding:8px 8px 4px}
.gc-chart-wrap svg{width:100%;height:auto;display:block}
.gc-provenance{max-width:70ch;font-size:12px;margin-top:16px;line-height:1.55}
@media(max-width:720px){.gc-app{grid-template-columns:1fr}}

/* calculator worked-examples table (server-rendered; the page was a 30-word form shell without it) */
.calcpv{margin-top:34px}
.calcpv h2{font:800 22px/1.15 var(--disp);font-style:italic;text-transform:uppercase;letter-spacing:-.01em;margin:0 0 8px}
/* Every wide table must scroll inside its OWN container — the page body must never scroll sideways.
   This was originally scoped per-section, which left the facet-page group profile and the dataset-page
   summary tables uncontained on a 390px viewport (459px of table in a 343px column). Generic now. */
.tablewrap{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
/* A wide table inside a wrap must scroll ONCE. Without this the phone rule below also turns the table into
   its own scroll container, nesting two of them: the outer wrap swallowed the swipe and the inner never
   moved, so the right-hand columns were unreachable on a phone. */
.tablewrap>table.data{display:table}
.calcpv .tablewrap{margin-top:14px}
.calcpv-t{width:100%;border-collapse:collapse;font-size:13.5px}
.calcpv-t th,.calcpv-t td{border:1px solid var(--line);padding:8px 11px;text-align:right;white-space:nowrap}
.calcpv-t thead th{background:var(--bg-sunk);font:700 12px/1.2 var(--sans);text-transform:uppercase;letter-spacing:.04em;color:var(--mut)}
.calcpv-t tbody th{text-align:left;font-weight:600}
.calcpv-t tbody th a{color:var(--ink);text-decoration:none}
.calcpv-t tbody th a:hover{color:var(--gink)}
.calcpv-t tbody tr:hover td{background:var(--bg-soft)}
.st-sum{font-size:14.5px;line-height:1.65;color:var(--ink);border-left:3px solid var(--game);
  padding:2px 0 2px 14px;margin:14px 0 4px}

/* facet-page computed group profile (P1-1: these were 88-word auto-generated filter lists) */
.gp-lead{font-size:14.5px;line-height:1.65;color:var(--ink);border-left:3px solid var(--game);
  padding:2px 0 2px 14px;margin:16px 0 6px}
.gp-t{margin-top:6px}
.gp-t .up{color:#34be78}
.gp-t .dn{color:#e0364a}
.ds-profile{font-size:14.5px;line-height:1.65;color:var(--ink);border-left:3px solid var(--game);
  padding:2px 0 2px 14px;margin:14px 0 6px}
.gc-static,.opt-static{margin-top:30px}
.gc-static h2,.opt-static h2{font:800 22px/1.15 var(--disp);font-style:italic;text-transform:uppercase;letter-spacing:-.01em;margin:0 0 8px}
.gc-static .tablewrap,.opt-static .tablewrap{margin-top:12px}
.gc-static-t,.opt-static-t{width:100%;border-collapse:collapse;font-size:13.5px}
.gc-static-t th,.gc-static-t td,.opt-static-t th,.opt-static-t td{border:1px solid var(--line);padding:8px 11px;text-align:right;white-space:nowrap}
.gc-static-t thead th,.opt-static-t thead th{background:var(--bg-sunk);font:700 12px/1.2 var(--sans);text-transform:uppercase;letter-spacing:.04em;color:var(--mut)}
.gc-static-t tbody th,.opt-static-t tbody th{text-align:left;font-weight:600}
.opt-static-t tbody th a{color:var(--ink);text-decoration:none}
.opt-static-t tbody th a:hover{color:var(--gink)}

/* ---------- Guides (hand-written editorial) ------------------------------------------------
   The rest of the site is dense tabular UI; a guide is the one place a reader is meant to read
   a paragraph, so it gets a measure (~72ch), generous leading and a real prose hierarchy rather
   than the compact data-row rhythm used everywhere else. */
.guide{max-width:none;padding-top:6px}
.guide-head{max-width:74ch;margin-bottom:26px}
.guide-kick{font:700 12px/1 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--game,var(--link));margin-bottom:12px}
.guide-head h1{font-size:clamp(30px,4.2vw,46px);line-height:1.02;margin:0 0 14px}
.guide-head .lead{font-size:18px;line-height:1.6;margin:0}
.guide-meta{display:flex;flex-wrap:wrap;gap:9px;align-items:center;font-size:12.5px;margin-top:16px;
  padding-top:14px;border-top:1px solid var(--line)}
.guide-body{max-width:74ch;font-size:16.5px;line-height:1.72}
.guide-body h2{font-size:clamp(21px,2.6vw,27px);line-height:1.1;margin:38px 0 12px}
.guide-body h3{font-size:18px;line-height:1.2;margin:26px 0 8px;text-transform:none;font-style:normal;font-weight:700;font-family:var(--sans)}
.guide-body p{margin:0 0 16px}
.guide-body ul,.guide-body ol{margin:0 0 18px;padding-left:22px}
.guide-body li{margin:0 0 8px}
.guide-body a{color:var(--link);text-decoration:underline;text-underline-offset:2px}
.guide-body strong{font-weight:700;color:var(--ink)}
.guide-body .pull{font-size:17px;line-height:1.6;border-left:3px solid var(--link);padding:4px 0 4px 18px;
  margin:24px 0;color:var(--ink)}
.guide-body .note{border:1px solid var(--line-strong);border-radius:12px;background:var(--panel);
  padding:16px 18px;margin:24px 0;font-size:15px;line-height:1.62}
.guide-body .note b:first-child{display:block;margin-bottom:6px}
.guide-body figure{margin:24px 0;max-width:none}
.guide-body figcaption{font-size:13px;color:var(--mut);margin-top:9px;line-height:1.55}
.guide-t{width:100%;border-collapse:collapse;font-size:13.5px}
.guide-t th,.guide-t td{border:1px solid var(--line);padding:9px 12px;text-align:right;white-space:nowrap}
.guide-t thead th{background:var(--bg-sunk);font:700 11.5px/1.2 var(--sans);text-transform:uppercase;
  letter-spacing:.05em;color:var(--mut);text-align:right}
.guide-t tbody th,.guide-t thead th:first-child{text-align:left}
.guide-t tbody th{font-weight:600;white-space:normal}
.guide-t tbody tr:hover td{background:var(--bg-sunk)}
.guide-t .up{color:#34be78}
.guide-t .dn{color:#e0364a}
.guide-foot{max-width:74ch;margin-top:40px;padding-top:18px;border-top:1px solid var(--line);font-size:13.5px}
.guide-rel{margin-top:30px}
.guide-rel h2{font-size:19px;margin:0 0 12px}
.guide-rel-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.guide-rel-c,.guide-c{display:flex;flex-direction:column;gap:6px;border:1px solid var(--line);border-radius:12px;
  background:var(--panel);padding:15px 16px;text-decoration:none;color:var(--ink);
  transition:border-color .16s ease,transform .16s ease}
.guide-rel-c:hover,.guide-c:hover{border-color:var(--line-strong);transform:translateY(-2px);text-decoration:none}
.guide-rel-c .rk,.guide-c .gk{font:700 10.5px/1 var(--sans);letter-spacing:.11em;text-transform:uppercase;color:var(--link)}
.guide-rel-c b,.guide-c b{font-size:15.5px;line-height:1.3}
.guide-rel-c .muted,.guide-c .muted{font-size:13px;line-height:1.5}
.guide-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(290px,1fr))}
.guide-c .gm{font-size:12px;margin-top:2px}
@media (max-width:640px){.guide-body{font-size:16px}.guide-head .lead{font-size:16.5px}}

/* Server-rendered "How this is computed" note on the bespoke tool pages. These were 21-29 word JS shells:
   a heading, one sentence and an empty widget for anyone who had not run the tool. The formula is the
   content — it is what a reader needs to trust the output, and what a crawler has to go on. */
.toolnote{max-width:74ch;margin:34px 0 8px;padding-top:20px;border-top:1px solid var(--line);
  font-size:15px;line-height:1.68}
.toolnote h2{font:800 22px/1.15 var(--disp);font-style:italic;text-transform:uppercase;letter-spacing:-.01em;margin:0 0 10px}
.toolnote p{margin:0 0 14px;color:var(--mut)}
.toolnote ul{margin:0 0 16px;padding-left:20px}
.toolnote li{margin:0 0 7px;color:var(--mut)}
.toolnote b{color:var(--ink)}
.toolnote a{color:var(--link);text-decoration:underline;text-underline-offset:2px}

/* /search/ — the standalone results page. Reuses .cmdk-res row styling so a result looks identical to the
   command palette; only the overlay-specific height cap and scroll are undone, since the page scrolls. */
.srch-form{display:flex;gap:8px;margin:18px 0 6px;max-width:560px}
.srch-form input{flex:1;min-width:0;padding:11px 14px;border:1px solid var(--line);border-radius:10px;
  background:var(--bg-sunk);color:var(--ink);font:500 15px/1.2 var(--alt)}
.srch-form input:focus{outline:2px solid var(--game,var(--link));outline-offset:1px}
.srch-count{font-size:13px;margin:6px 0 10px;min-height:1.2em}
.cmdk-res.srch-res{max-height:none;overflow:visible;border-top:1px solid var(--line);margin-bottom:40px}
.cmdk-res.srch-res a{padding-left:0;padding-right:0}

/* ---- Umamusume race planner ---- */
.race-mode{display:flex;gap:8px;margin:18px 0 4px}
.race-mode .seg,.race-sort .seg,.chart-diffs .seg{cursor:pointer;padding:5px 12px;border:1px solid var(--line);
  border-radius:6px;background:transparent;color:var(--mut);font:inherit;font-size:12.5px;transition:var(--t)}
.race-mode .seg:hover,.race-sort .seg:hover,.chart-diffs .seg:hover{border-color:var(--line-strong)}
.race-mode .seg.on,.race-sort .seg.on,.chart-diffs .seg.on{background:color-mix(in srgb,var(--game) 20%,var(--card));
  border-color:var(--game);color:var(--ink)}
.race-layout{display:grid;grid-template-columns:380px 1fr;gap:20px;margin-top:14px;align-items:start}
.race-layout .race-pick{position:sticky;top:78px;max-height:calc(100vh - 96px);overflow:auto;min-width:0}
.race-layout .race-result{min-width:0}
@media(max-width:900px){.race-layout{grid-template-columns:1fr}.race-layout .race-pick{position:static;max-height:420px}}
.race-picklist{display:flex;flex-direction:column;gap:4px}
.race-pickrow{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:9px;padding:6px 9px;
  border:1px solid var(--line);border-radius:6px;background:var(--panel);color:var(--ink);text-decoration:none;transition:var(--t)}
.race-pickrow:hover{border-color:var(--line-strong);text-decoration:none}
.race-pickrow.on{border-color:var(--game);box-shadow:0 0 0 1px var(--game) inset}
.rp-nm b{font-size:13.5px;display:block}
.rp-sub,.rr-sub{font-size:11px;color:var(--faint);display:block}
.rp-meta{font-size:11.5px;color:var(--mut);text-align:right;white-space:nowrap}
.rp-band{display:block;font-size:10px;color:var(--faint)}
.rgrade{font:700 10.5px var(--alt);padding:2px 6px;border-radius:3px;border:1px solid var(--line);color:var(--mut);white-space:nowrap}
.rgrade.rgG1{color:#f0c674;border-color:color-mix(in srgb,#e0a020 45%,transparent);background:rgba(224,160,32,.12)}
.rgrade.rgG2{color:#9fc7f0;border-color:color-mix(in srgb,#4a90d9 45%,transparent);background:rgba(74,144,217,.12)}
.rgrade.rgG3{color:#a7dcc0;border-color:color-mix(in srgb,#34be78 40%,transparent);background:rgba(52,190,120,.1)}
.race-sel{display:flex;gap:12px;align-items:flex-start;padding:11px;border:1px solid var(--line-strong);
  border-radius:8px;background:var(--panel-2);margin-bottom:10px}
.race-sel-img{width:56px;height:56px;border-radius:6px;object-fit:cover;object-position:top;flex:none}
.race-sel-nm{font-weight:700;font-size:16px;margin-bottom:5px}
.race-sel-apt{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:4px}
.race-sel-sub{font-size:11.5px;color:var(--faint)}
.apt{font:600 10.5px var(--alt);padding:2px 7px;border-radius:3px;border:1px solid var(--line);color:var(--faint);white-space:nowrap}
.apt b{color:var(--ink);font-weight:800}
.apt-A{border-color:color-mix(in srgb,#34be78 50%,transparent);background:rgba(52,190,120,.12)}
.apt-A b{color:#5fd39a}
.apt-B{border-color:color-mix(in srgb,#4a90d9 45%,transparent);background:rgba(74,144,217,.1)}
.apt-C{border-color:color-mix(in srgb,#e0a020 40%,transparent);background:rgba(224,160,32,.1)}
.apt-D,.apt-E{color:var(--faint)}
.apt-F b,.apt-G b{color:#f08a95}
.race-sort{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:10px}
.race-filter{font-size:11.5px;color:var(--faint);cursor:pointer;white-space:nowrap;margin-left:auto}
.race-count{font-size:12.5px;color:var(--mut);margin:0 0 8px}
.race-list{display:flex;flex-direction:column;gap:5px}
.race-row{display:grid;grid-template-columns:auto 1fr auto auto;align-items:center;gap:10px;padding:7px 11px;
  border:1px solid var(--line);border-radius:7px;background:var(--panel);color:var(--ink);text-decoration:none;transition:var(--t)}
.race-row.uma{grid-template-columns:24px 40px 1fr auto auto}
a.race-row:hover{border-color:var(--line-strong);transform:translateX(2px);text-decoration:none}
.rr-nm b{font-size:13.5px;display:block}
.rr-apt{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}
.fit{font:700 11px var(--alt);padding:3px 9px;border-radius:3px;min-width:74px;text-align:center}
.fit-perfect{color:#5fd39a;background:rgba(52,190,120,.14)}
.fit-strong{color:#9fc7f0;background:rgba(74,144,217,.14)}
.fit-workable{color:#e2c078;background:rgba(224,160,32,.12)}
.fit-poor{color:var(--mut);background:var(--bg-sunk)}
.fit-bad{color:#f08a95;background:rgba(224,54,74,.1)}
@media(max-width:640px){.rr-apt{display:none}.race-row{grid-template-columns:auto 1fr auto}.race-row.uma{grid-template-columns:22px 34px 1fr auto}}

/* ---- CookieRun: Crumble gacha level planner ---- */
.lvl-layout{display:grid;grid-template-columns:1fr 330px;gap:20px;margin-top:16px;align-items:start}
.lvl-layout .lvl-side{position:sticky;top:78px}
@media(max-width:900px){.lvl-layout{grid-template-columns:1fr}.lvl-layout .lvl-side{position:static}}
.lvl-fields{display:grid;grid-template-columns:2fr 1fr 1fr;gap:10px;margin-bottom:14px}
.lvl-fields label{display:flex;flex-direction:column;gap:3px;font-size:10.5px;color:var(--faint);
  text-transform:uppercase;letter-spacing:.05em}
.lvl-fields input,.lvl-fields select{font:inherit;font-size:14px;padding:7px 8px;background:var(--bg-sunk);
  border:1px solid var(--line);border-radius:5px;color:var(--ink);min-width:0}
@media(max-width:560px){.lvl-fields{grid-template-columns:1fr 1fr}.lvl-fields label:first-child{grid-column:1/-1}}
.lvl-now{font-size:14px;padding:9px 12px;border:1px solid var(--line-strong);border-radius:7px;
  background:var(--panel-2);margin-bottom:12px}
.lvl-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px}
.lvl-card{border:1px solid var(--line);border-radius:8px;background:var(--panel);padding:12px 14px}
.lvl-card-h{font-size:12.5px;color:var(--mut);margin-bottom:4px}
.lvl-big{font:800 32px/1 var(--disp);color:var(--gink)}
.lvl-big-sub{display:block;font:500 11.5px/1.3 var(--alt);color:var(--faint);margin-top:4px}
.lvl-lines{margin-top:10px;display:flex;flex-direction:column;gap:4px;font-size:12.5px}
.lvl-lines div{display:flex;justify-content:space-between;gap:10px;border-top:1px dashed var(--line);padding-top:4px}
.lvl-lines span{color:var(--faint)}
.lvl-lines b{white-space:nowrap}
.lvl-lines i{color:var(--faint);font-style:normal;font-weight:500;font-size:11px}
.lvl-foot{font-size:12px;margin-top:12px}
.lvl-h{font:800 17px/1.2 var(--disp);text-transform:uppercase;letter-spacing:-.01em;margin:22px 0 8px}
.lvl-side .lvl-h{margin-top:0}
.lvl-table-wrap{overflow-x:auto}
.lvl-table{width:100%;border-collapse:collapse;font-size:12.5px}
.lvl-table th{text-align:left;color:var(--faint);font-weight:600;border-bottom:1px solid var(--line);padding:5px 8px}
.lvl-table td{padding:5px 8px;border-bottom:1px solid var(--line)}
.lvl-table tr.now{background:color-mix(in srgb,var(--game) 14%,transparent)}
.lvl-table tr.reach td{color:var(--ink)}
.lvl-table tr.feat td{color:var(--gink);font-weight:600}
.lvl-mark{color:var(--faint);font-size:11px;white-space:nowrap}
.lvl-note{font-size:11.5px;margin-top:8px}

/* ---- hololive Dreams chart finder ---- */
.chart-controls{margin-top:16px}
.chart-diffs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.chart-fields{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end}
.chart-fields label{display:flex;flex-direction:column;gap:3px;font-size:10.5px;color:var(--faint);
  text-transform:uppercase;letter-spacing:.05em}
.chart-fields input,.chart-fields select{font:inherit;font-size:13.5px;padding:6px 8px;background:var(--bg-sunk);
  border:1px solid var(--line);border-radius:5px;color:var(--ink);width:88px}
.chart-fields select{width:auto;max-width:220px}
.chart-fields input[type=search]{width:180px}
.chart-dist{margin:16px 0 6px}
.cd-head{font-size:11.5px;margin-bottom:6px}
.cd-bars{display:flex;gap:3px;align-items:flex-end;flex-wrap:wrap}
.cd-bar{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:2px;cursor:pointer;
  border:none;background:none;padding:2px;font:inherit;color:var(--faint);min-width:26px}
.cd-fill{display:block;width:18px;border-radius:2px 2px 0 0;background:var(--line-strong);transition:var(--t)}
.cd-bar.on .cd-fill{background:var(--game)}
.cd-bar:hover .cd-fill{background:color-mix(in srgb,var(--game) 70%,var(--line-strong))}
.cd-n{font-size:9.5px}
.cd-l{font:700 11px var(--alt);color:var(--mut)}
.cd-bar.on .cd-l{color:var(--ink)}
.chart-count{font-size:13px;color:var(--mut);margin:10px 0 8px}
.chart-table-wrap{overflow-x:auto;margin-bottom:40px}
.chart-table{width:100%;border-collapse:collapse;font-size:13px}
.chart-table th{text-align:left;color:var(--faint);font-weight:600;border-bottom:1px solid var(--line);padding:6px 9px;white-space:nowrap}
.chart-table td{padding:6px 9px;border-bottom:1px solid var(--line)}
.ct-lv{font:800 15px var(--alt);color:var(--gink);width:44px}
.ct-nm{font-weight:600}
.ct-sing{color:var(--mut);font-size:12.5px}
.ct-gen{display:block;font-size:10.5px;color:var(--faint)}
.ct-bpm{color:var(--mut);text-align:right;width:56px}
.chart-table th.ct-d,.chart-table td.ct-d{text-align:center;width:38px;color:var(--faint)}
.chart-table td.ct-d.on{color:var(--ink);font-weight:700}
.ct-yt a{font-size:11.5px;color:var(--link)}
@media(max-width:640px){.chart-table .ct-d,.chart-table .ct-bpm{display:none}}
.lvl-gate{margin-top:8px;font-size:12px;padding:5px 8px;border-radius:5px;color:var(--mut);
  background:rgba(224,160,32,.1);border:1px solid color-mix(in srgb,#e0a020 35%,transparent)}
.lvl-gate b{color:var(--ink)}

/* ---- Pull Planner: cross-game standing strip ------------------------------------------------------
   Shares the /meta/ chart's marks and its VALIDATED grade palette (blue -> aqua -> red, checked against
   both surfaces with the dataviz validator). The bar is drawn on the cross-game axis, so its position
   here and in the hub mean the same thing — a per-game scale would make every game look identical. */
.pp-stand{--gr-generous:#2a78d6;--gr-fair:#1baf7a;--gr-steep:#d03b3b;
  margin:18px 0 22px;padding:16px 18px;border:1px solid var(--line);background:var(--panel);
  clip-path:polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)}
:root[data-theme="dark"] .pp-stand{--gr-generous:#3987e5;--gr-fair:#199e70;--gr-steep:#e66767}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .pp-stand{
  --gr-generous:#3987e5;--gr-fair:#199e70;--gr-steep:#e66767}}
.pp-stand.g-generous{--gr:var(--gr-generous)}
.pp-stand.g-fair{--gr:var(--gr-fair)}
.pp-stand.g-steep{--gr:var(--gr-steep)}
.pp-stand .mg-grade{display:inline-block;padding:3px 9px;border-radius:2px;font:600 11.5px/1.5 var(--alt);
  letter-spacing:.04em;color:var(--gr);border:1px solid color-mix(in srgb,var(--gr) 45%,transparent);
  background:color-mix(in srgb,var(--gr) 12%,transparent)}
.pp-stand-h{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.pp-rank{font-size:13.5px;color:var(--ink);font-weight:600}
.pp-cmp{margin-left:auto;font-size:13px;white-space:nowrap}
.pp-stand .mg-track{position:relative;display:block;height:12px;border-radius:2px;background:var(--bg-sunk);
  border:1px solid var(--line)}
.pp-stand .mg-band{position:absolute;top:1px;bottom:1px;border-radius:4px;background:var(--gr);opacity:.55}
.pp-stand .mg-avg{position:absolute;top:-2px;bottom:-2px;width:2px;background:var(--gr);
  box-shadow:0 0 0 2px var(--panel)}
.pp-stand .mg-stop{position:absolute;top:-3px;bottom:-3px;width:2px;background:var(--ink);opacity:.55}
.pp-stand .mg-stop::after{content:"";position:absolute;left:-2px;top:-2px;width:6px;height:6px;
  border-radius:50%;background:var(--ink);opacity:.8}
.pp-scale{display:flex;justify-content:space-between;margin-top:5px;font-size:11px;color:var(--faint);
  font-variant-numeric:tabular-nums}
.pp-stand-n{margin:9px 0 0;font-size:13px;color:var(--mut)}
@media(max-width:860px){.pp-cmp{margin-left:0}}

/* B6-5: deep link from a unit's stat block into the calculator, preselected to that unit. */
.calc-link{font-family:var(--sans);font-style:normal;font-weight:600;font-size:12px;letter-spacing:.02em;text-transform:none;margin-left:10px;padding:3px 9px;border-radius:999px;border:1px solid var(--line);color:var(--ink-2);text-decoration:none;white-space:nowrap}
.calc-link:hover{border-color:var(--ac);color:var(--ac)}

/* B6-7 — section rail. The hub lists every tool and dataset, but from INSIDE one the only way
   across was Back or a round trip through the hub. A horizontal strip rather than a left column:
   same 'one click away' outcome without a layout rewrite, and it degrades to a scrollable row on
   mobile instead of eating width. Scroll-snap so a partly-scrolled rail never hides a half chip. */
.secrail{display:flex;align-items:center;gap:10px;margin:2px 0 14px;padding-bottom:2px;min-width:0}
.secrail-home{flex:0 0 auto;font-family:var(--sans);font-weight:700;font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2);text-decoration:none;padding-right:10px;border-right:1px solid var(--line)}
.secrail-home:hover{color:var(--ac)}
/* The rail scrolls, but the scrollbar is replaced by two arrow buttons + edge fades: the bar itself read
   as a stray UI artefact, and on a long rail (Arknights ships 13 sections) it clipped the last chip with
   no hint that more existed. Fades are masked so they sit ON the chips without repainting the header art. */
.secrail-wrap{position:relative;flex:1 1 auto;min-width:0;display:flex;align-items:center}
/* Deliberately NO scroll-snap and NO scroll-behavior here.
   Snap pulled the rail to the nearest chip after every arrow page, so the resting scrollLeft never reached
   scrollWidth-clientWidth and the "you are at the end" test never fired — the next arrow stayed lit on a
   rail that could not move. And UA scroll animation is not dependable: where it is suppressed, BOTH
   scrollBy({behavior:'smooth'}) and a plain scrollLeft assignment under scroll-behavior:smooth become
   silent no-ops, i.e. the arrows do nothing at all. The rail's own rAF tween owns the motion instead. */
.secrail-row{display:flex;gap:6px;overflow-x:auto;padding-bottom:2px}
/* The native scrollbar is hidden ONLY once rail.js has taken over (it sets .js). Hiding it
   unconditionally meant that with JS off you got no scrollbar, no arrows and no fades — clipped
   chips with zero affordance, strictly worse than the bar this replaced. */
.secrail-wrap.js .secrail-row{scrollbar-width:none;-ms-overflow-style:none}
.secrail-wrap.js .secrail-row::-webkit-scrollbar{display:none}
.secrail-row>*{flex:0 0 auto}
.secrail .dschip{font-size:12px;padding:4px 10px}
.secrail .dschip.on{background:var(--ac);border-color:var(--ac);color:#fff;cursor:default}
.secrail-wrap::before,.secrail-wrap::after{content:"";position:absolute;top:0;bottom:0;width:44px;
  pointer-events:none;opacity:0;transition:opacity .18s ease;z-index:1}
.secrail-wrap::before{left:0;background:linear-gradient(90deg,var(--bg) 12%,transparent)}
.secrail-wrap::after{right:0;background:linear-gradient(270deg,var(--bg) 12%,transparent)}
.secrail-wrap.at-start::after,.secrail-wrap.at-end::before,
.secrail-wrap.mid::before,.secrail-wrap.mid::after{opacity:1}
.secrail-wrap.at-start::before,.secrail-wrap.at-end::after{opacity:0}
.secrail-arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:26px;height:26px;
  display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;
  border:1px solid var(--line-strong);border-radius:50%;background:var(--panel);color:var(--ink-2);
  transition:color .15s ease,border-color .15s ease,background .15s ease,transform .15s ease}
.secrail-arrow svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2.1;
  stroke-linecap:round;stroke-linejoin:round}
.secrail-arrow:hover{color:var(--ac);border-color:var(--ac);transform:translateY(-50%) scale(1.08)}
.secrail-arrow:focus-visible{outline:2px solid var(--ac);outline-offset:2px}
.secrail-arrow[hidden]{display:none}
.secrail-arrow.prev{left:-2px}
.secrail-arrow.next{right:-2px}
@media (max-width:860px){.secrail{margin-bottom:10px}.secrail-home{display:none}}
/* Coarse pointers swipe the rail directly, so the arrows are dead weight — keep only the edge fades. */
@media (hover:none){.secrail-arrow{display:none}}

/* ---- Glossary (/glossary/) -------------------------------------------------------------------
   One definition per card so the page scans as a reference rather than an essay. The permalink
   anchor is what makes a term quotable in a Discord answer, which is the main way anyone will
   actually arrive here. */
.gl-toc a{margin-right:2px}
.gl-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(340px,100%),1fr));gap:14px;margin-top:18px}
.gl-item{position:relative;border:1px solid var(--line);border-radius:12px;padding:16px 18px;background:var(--panel)}
.gl-item h2{margin:0 0 6px;font-size:17px}
.gl-item p{margin:0;font-size:14px;line-height:1.55}
.gl-perma{position:absolute;top:12px;right:14px;opacity:0;font-size:13px;text-decoration:none}
.gl-item:hover .gl-perma,.gl-perma:focus{opacity:.55}
/* :target — arriving from a shared #anchor should make it obvious WHICH term was linked. */
.gl-item:target{border-color:var(--game,var(--line-strong));box-shadow:0 0 0 2px color-mix(in srgb,var(--game,#888) 22%,transparent)}

/* ---- Arknights recruitment calculator ---- */
.rc-rules{margin:10px 0 0;padding-left:18px;font-size:13px;color:var(--mut)}
.rc-rules li{margin:3px 0}
.rc-pick{margin-top:22px}
.rc-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.rc-head h2{margin:0;font-size:15px}
.rc-clear{font:inherit;font-size:12px;color:var(--mut);background:none;border:none;cursor:pointer;
  text-decoration:underline;padding:0}
.rc-clear:hover{color:var(--ink)}
.rc-tags{margin-top:10px;display:flex;flex-direction:column;gap:9px}
.rc-grp{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.rc-glab{flex:0 0 88px;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--faint)}
.rc-chips{display:flex;gap:6px;flex-wrap:wrap;flex:1 1 260px}
.rc-chip{font:inherit;font-size:12.5px;cursor:pointer;padding:4px 9px;border-radius:999px;
  border:1px solid var(--line);background:var(--bg-sunk);color:var(--mut);transition:var(--t);
  display:inline-flex;align-items:center;gap:5px}
.rc-chip:hover{border-color:var(--line-strong);color:var(--ink)}
.rc-chip.on{background:color-mix(in srgb,var(--game) 22%,var(--card));border-color:var(--game);color:var(--ink)}
.rc-chip.rare{border-style:dashed}
.rc-chip.rare.on{border-style:solid}
.rc-n{font:700 10px var(--alt);color:var(--faint)}
.rc-chip.on .rc-n{color:var(--gink)}
.rc-picked{margin:10px 0 0;font-size:12.5px;color:var(--faint)}
.rc-out{margin:24px 0 40px}
.rc-h{font-size:15px;margin:0 0 12px;display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.rc-h .rc-sub{font:400 12px var(--sans);color:var(--faint)}
.rc-none{font-size:13.5px;color:var(--mut)}
.rc-combo{border:1px solid var(--line);border-radius:var(--r);padding:11px 13px;margin-bottom:10px;
  background:var(--card)}
.rc-combo.top{border-color:var(--game);box-shadow:0 0 0 1px color-mix(in srgb,var(--game) 28%,transparent)}
.rc-cbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:9px}
.rc-csel{display:flex;gap:5px;flex-wrap:wrap;flex:1 1 auto}
.rc-ctag{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--bg-sunk);
  border:1px solid var(--line);color:var(--ink)}
.rc-floor{font:700 12px var(--alt);color:var(--mut);white-space:nowrap}
.rc-floor.f5,.rc-floor.f6{color:var(--gink)}
.rc-cn{font-size:11.5px;color:var(--faint);white-space:nowrap}
.rc-ops{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:7px}
.rc-op{display:flex;align-items:center;gap:7px;padding:4px 9px 4px 4px;border-radius:999px;
  background:var(--bg-sunk);border:1px solid var(--line);font-size:12.5px}
.rc-art{width:26px;height:26px;border-radius:50%;object-fit:cover;flex:none;background:var(--panel-2)}
.rc-mono{display:flex;align-items:center;justify-content:center;font:700 12px var(--alt);color:var(--faint)}
.rc-opn{display:flex;flex-direction:column;line-height:1.2}
.rc-opr{font-size:10px;color:var(--faint)}
.rc-op.r6{border-color:color-mix(in srgb,var(--rarity) 55%,var(--line))}
.rc-op.r5{border-color:color-mix(in srgb,var(--rarity) 28%,var(--line))}
@media(max-width:640px){.rc-glab{flex-basis:100%}}
