@font-face{font-family:Cinzel;font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/cinzel.e3007b72.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400 600;font-display:swap;src:url(fonts/ibm-plex-sans.d8b4e62d.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/ibm-plex-mono-400.bb87500e.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/ibm-plex-mono-500.d32f0e07.woff2) format('woff2')}
*,*::before,*::after{box-sizing:border-box}
/* The design is square throughout: no radius anywhere, borders are hairlines. */
:root{
  --bg:#08080a;          /* page */
  --bg2:#0d0d10;         /* rows */
  --card:#101013;        /* panels and cards */
  --row-hover:#131318;
  --line:rgba(233,228,218,.10);
  --line2:rgba(233,228,218,.06);
  --fg:#e9e4da;
  --dim:#9c958a;         /* secondary text */
  --dim2:#8d867a;        /* labels and meta */
  --faint:#7b756c;       /* notes, qualifiers */
  --off:#5f5a52;         /* counters, inactive */
  --accent:#c9a24a;      /* gold: brand, filled, links */
  --accent2:#e3c477;     /* link and button hover */
  --on-accent:#12100c;   /* text on a gold fill */
  --daily:#7d8f6a;
  --danger:#c96a4a;--danger-fg:#d98b6f;
  --frame:#5a4a30;       /* bronze edge around game icons */
  --well:#0a0a0c;        /* inside of a text field */
  /* Labels, numbers and kickers. Forever swaps it for the sans. */
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  /* Overridden per patch from index.md. They tint the few remaining
     patch-specific accents; the shell itself no longer uses them. */
  --key:#c9a24a;--key2:#8d867a}
/* WoW Forever wears the same shell in the colours of Blizzard's own Forever
   site (worldofwarcraft.blizzard.com/en-us/forever, read 24 Sep 2026): deep
   ocean-teal sections, cream text, bright gold for emphasis and teal-green
   buttons. So the page is the teal, deepening from the brighter #02597e at
   the top; gold keeps its meaning ("reward", filled) but goes brighter; the
   gold-filled buttons turn teal-green like Blizzard's. The rail and mobile
   menu are the flat tan (#c6af8d) of the Forever logo's flat mark, not the
   gradient parchment of the site's panels -- a distinct, brand-matched
   surface rather than another shade of the page -- so its own text and nav
   states get darker, ring-brown tones to read on that lighter ground.
   Labels drop the typewriter mono for the sans, with tabular figures so the
   numbers in tables still line up. The two patch colours (the globe's cyan
   and the ring's bronze) sit in index.md like retail's, and drive the stage
   aurora. */
body[data-flavor="forever"]{
  --bg:#073d58;--bg2:#094564;--card:#0b4d6c;--row-hover:#0f5779;
  --line:rgba(243,238,226,.16);--line2:rgba(243,238,226,.08);
  --fg:#f3eee2;--dim:#c8d6dd;--dim2:#abc0cb;--faint:#8ea8b6;--off:#6b8b9b;
  --accent:#f2c14e;--accent2:#ffdf85;--on-accent:#10222b;
  --daily:#8fc9a0;--frame:#b69b7b;--well:#05324a;
  --mono:'IBM Plex Sans',system-ui,Helvetica,Arial,sans-serif;
  font-variant-numeric:tabular-nums;
  background:linear-gradient(180deg,#02597e 0,#073d58 560px) no-repeat,var(--bg)}
body[data-flavor="forever"] .rail{background:#c6af8d;
  box-shadow:inset -1px 0 0 rgba(36,26,14,.3);--line:rgba(36,26,14,.22);
  scrollbar-color:rgba(36,26,14,.3) transparent}
body[data-flavor="forever"] .rail .brand{color:#170f07}
body[data-flavor="forever"] .rail .wm b{color:#5c3a0e}
body[data-flavor="forever"] .rail .wm-f{color:#4a3a22}
body[data-flavor="forever"] .rail .rail-foot p{color:#4a3a22}
body[data-flavor="forever"] .rail .navlink,body[data-flavor="forever"] .mobmenu .navlink{color:#33260f;font-weight:500}
body[data-flavor="forever"] .rail .navlink:hover,body[data-flavor="forever"] .mobmenu .navlink:hover{
  color:#170f07;background:rgba(23,15,7,.08)}
body[data-flavor="forever"] .rail .navlink.on,body[data-flavor="forever"] .mobmenu .navlink.on{
  color:#170f07;background:rgba(23,15,7,.16);box-shadow:inset 2px 0 0 #5c3a0e}
/* The "signed in"/"admin" badges default to gold-on-gold (--accent/--key),
   unreadable on this flavor's tan rail -- swap them for the same dark-brown
   ink the rest of the rail nav uses. */
body[data-flavor="forever"] .rail .navlink.acct::after,body[data-flavor="forever"] .mobmenu .navlink.acct::after{
  color:#170f07;border-color:rgba(23,15,7,.5);background:rgba(23,15,7,.16)}
body[data-flavor="forever"] .rail .navlink.adm::after,body[data-flavor="forever"] .mobmenu .navlink.adm::after{
  color:#170f07;border-color:rgba(23,15,7,.6);background:rgba(23,15,7,.22)}
body[data-flavor="forever"] .topbar{background:rgba(7,61,88,.94)}
body[data-flavor="forever"] .mobmenu{background:#c6af8d}
body[data-flavor="forever"] .vpanel,body[data-flavor="forever"] .vpr{background:var(--card)}
body[data-flavor="forever"] .btn-gold,body[data-flavor="forever"] .flv-a.on,
body[data-flavor="forever"] .flv-a.on:hover{background:#0f6064;color:#fdf6e6;box-shadow:inset 0 0 0 1px rgba(143,201,160,.45)}
body[data-flavor="forever"] .btn-gold:hover{background:#13767a}
body{margin:0;background:var(--bg);color:var(--fg);
  font:400 14px/1.6 'IBM Plex Sans',system-ui,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-decoration:none}
/* A link inside running text has to be findable without seeing the colour. */
.lede a,.sub a,.note a,.wk-n a,.wk-imp-h a,.wk-imp-k a,.sec-s a,.blurb a,p a,li a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px;text-decoration-color:color-mix(in oklab,var(--accent) 55%,transparent)}
.lede a:hover,.sub a:hover,.note a:hover,.wk-n a:hover,p a:hover,li a:hover{text-decoration-color:currentColor}
a:hover{color:var(--accent2)}
h1,h2,h3,h4{font-family:Cinzel,Georgia,serif;font-weight:400;letter-spacing:.02em;text-wrap:balance}
h1{font-size:clamp(28px,4.4vw,40px);line-height:1.1;margin:0 0 8px}
.h1-xl{font-size:clamp(34px,6vw,60px);line-height:1.02;margin:0 0 14px;letter-spacing:-.025em;max-width:18ch}
.mono,input,select,button{font-family:var(--mono)}
input,select,button{font-size:13px;color:inherit}
.main{min-width:0;padding:44px 56px 90px;display:flex;flex-direction:column;gap:46px}
/* Page sections were separated by their own margins; the shell owns that gap
   now, so a stray bottom margin would double it. */
.main>*{margin-bottom:0}
.wrap{max-width:100%;margin:0;padding:0}
.dim{color:var(--dim)}.dim2{color:var(--dim2)}.accent{color:var(--accent)}.sm{font-size:13.5px}.strong{font-weight:500}
.kicker{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim2)}
.sub{color:var(--dim);max-width:62ch;margin:0 0 26px}
.lede{color:var(--dim);font-size:18px;max-width:62ch;text-wrap:pretty}
.lede.sm{font-size:15px;margin-bottom:4px}
.lede p{margin:0 0 14px}
/* ---- shell: a sticky rail, and a top bar once the rail no longer fits ----- */
.shell{max-width:1480px;margin:0 auto;display:grid;grid-template-columns:236px minmax(0,1fr);align-items:start}
.rail{display:flex;flex-direction:column;gap:34px;position:sticky;top:0;height:100vh;
  padding:30px 26px;border-right:1px solid var(--line);overflow-y:auto}
.rail{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--fg) 14%,transparent) transparent}
.rail::-webkit-scrollbar{width:6px}
.rail::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--fg) 14%,transparent)}
.rail::-webkit-scrollbar-track{background:transparent}
.rail-foot{margin-top:auto;display:flex;flex-direction:column;gap:12px}
.rail-foot p{margin:0;font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--off)}
.brand{display:flex;align-items:center;gap:11px;color:var(--fg)}
.wm{font-family:Cinzel,Georgia,serif;font-size:17px;letter-spacing:.04em}
.wm b{font-weight:700;color:var(--accent)}
.wm{display:flex;flex-direction:column;line-height:1.1}
.wm-f{font-style:normal;font-family:var(--mono);font-size:9px;letter-spacing:.3em;
  text-transform:uppercase;color:var(--dim2);margin-top:3px}
.wm-f-ph{visibility:hidden}
.mark{flex:none;display:block}
/* Retail | Forever. Two links in one box, the current one filled: a segmented
   control, the same idiom as the region picker on the settings page. It sits
   between the brand and the nav in the rail, first in the mobile menu. */
.flv{display:flex;border:1px solid var(--line);padding:2px;gap:2px;background:var(--bg2)}
.flv-a{flex:1 1 0;text-align:center;font-family:var(--mono);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim);padding:7px 8px;white-space:nowrap}
.flv-a:hover{color:var(--fg)}
.flv-a.on{color:var(--on-accent);background:var(--accent)}
.flv-a.on:hover{color:var(--on-accent)}
.mobmenu .flv{margin:4px 12px 0}
/* The first-visit chooser (flavorPicker). Covers the root page rather than
   replacing it, so the page underneath is still the page. Each card wears
   its own game's colours -- retail's black and gold, Forever's teal and tan
   (the same values as body[data-flavor="forever"] below) -- so the choice
   reads before a word of it does. */
.pick{display:none}
html.pv-pick .pick{display:flex;position:fixed;inset:0;z-index:60;overflow-y:auto;
  padding:40px 16px;background:radial-gradient(ellipse 90% 60% at 50% 0,#1a1710 0,var(--bg) 70%)}
html.pv-pick body{overflow:hidden}
.pick-in{width:min(900px,100%);margin:auto;display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:10px}
.pick-brand{display:flex;align-items:center;gap:12px;color:var(--fg);margin-bottom:18px}
.pick-brand .wm{font-size:20px}
.pick-h{margin:0}
.pick-s{margin:0 0 22px;font-size:13.5px;color:var(--dim);max-width:52ch;text-wrap:pretty}
.pick-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:16px;width:100%}
.pick-c{display:flex;flex-direction:column;gap:10px;text-align:left;padding:24px 24px 20px;
  border:1px solid var(--line);background:var(--card);color:var(--fg);
  transition:border-color .15s,transform .15s,box-shadow .15s}
.pick-c:hover,.pick-c:focus-visible{border-color:var(--pc-accent,var(--accent));transform:translateY(-2px);
  box-shadow:0 10px 30px rgba(0,0,0,.35);outline:none}
.pick-k{font-family:var(--mono);font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--pc-accent,var(--accent))}
.pick-t{font-family:Cinzel,Georgia,serif;font-size:24px;line-height:1.15}
.pick-p{font-size:13.5px;line-height:1.6;color:var(--pc-dim,var(--dim));flex:1}
.pick-f{font-size:11.5px;color:var(--pc-dim2,var(--dim2))}
.pick-go{margin-top:6px;align-self:flex-start;font-family:var(--mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;padding:9px 14px;background:var(--pc-btn,var(--accent));color:var(--pc-on,var(--on-accent))}
.pick-c[data-flavor="forever"]{--pc-accent:#f2c14e;--pc-dim:#c8d6dd;--pc-dim2:#abc0cb;
  --pc-btn:#0f6064;--pc-on:#fdf6e6;color:#f3eee2;border-color:rgba(243,238,226,.2);
  background:linear-gradient(180deg,#02597e 0,#073d58 100%)}
.pick-c[data-flavor="forever"] .pick-go{box-shadow:inset 0 0 0 1px rgba(143,201,160,.45)}
/* The intro a flavor opens on before it has a week to track. */
.intro{display:flex;flex-direction:column;gap:30px}
.intro .st-c{margin-top:10px}
.intro .prose{max-width:68ch}
.intro-l{display:flex;flex-direction:column;gap:6px}
.dc-l{margin:0;padding-left:16px;display:flex;flex-direction:column;gap:5px;font-size:12.5px;color:var(--dim)}
.dc-l li::marker{color:var(--off)}
.tbl.dun{min-width:640px}
.tbl.dun .dun-n{color:var(--dim);max-width:34ch}
/* ---- alts: every character in one table -------------------------------
   The table the site already uses, with the class colour on the name, the
   level as the number that matters, and professions as small bars.
   display:table is spelled out because the class pages' .alts list is a
   flex column, and on the table that splits head and body into two grids
   whose columns no longer line up. */
.tbl.alts{display:table;min-width:980px}
.tbl.alts td{vertical-align:middle}
.tbl.alts tbody tr:not(.al-rx):hover{background:color-mix(in oklab,var(--accent) 5%,transparent)}
.al-s{background:none;border:0;padding:0;font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;cursor:pointer;white-space:nowrap}
.al-s:hover{color:var(--fg)}
th[aria-sort] .al-s{color:var(--accent)}
th[aria-sort=ascending] .al-s::after{content:' ▲'}
th[aria-sort=descending] .al-s::after{content:' ▼'}
.al-c{display:flex;align-items:center;gap:10px}
.al-c img{width:28px;height:28px;border:1px solid var(--line);flex:none}
.al-cn{display:flex;flex-direction:column;gap:2px;min-width:0}
/* Two small buttons, only for a character that actually has something to
   show: an export from before addon 1.12 has no bags or bank at all, and an
   icon nobody's client will ever fill in is worse than no icon. */
.al-inv{display:flex;gap:4px;flex:none;margin-left:auto}
.al-inv button{background:none;border:1px solid var(--line);width:24px;height:24px;padding:0;
  display:flex;align-items:center;justify-content:center;color:var(--dim2);cursor:pointer}
.al-inv button:hover{color:var(--accent);border-color:var(--accent)}
/* The last-synced clock: sits with the bag and bank buttons, shaped like them
   but not a button (nothing to press), so it is drawn without the hover. */
.al-sy{display:inline-grid;place-items:center;width:24px;height:24px;border:1px solid var(--line);color:var(--dim2);cursor:help}
.al-sy:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.al-sy.old{color:var(--danger-fg);border-color:color-mix(in srgb,var(--danger-fg) 60%,transparent)}
.al-n{font-family:Cinzel,Georgia,serif;font-size:15px;letter-spacing:.02em;color:var(--cc,var(--fg));text-decoration:none;white-space:nowrap}
.al-n:hover{text-decoration:underline}
.al-m{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.04em;color:var(--dim2)}
.al-lv{font-family:var(--mono);font-size:18px;color:var(--accent);line-height:1}
.al-x{display:block;width:64px;height:2px;background:var(--line);position:relative;margin:6px 0 3px}
.al-x i{position:absolute;inset:0 auto 0 0;background:color-mix(in oklab,var(--key) 70%,var(--accent));display:block}
.al-cls{color:var(--cc,var(--fg))}
.tbl.alts td.mono{white-space:nowrap}
.al-ps{display:flex;flex-direction:column;gap:6px;width:220px}
/* The game's professions bar: black, a brass edge, filled in the trade's
   own colour with a little gloss, the name and rank across the middle. */
.al-p{display:flex;align-items:center;gap:7px}
.al-p img,.al-2i img{border:1px solid var(--frame);flex:none;display:block}
.al-pb{position:relative;flex:1;min-width:0;height:18px;background:#050505;border:1px solid var(--frame);
  box-shadow:inset 0 0 0 1px #000;overflow:hidden;display:flex;align-items:center;justify-content:center}
.al-pb i,.al-2b i{position:absolute;inset:1px auto 1px 1px;width:var(--pw);display:block;
  background:linear-gradient(to bottom,color-mix(in srgb,var(--pc) 55%,#fff),var(--pc) 45%,color-mix(in srgb,var(--pc) 65%,#000))}
.al-pb span{position:relative;font-size:10.5px;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 6px;
  text-shadow:0 1px 1px #000,0 0 3px #000}
.al-2{display:flex;gap:10px;flex-wrap:wrap;margin-top:1px}
.al-2i{display:flex;align-items:center;gap:5px}
.al-2t{display:flex;flex-direction:column;gap:3px}
.al-2b{position:relative;width:34px;height:5px;background:#050505;border:1px solid var(--frame);display:block}
.al-2b i{inset:0 auto 0 0}
.al-2r{font-family:var(--mono);font-size:10px;color:var(--dim);line-height:1}
.al-g{color:var(--accent);white-space:nowrap}
.al-g i{font-style:normal;color:var(--dim2)}
#al-sum .v i{font-style:normal;font-size:11px;color:var(--dim2)}
button.al-p,button.al-2i{background:none;border:0;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;text-align:left}
button.al-p:hover .al-pb,button.al-2i:hover .al-2b{border-color:var(--accent)}
button.al-p .al-pb span::after{content:' ›';color:var(--accent)}
.tbl.alts tbody tr{cursor:pointer}
.tbl.alts tbody tr.on{background:color-mix(in oklab,var(--accent) 9%,transparent)}
.tbl.alts tbody tr.on td:first-child{box-shadow:inset 2px 0 0 var(--accent)}
/* Each character's row in a dark shade of its own class colour, with a
   stripe of it down the left edge. Not the class colour laid transparently
   over the teal: a colour washed over teal turns grey-blue (Paladin pink
   read as no pink at all), while the class colour darkened keeps its hue --
   Paladin a deep pink, Druid a burnt orange. The shades come from the script
   (--cw, --cwh hover, --cwo open), which darkens each class colour only as
   far as keeps the palest text in the row at a contrast of 5 (4.6 on hover
   and the open row), so a light class like Priest or Rogue gets a little
   less colour than the rest. The two greys go one step lighter inside a row
   and every text gets a faint shadow. The class-coloured name (Cinzel 700)
   and class (600) get a crisp 1px dark outline all round, and a class colour
   too dark for its row arrives lightened in --cct. */
.tbl.alts tbody tr[data-who]{background:var(--cw,transparent)}
.tbl.alts tbody tr[data-who] td:first-child{box-shadow:inset 3px 0 0 var(--cc,transparent)}
.tbl.alts tbody tr[data-who]:hover{background:var(--cwh,var(--cw,transparent))}
.tbl.alts tbody tr[data-who].on{background:var(--cwo,var(--cw,transparent))}
body[data-flavor="forever"] .tbl.alts tbody tr[data-who]{--dim:#dde7ec;--dim2:#c8d6dd}
.tbl.alts tbody tr[data-who] td{text-shadow:0 1px 1px rgba(0,0,0,.3)}
.tbl.alts tbody tr[data-who] .al-n{font-weight:700}
.tbl.alts tbody tr[data-who] .al-cls{font-weight:600}
.tbl.alts tbody tr[data-who] .al-n,.tbl.alts tbody tr[data-who] .al-cls{color:var(--cct,var(--cc,var(--fg)));
  text-shadow:-1px -1px 0 rgba(0,0,0,.8),1px -1px 0 rgba(0,0,0,.8),-1px 1px 0 rgba(0,0,0,.8),1px 1px 0 rgba(0,0,0,.8),
    0 1px 0 rgba(0,0,0,.8),0 -1px 0 rgba(0,0,0,.8),1px 0 0 rgba(0,0,0,.8),-1px 0 0 rgba(0,0,0,.8),0 2px 3px rgba(0,0,0,.5)}
.tbl.alts tbody tr[data-who].on td:first-child{box-shadow:inset 3px 0 0 var(--cc,var(--accent))}
.tbl.alts tbody tr td:first-child{padding-left:10px}
/* The unfolded sheet: a row of its own, joined to the row above it. */
.tbl.alts tbody tr.al-rx{cursor:default;background:none}
.tbl.alts tbody tr.al-rx td{border-top:0;padding:0 0 16px;box-shadow:none;vertical-align:top;font-size:inherit}
.al-rx-in{will-change:transform}
.al-rx .ch-detail{border-color:color-mix(in oklab,var(--accent) 45%,var(--line));border-top:2px solid var(--accent)}
/* The unfolded sheet in its character's colours: a calm shade of the class
   colour for the ground (--cx, from the script) and the class colour for its
   edges. Every block in it -- stats, the gear columns, each group of
   reputations, skills or recipes, each part of the history -- is a surface of
   its own, a step lighter with a hairline edge, so a long sheet reads as
   blocks instead of one blue field. The greys go one step lighter, as in
   the rows. */
.al-rx .ch-detail{background:var(--cx,var(--card));border-color:color-mix(in srgb,var(--cc,var(--accent)) 45%,var(--line));
  border-top:2px solid var(--cc,var(--accent));--blk:rgba(255,255,255,.05);--blk-l:rgba(255,255,255,.11)}
body[data-flavor="forever"] .al-rx .ch-detail{--dim:#dde7ec;--dim2:#c8d6dd}
.al-rx .ch-detail .vp-tab[aria-selected="true"]{border-bottom-color:var(--cc,var(--accent))}
.al-rx .repg{background:var(--blk);border:1px solid var(--blk-l);border-radius:4px;padding:0 14px;margin:0 0 10px}
.al-rx .repg:last-child{border-bottom:1px solid var(--blk-l);margin-bottom:0}
.al-rx .ch-kv,.al-rx .doll-c,.al-rx .doll-w,.al-rx .hi>section{background:var(--blk);border:1px solid var(--blk-l);border-radius:4px;padding:12px 16px}
.al-rx .ch-pvp .ch-kv{margin-top:2px}
.tbl.alts thead th:first-child{padding-left:10px}
/* Rested XP as a share of the level, gold once it is worth half a level or
   more; the line above the table names the alt with the most. */
.al-rs{font-family:var(--mono);font-size:13px;color:var(--dim)}
.al-rs.hi{color:var(--accent)}
.al-hint{margin:0;font-size:13px;color:var(--dim)}
.al-merge{display:flex;align-items:center;flex-wrap:wrap;gap:8px 12px;padding:10px 12px;
  border:1px solid color-mix(in srgb,var(--accent) 40%,transparent);background:color-mix(in srgb,var(--accent) 7%,transparent)}
.al-merge b{font-weight:600;color:var(--fg)}
/* display:flex above would otherwise win over [hidden] and leave an empty
   bordered box whenever there is nothing to suggest. */
.al-merge[hidden]{display:none}
.ch-mg{font:inherit;font-size:11px;background:var(--well);color:var(--dim);border:1px solid var(--line);padding:2px 6px;margin-left:6px;cursor:pointer}
.ch-mg:hover{color:var(--fg)}
.al-hint b{font-weight:400;color:var(--cc,var(--fg))}
/* An alt not synced for a while: the date turns warm, the tooltip says
   where it was left. */
/* ---- recipes: one profession's list, the game's window as a page ---------- */
.rv{display:flex;flex-direction:column;gap:12px;background:var(--card);border:1px solid var(--line);padding:16px 18px;min-width:0;white-space:normal}
.rv-h{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
.rv-t{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.rv-t img{border:1px solid var(--frame)}
.rv-t b{font-family:Cinzel,Georgia,serif;font-size:17px;font-weight:400;color:var(--fg)}
.rv-t .mono{font-size:11px}
.rv-f{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.rv-q{background:var(--bg);border:1px solid var(--line);color:var(--fg);font:inherit;font-size:12.5px;padding:6px 10px;width:220px;max-width:100%}
.rv-q:focus{outline:none;border-color:var(--accent)}
.rv-f label{font-size:10.5px;letter-spacing:.06em;color:var(--dim);display:flex;align-items:center;gap:6px;cursor:pointer}
.rv-key{display:flex;gap:14px;flex-wrap:wrap;font-size:10px;color:var(--dim2)}
.rv-key>span{display:flex;align-items:center;gap:5px}
.rv-key .rv-note{margin-left:auto}
.rv-d{width:8px;height:8px;flex:none;display:inline-block;border:1px solid #000}
.rv-d.d0{background:#ff8040}.rv-d.d1{background:#ffd200}.rv-d.d2{background:#40bf40}.rv-d.d3{background:#808080}
.rv-l{display:flex;flex-direction:column;gap:1px}
.rv-g{display:flex;flex-direction:column}
.rv-r{display:grid;grid-template-columns:8px minmax(160px,1.1fr) 2fr 70px;gap:12px;align-items:center;padding:7px 0;
  border-top:1px solid color-mix(in srgb,var(--fg) 6%,transparent);font-size:12.5px}
.rv-r:first-child{border-top:0}
.rv-n{min-width:0}
.rv-n a{color:var(--fg);text-decoration:none}
.rv-n a:hover{text-decoration:underline}
.rv-x{margin-left:6px;font-family:var(--mono);font-size:10.5px;color:var(--dim2)}
.rv-need{display:flex;flex-wrap:wrap;gap:4px 12px}
.rv-rg{display:inline-flex;align-items:baseline;gap:5px;font-size:11.5px}
.rv-rg b{font-family:var(--mono);font-weight:400;font-size:10.5px;color:var(--dim)}
.rv-rg a{color:var(--dim);text-decoration:none}
.rv-rg a:hover{color:var(--fg)}
.rv-rg i{font-style:normal;font-family:var(--mono);font-size:9.5px;color:var(--dim2);border:1px solid var(--line);padding:0 4px}
.rv-rg.short i{color:var(--danger-fg,#e06c5a);border-color:color-mix(in oklab,var(--danger-fg,#e06c5a) 40%,transparent)}
.rv-k{font-size:10.5px;color:var(--accent);text-align:right}
.rv-tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}
.rv-tab{display:flex;align-items:center;gap:7px;background:none;border:1px solid var(--line);color:var(--dim);font-size:11px;padding:4px 10px 4px 4px;cursor:pointer}
.rv-tab img{border:1px solid var(--frame)}
.rv-tab[aria-pressed=true]{border-color:var(--accent);color:var(--fg)}
.ch-pane .rv{background:none;border:0;padding:0}
.rv-share{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 14px;font-size:11px}
.rv-url{flex:1 1 260px;min-width:0;background:var(--bg);border:1px solid var(--line);color:var(--fg);
  font-family:var(--mono);font-size:11px;padding:5px 8px}
.share{display:flex;flex-direction:column;gap:22px}
.sh-foot{margin:0;font-size:12px;color:var(--dim2)}
.sh-foot a{color:var(--accent)}
@media (max-width:700px){
  .rv-r{grid-template-columns:8px 1fr auto;gap:6px 10px}
  .rv-need{grid-column:2 / -1;grid-row:2}
  .rv-key .rv-note{margin-left:0}
}
/* ---- professions, account-wide: every alt's recipe lists read together ----
   The recipe sheet's own parts (skill-up dots, reagent chips, folding groups)
   in a card of its own under the table, tabbed like the sheet. */
.pf{display:flex;flex-direction:column;gap:14px;min-width:0}
.pf-card{background:var(--card);border:1px solid var(--line);padding:18px 20px;display:flex;flex-direction:column;gap:18px;min-width:0}
.pf-pane{display:flex;flex-direction:column;gap:14px;min-width:0}
.pf-out{display:flex;flex-direction:column;gap:12px;min-width:0}
.pf-note{margin:0;font-size:11.5px;color:var(--dim2);line-height:1.6;max-width:84ch;text-wrap:pretty}
.pf-sum{margin:0;font-size:13.5px;color:var(--fg)}
.pf-bar{display:flex;align-items:center;gap:10px 14px;flex-wrap:wrap}
.pf-bar label{font-size:10.5px;letter-spacing:.06em;color:var(--dim);display:flex;align-items:center;gap:6px;cursor:pointer}
.pf-q,.pf-sel,.pf-num,.pf-w{background:var(--bg);border:1px solid var(--line);color:var(--fg);font-size:12.5px;padding:6px 10px;max-width:100%;min-width:0}
.pf-q,.pf-w{width:300px}
.pf-sel{max-width:min(100%,420px)}
.pf-num{width:76px}
.pf-q:focus,.pf-sel:focus,.pf-num:focus,.pf-w:focus{outline:none;border-color:var(--accent)}
.pf-sel option,.pf-sel optgroup{background:var(--card);color:var(--fg)}
.pf-sh{margin:0 0 14px}
.pf-sh .rv-share{margin:0}
.ash-who{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;margin-top:10px;font-size:13px}
.ash-c{display:inline-flex;align-items:center;gap:6px;color:var(--cc,var(--fg));cursor:pointer}
.ash-c input{width:auto;margin:0;accent-color:var(--accent)}
.acc-q input{width:100%;max-width:520px;font:inherit;font-size:15px;padding:10px 12px;background:var(--well);color:var(--fg);border:1px solid var(--line)}
.acc-q input:focus{outline:none;border-color:var(--accent)}
.acc-hits{display:flex;flex-direction:column;margin:10px 0 18px}
.acc-hits:empty{display:none}
.acc-hit{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;padding:8px 0;border-bottom:1px solid var(--line2);font-size:14px}
.acc-hit>a{min-width:220px}
.acc-who{background:none;border:0;padding:0;font:inherit;font-weight:600;color:var(--cc,var(--fg));cursor:pointer}
.acc-who:hover{text-decoration:underline}
.acc-hit .mono{display:inline-flex;align-items:center;gap:6px;font-size:12px}
.acc-chars{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:8px;margin:0 0 20px}
.acc-c{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:10px 12px;text-align:left;font:inherit;cursor:pointer;
  background:color-mix(in srgb,var(--cc,var(--accent)) 12%,var(--card));color:var(--fg);border:1px solid var(--line);box-shadow:inset 3px 0 0 var(--cc,var(--accent))}
.acc-c:hover{border-color:var(--cc,var(--accent))}
.acc-c[aria-pressed="true"]{border-color:var(--cc,var(--accent));background:color-mix(in srgb,var(--cc,var(--accent)) 22%,var(--card))}
.acc-n{font-family:Cinzel,Georgia,serif;font-weight:700;font-size:16px;color:var(--cc,var(--fg));
  text-shadow:-1px -1px 0 rgba(0,0,0,.7),1px -1px 0 rgba(0,0,0,.7),-1px 1px 0 rgba(0,0,0,.7),1px 1px 0 rgba(0,0,0,.7)}
.acc-m{font-size:11px;color:var(--dim)}
.acc-p{display:flex;flex-wrap:wrap;gap:8px}
.acc-p>span{display:inline-flex;align-items:center;gap:3px}
.acc-p i{font-style:normal;font-size:11px;color:var(--dim)}
.pf-hits{display:flex;flex-direction:column;gap:6px}
.pf-hits:empty{display:none}
.pf-hit{display:flex;align-items:center;gap:6px 12px;flex-wrap:wrap;padding:10px 14px;font-size:13px;
  border:1px solid color-mix(in oklab,var(--accent) 45%,var(--line));background:color-mix(in oklab,var(--accent) 8%,var(--card))}
.pf-hit>b{font-weight:500;color:var(--accent)}
.pf-hit a:not(.pf-who){color:var(--fg)}
.pf-hit .lnk-btn{margin-left:auto}
.pf-rec{padding:10px 0;border-top:1px solid var(--line2);display:flex;flex-direction:column;gap:7px;min-width:0}
.pf-rec:first-child{border-top:0}
.pf-rh{display:flex;align-items:center;gap:6px 10px;flex-wrap:wrap;font-size:13px}
.pf-rh img,.pf-p img{border:1px solid var(--frame);flex:none}
.pf-rh a{color:var(--fg);text-decoration:none}
.pf-rh a:hover{text-decoration:underline}
.pf-rh .mono{font-size:10.5px}
.pf-pool{margin-left:auto}
.pf-hs{display:flex;flex-direction:column;gap:4px;padding-left:12px;border-left:1px solid var(--line)}
.pf-h{display:flex;align-items:center;gap:4px 10px;flex-wrap:wrap;font-size:12px;min-width:0}
.pf-h .mono{font-size:10.5px}
.pf-who{font-family:Cinzel,Georgia,serif;font-size:14px;letter-spacing:.02em;text-decoration:none;color:var(--fg)}
a.pf-who:hover{text-decoration:underline}
.pf-ok{color:var(--accent)}
.pf-bad{color:var(--danger-fg,#e06c5a)}
.pf-pick{padding:12px 14px;border:1px solid color-mix(in oklab,var(--accent) 40%,var(--line));display:flex;flex-direction:column;gap:6px}
.pf-pick p{margin:0;font-size:13.5px}
.pf-p{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.pf-p b{font-family:Cinzel,Georgia,serif;font-size:16px;font-weight:400;color:var(--fg)}
.pf-p .mono{font-size:10.5px}
.pf-grp{display:flex;flex-direction:column;gap:6px;padding-top:12px;border-top:1px solid var(--line)}
.pf-grp:first-child{border-top:0;padding-top:0}
.pf-miss{margin:0;padding:6px 0 10px 16px;display:flex;flex-direction:column;gap:4px;font-size:12px}
.pf-miss a{color:var(--fg);text-decoration:none}
.pf-miss a:hover{text-decoration:underline}
.pf-miss li::marker{color:var(--off)}
.pf-miss .mono{font-size:10px;color:var(--dim2);margin-left:8px}
.pf-m{display:grid;grid-template-columns:minmax(150px,220px) 1fr;gap:4px 14px;align-items:center;padding:8px 0;border-top:1px solid var(--line2);font-size:12.5px}
.pf-m:first-child{border-top:0}
.pf-m>span:first-child{display:flex;align-items:center;gap:8px;color:var(--fg)}
.pf-m>span:first-child img{border:1px solid var(--frame)}
.pf-m .mono{font-size:10.5px}
.tbl.pf-t{min-width:560px}
.tbl.pf-t a:not(.pf-who){color:var(--fg);text-decoration:none}
.tbl.pf-t .pf-who{font-size:13px}
.rv-r.pf-r{grid-template-columns:8px minmax(160px,1.1fr) 2fr 150px}
.pf-r .rv-k{white-space:normal}
@media (max-width:700px){
  .pf-card{padding:14px 12px}
  .rv-r.pf-r{grid-template-columns:8px 1fr auto}
  .pf-m{grid-template-columns:1fr}
  .pf-pool{margin-left:0}
}
#al-sum:empty{display:none}
/* ---- your characters, from the addon --------------------------------------
   Same bones as the vault hero: the panel on the left, the sync card on the
   right. The list is one card per character; the card you pick opens the
   sheet below it, tabbed the way the game tabs it. */
.chars{display:flex;flex-direction:column;gap:22px}
.ch-main{min-width:0;display:flex;flex-direction:column;gap:22px}
/* Addon sync and item search used to sit as permanent strips above the
   roster; both are now a button beside the heading that opens the same
   .inv-box lightbox the bag/bank popup uses, so the roster starts right
   under the heading and the two tools cost one row between them. */
.ch-tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ch-sync-b{display:flex;align-items:center;gap:10px 18px;flex-wrap:wrap}
.ch-sync-in{display:flex;gap:8px;flex:1 1 360px;min-width:0}
.ch-sync-in input{flex:1;min-width:0;background:var(--bg);border:1px solid var(--line);color:var(--fg);
  font-family:var(--mono);font-size:12px;padding:7px 10px}
.ch-sync-in input:focus{outline:none;border-color:var(--accent)}
.ch-sync-in .btn-gold{flex:none}
.ch-sync-dl{display:flex;gap:16px;flex-wrap:wrap;font-size:11px}
.ch-sync-dl a{color:var(--dim);text-decoration:none;white-space:nowrap}
.ch-sync-dl a:hover{color:var(--accent)}
.ch-sync-b .wk-imp-m{flex-basis:100%;margin:0}
.ch-sync-b .wk-imp-m:empty{display:none}
/* One box, gear and bags and bank all read the same way: type, see who has
   it and where. */
.ch-find-b{display:flex;flex-direction:column;gap:10px}
.ch-find-b input{background:var(--bg);border:1px solid var(--line);color:var(--fg);
  font-family:var(--mono);font-size:12px;padding:7px 10px}
.ch-find-b input:focus{outline:none;border-color:var(--accent)}
.ch-find-r{display:flex;flex-direction:column;gap:1px;background:var(--line2)}
.ch-find-r:empty{display:none}
.cf-r{display:flex;align-items:center;gap:10px;padding:7px 10px;background:var(--card);font-size:12.5px}
.cf-r a{color:inherit;text-decoration:none}
.cf-r a:hover{text-decoration:underline}
.cf-w{color:var(--cc,var(--fg));flex:none;width:15ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cf-k{flex:none;width:9ch;font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim2)}
.cf-n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cf-c{flex:none;font-family:var(--mono);color:var(--dim)}
.ch-list{display:flex;flex-direction:column;gap:14px;min-width:0}
.ch-empty{margin:0;padding:22px;border:1px dashed var(--line);color:var(--dim);font-size:13px;line-height:1.6}
.ch-empty code{font-family:var(--mono);color:var(--fg)}
.ch-detail{background:var(--card);border:1px solid var(--line);padding:20px 22px;display:flex;flex-direction:column;gap:20px;min-width:0}
.ch-detail .vp-h{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap}
.ch-pane{min-width:0}
/* The bag/bank, addon sync and item search lightboxes: a native <dialog>,
   but opened with .show() rather than .showModal(). A modal dialog is
   promoted to the browser's top layer, which paints above literally
   everything else in the page regardless of z-index -- including the
   Wowhead tooltip script's, so an item's tooltip inside one of these boxes
   would render half hidden behind the box that named it. .show() keeps the
   dialog in ordinary stacking order (see z-index below, comfortably under
   Wowhead's), at the cost of doing the backdrop (#dlg-bg, a plain element
   now, not ::backdrop) and Esc-to-close by hand instead of for free.
   Sized to the content, not the viewport -- a bag of eight items should not
   open full-screen. The display property must stay scoped to [open]: any
   author rule for it, even at lower specificity, overrides the UA
   stylesheet's dialog:not([open]){display:none}, so an unscoped
   display:flex here shows the empty dialog on every page load instead of
   only when opened. */
.inv-box{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);margin:0;z-index:41;
  width:min(600px,94vw);max-height:min(640px,84vh);padding:16px 18px;
  background:var(--card);color:var(--fg);border:1px solid var(--line)}
.inv-box[open]{display:flex;flex-direction:column;gap:14px}
.dlg-bg{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:40}
.inv-h{display:flex;align-items:center;gap:10px}
.inv-t{font-family:Cinzel,Georgia,serif;font-size:16px;color:var(--fg)}
.inv-when{flex:1;min-width:0}
/* Close, always top right and big enough to find: margin-left:auto pushes it
   there whatever the text before it is (the bag header's line is short, and
   the button used to sit right after it). Shared by every lightbox. */
.inv-x{margin:-4px -6px -4px auto;flex:none;width:34px;height:34px;display:grid;place-items:center;padding:0;
  background:var(--bg2);border:1px solid var(--line);border-radius:3px;color:var(--fg);font-size:22px;line-height:1;cursor:pointer;
  transition:border-color .15s,color .15s}
.inv-x:hover{border-color:var(--accent);color:var(--accent)}
.inv-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* The Features drawer: everything the site does, sliding in from the right.
   Shown by .open (the script) or :target (a bare #features link before the
   script has run). The page behind stops scrolling while it is open. */
.feat{display:none;position:fixed;inset:0;z-index:50}
.feat:target,.feat.open{display:block}
.feat-bg{position:absolute;inset:0;background:rgba(0,0,0,.62);cursor:default}
.feat-p{position:absolute;top:0;right:0;bottom:0;width:min(620px,100vw);display:flex;flex-direction:column;
  background:var(--bg);border-left:1px solid var(--line);box-shadow:-24px 0 60px rgba(0,0,0,.45);animation:feat-in .22s ease-out}
@keyframes feat-in{from{transform:translateX(48px);opacity:0}}
@media (prefers-reduced-motion:reduce){.feat-p{animation:none}}
.feat-hd{display:flex;align-items:flex-start;gap:12px;padding:22px 24px 14px}
.feat-hd>div{flex:1;min-width:0}
.feat-hd h2{margin:6px 0 0;font-size:26px;line-height:1.15}
.feat-tabs{display:flex;gap:2px;padding:0 24px;border-bottom:1px solid var(--line);overflow-x:auto}
.feat-tab{padding:10px 12px;font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;
  color:var(--dim);text-decoration:none;border-bottom:2px solid transparent;margin-bottom:-1px}
.feat-tab:hover{color:var(--fg)}
.feat-tab[aria-selected="true"]{color:var(--accent);border-bottom-color:var(--accent)}
.feat-b{flex:1;min-height:0;overflow-y:auto;padding:4px 24px 24px;overscroll-behavior:contain}
.feat.tabbed .feat-sec[data-off],.feat.tabbed .feat-sh{display:none}
.feat-sh{margin:22px 0 0;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.ft{padding:20px 0;border-bottom:1px solid var(--line2)}
.ft:last-child{border-bottom:0}
.ft-t{margin:0 0 6px;font-size:17px;line-height:1.3}
.ft-p{margin:0 0 12px;color:var(--dim);font-size:14px;line-height:1.6;text-wrap:pretty}
.ft-i{display:block;width:100%;height:auto;margin:0 0 10px;border:1px solid var(--line);border-radius:4px;background:var(--card)}
/* A picture opens full size on click: a link to the image itself, so it
   still works without the script, which turns it into the .zoom overlay. */
.ft-z{display:block;position:relative;cursor:zoom-in}
.ft-z::after{content:"Click to enlarge";position:absolute;top:8px;right:8px;padding:3px 8px;border-radius:3px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;color:#fff;background:rgba(0,0,0,.7);opacity:0;transition:opacity .15s}
.ft-z:hover::after,.ft-z:focus-visible::after{opacity:1}
.ft-z:hover .ft-i{border-color:var(--accent)}
.ft-z:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.zoom{position:fixed;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;padding:56px 24px 24px;
  background:rgba(0,0,0,.86);cursor:zoom-out}
.zoom[hidden]{display:none}
.zoom img{display:block;max-width:min(1400px,96vw);max-height:calc(100vh - 90px);width:auto;height:auto;
  border:1px solid var(--line);border-radius:4px;box-shadow:0 20px 60px rgba(0,0,0,.6)}
.zoom .inv-x{position:absolute;top:14px;right:16px;margin:0}
.ft-l{font-size:11px;color:var(--accent);text-decoration:none}
.ft-l:hover{color:var(--accent2)}
.feat-ft{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:14px 24px;border-top:1px solid var(--line);background:var(--card)}
.feat-ft span{flex:1;min-width:160px;font-size:13px;color:var(--dim)}
.feat-ft .btn-gold{text-decoration:none;display:inline-block}
body.feat-lock{overflow:hidden}
@media (max-width:640px){.feat-hd{padding:16px 16px 10px}.feat-tabs{padding:0 16px}.feat-b{padding:4px 16px 20px}.feat-ft{padding:12px 16px}}
/* Bags and bank as the game draws them: icon slots with the stack count in
   the corner and a border in the item's quality colour, grouped by item class
   (Equipment, Consumables, Crafting...), each group split by subclass. The
   small subgroups sit side by side, so a bag of forty kinds of thing stays
   one screen tall. */
.inv-grid{overflow-y:auto;min-height:0;display:flex;flex-direction:column;gap:14px}
/* The scroll box clips at its own edge, and the hover outline below sits 3px
   outside a slot: without this room the first column and the last row lost
   the left and bottom of it. Pulled back out with the negative margin, so
   the icons still line up with the heading above. */
.inv-grid{padding:3px;margin:-3px}
.inv-g{display:flex;flex-direction:column;gap:6px}
.inv-gh{margin:0;font-size:12.5px;font-weight:600;color:var(--accent);display:flex;align-items:center;gap:8px}
.inv-gh::after{content:"";flex:1;height:1px;background:var(--line)}
.inv-subs{display:flex;flex-wrap:wrap;gap:8px 18px}
.inv-sub{display:flex;flex-direction:column;gap:4px;min-width:0}
.inv-sh{font-size:10.5px;color:var(--dim)}
.inv-slots{display:flex;flex-wrap:wrap;gap:4px}
.inv-s{position:relative;width:40px;height:40px;flex:none;display:block;border:1px solid var(--line);border-radius:3px;
  background:var(--well);overflow:hidden;text-decoration:none}
.inv-s img{display:block;width:100%;height:100%;object-fit:cover}
.inv-s b{position:absolute;right:2px;bottom:0;font-family:var(--mono);font-size:11px;font-weight:600;line-height:1.3;
  color:#fff;text-shadow:0 0 2px #000,0 0 2px #000,1px 1px 1px #000}
.inv-s:hover,.inv-s:focus-visible{outline:2px solid var(--accent2);outline-offset:1px}
.inv-s.q2{border-color:#1eff00}.inv-s.q3{border-color:#0070dd}.inv-s.q4{border-color:#a335ee}.inv-s.q5{border-color:#ff8000}
.inv-s.q0 img{filter:saturate(.6) brightness(.85)}
.inv-s.wait{background:linear-gradient(110deg,var(--well) 30%,var(--bg2) 50%,var(--well) 70%);background-size:200% 100%;
  animation:inv-wait 1.2s linear infinite}
@keyframes inv-wait{to{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){.inv-s.wait{animation:none}}
.ch-kv{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:0 28px}
.ch-kv .kv{font-size:13px}
.ch-kv .kv span:last-child{font-family:var(--mono);color:var(--fg)}
.ch-reps{display:flex;flex-direction:column;gap:1px}
.ch-reps .repg-b{grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.rep-s{font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--dim2)}
/* No r1..r8 classes on these: Wowhead's tooltip stylesheet, loaded on the
   same pages, owns .r1-.r4 (its recipe colours) and painted Hostile's text
   pure yellow. The row's data-st carries the standing instead. */
/* Each standing its own colour, red (Hated) through yellow (Neutral) and
   green to blue (Revered) and purple (Exalted), on the bar, the "... to X"
   line, a badge and a stripe down the left, so the level reads at a glance
   down a whole list. Every one keeps a contrast of 4.5 or more on the
   panels it sits on. Only rows that carry data-st (Forever's reputation
   window and sheet); retail's Battle.net rows keep their own look. */
.rep[data-st="1"]{--st:#ff9a94}.rep[data-st="2"]{--st:#ffab86}.rep[data-st="3"]{--st:#ffc27a}.rep[data-st="4"]{--st:#f2dc6a}
.rep[data-st="5"]{--st:#8fe06e}.rep[data-st="6"]{--st:#4fdcb4}.rep[data-st="7"]{--st:#7ccbff}.rep[data-st="8"]{--st:#d2adff}
.rep[data-st]{padding-left:10px;box-shadow:inset 3px 0 0 var(--st)}
.rep[data-st] .rep-s{color:var(--st)}
.rep[data-st] .rep-t{height:4px;border-radius:2px;background:color-mix(in srgb,var(--st) 16%,var(--line))}
.rep[data-st] .rep-t i{background:var(--st);border-radius:2px}
.rep-b{display:inline-block;margin-left:2px;padding:0 6px;border-radius:3px;line-height:1.6;
  color:var(--st,var(--dim2));border:1px solid color-mix(in srgb,var(--st,var(--dim2)) 45%,transparent);
  background:color-mix(in srgb,var(--st,var(--dim2)) 12%,transparent)}
.ch-pvp{display:flex;flex-direction:column;gap:14px}
.ch-pvp .big{font-family:Cinzel,Georgia,serif;font-size:26px;color:var(--fg)}
.ch-none{margin:0;color:var(--dim);font-size:13px}
/* The History tab: the character's own past, the account's gold as one
   quiet line, and the journal of every character under it. */
.hi{display:flex;flex-direction:column;gap:22px}
.hi-h{margin:0 0 8px}
.hi-l{list-style:none;margin:0;padding:0}
.hi-l li{display:flex;justify-content:space-between;align-items:baseline;gap:4px 14px;flex-wrap:wrap;
  padding:6px 0;border-bottom:1px solid var(--line2);font-size:13px;color:var(--fg)}
.hi-t{min-width:0}
.hi-w{font-weight:600}
.hi-a{font-size:10.5px;color:var(--dim2);white-space:nowrap}
.hi-sp svg{display:block;width:100%;height:48px;overflow:visible;cursor:crosshair}
.hi-sl{fill:none;stroke:var(--accent);stroke-width:2;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.hi-x{stroke:var(--dim2);stroke-width:1;vector-effect:non-scaling-stroke}
.hi-cap{margin:6px 0 0;font-size:11px;color:var(--dim)}
.hi-f{margin:0}
.ch-nudge{display:flex;align-items:center;gap:8px;margin:14px 0 0;color:var(--dim);font-size:13px}
.ch-nudge img{border:1px solid var(--frame);flex:none}
.ch-rm{background:none;border:0;padding:0;font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--off);cursor:pointer}
.ch-rm:hover{color:var(--danger-fg)}
/* Role tags: small chips under an alt's name, and a row of the same chips
   over the table to show only the alts that carry one. */
.al-tags{display:flex;flex-wrap:wrap;align-items:center;gap:3px;max-width:200px;margin-top:2px;white-space:normal}
.al-tag{display:inline-flex;align-items:center;gap:4px;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.06em;text-transform:uppercase;line-height:15px;color:var(--dim);border:1px solid var(--line);padding:0 5px;
  background:none;cursor:default}
.al-tx,.al-ta{background:none;border:0;padding:0;font-family:var(--mono);font-size:10px;line-height:15px;
  color:var(--off);cursor:pointer}
.al-tx:hover,.al-ta:hover{color:var(--accent)}
.al-ta{letter-spacing:.06em;text-transform:uppercase;font-size:9.5px}
@media (hover:hover){.tbl.alts tbody tr:not(:hover) .al-ta:not(:focus){opacity:0}}
button.al-ts{cursor:pointer;border-style:dashed}
button.al-ts:hover{color:var(--accent);border-color:var(--accent)}
.al-ti{width:92px;background:var(--bg);border:1px solid var(--line);color:var(--fg);font-family:var(--mono);
  font-size:10.5px;padding:1px 5px}
.al-ti:focus{outline:none;border-color:var(--accent)}
.al-tf{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.al-tf:empty{display:none}
.al-tf .lbl{margin-right:4px}
.al-tf .al-tag{cursor:pointer;font-size:10px;line-height:20px;padding:0 8px}
.al-tf .al-tag i{font-style:normal;color:var(--dim2)}
.al-tf .al-tag:hover{color:var(--fg)}
.al-tf .al-tag[aria-pressed=true]{color:var(--accent);border-color:var(--accent);
  background:color-mix(in oklab,var(--accent) 10%,transparent)}
/* An account-wide reading under the table: a few calm lines on what to roll
   next. Reputation spread used to sit beside it as a fold; it is a lightbox
   off the toolbar now, same as addon sync and item search, so .ch-box only
   has the one card left to lay out. */
.ch-x{display:flex;flex-wrap:wrap;gap:14px 22px;align-items:flex-start}
.ch-x[hidden]{display:none}
.ch-box{flex:2 1 460px;min-width:0;background:var(--card);border:1px solid var(--line);padding:14px 18px}
.ch-box.ch-next{flex:1 1 260px;display:flex;flex-direction:column;gap:10px}
.ch-box-s{margin:12px 0 4px;font-size:12px;color:var(--dim)}
.rep-w{grid-column:1 / -1;font-family:var(--mono);font-size:10px;color:var(--dim2);
  display:flex;gap:6px;align-items:baseline;min-width:0}
.rep-w button{background:none;border:0;padding:0;font:inherit;font-size:10.5px;color:var(--cc,var(--fg));cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rep-w button:hover{text-decoration:underline}
.ch-gap{margin:0;font-size:13px;color:var(--dim);line-height:1.6}
.ch-gap-l{display:flex;flex-wrap:wrap;gap:5px 12px;margin-top:6px}
.ch-gap-l span{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--fg)}
.ch-gap-l img{border:1px solid var(--frame)}
/* The paper doll: two columns of slots and the weapons under them, the
   game's own order, an empty slot drawn as a gap rather than left out. */
.doll{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 28px}
.doll-c{display:flex;flex-direction:column}
.doll-w{grid-column:1 / -1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 28px;margin-top:14px;
  border-top:1px solid var(--line);padding-top:6px}
.doll-a{margin:0 0 12px;font-size:11px;letter-spacing:.08em;color:var(--dim2)}
.gr{display:grid;grid-template-columns:72px minmax(0,1fr) 34px;gap:10px;align-items:baseline;padding:7px 0;border-bottom:1px solid var(--line2);font-size:13px}
.gr-s{font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim2)}
.gr-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration:none}
.gr.empty .gr-n{color:var(--off)}
.gr-l{font-size:11px;color:var(--dim2);text-align:right}
@media (max-width:720px){.ch-list{grid-template-columns:minmax(0,1fr)}.doll{grid-template-columns:minmax(0,1fr)}.doll-w{grid-template-columns:minmax(0,1fr)}}
.nav{display:flex;flex-direction:column;gap:2px;font-size:14px}
.navlink{color:var(--dim);padding:8px 10px;white-space:nowrap}
.navlink:hover{color:var(--fg);background:color-mix(in srgb,var(--fg) 4%,transparent)}
.navlink.on{color:var(--fg);background:color-mix(in srgb,var(--accent) 10%,transparent);box-shadow:inset 2px 0 0 var(--accent)}
/* The class jump list, colour-coded, reachable from every page. */
.rcls-list{display:flex;flex-direction:column;gap:1px;font-size:12px}
.rcls{padding:6px 10px;color:var(--cc);opacity:.75}
.rcls:hover{opacity:1;color:var(--cc);background:color-mix(in srgb,var(--fg) 5%,transparent)}
/* Below the rail breakpoint: a sticky bar and a panel it opens. */
.topbar{display:none;align-items:center;justify-content:space-between;gap:16px;
  padding:14px 16px;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:30;
  background:rgba(8,8,10,.94);backdrop-filter:blur(8px)}
.burger{display:flex;flex-direction:column;gap:4px;align-items:center;justify-content:center;
  width:44px;height:44px;margin:-11px -10px -11px 0;background:none;border:0;cursor:pointer}
.burger i{width:20px;height:2px;background:var(--fg)}
.mobmenu{display:none;flex-direction:column;gap:14px;padding:10px 8px 20px;
  background:#0b0b0e;border-bottom:1px solid var(--line);position:sticky;top:57px;z-index:29}
.mobmenu .navlink{font-size:15px;padding:12px}
.mob-cls-h{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--off);padding:0 12px}
.mob-cls{display:flex;flex-wrap:wrap;gap:6px;padding:0 12px}
.mob-cls .rcls{padding:8px 10px;background:color-mix(in srgb,var(--fg) 5%,transparent);opacity:1}
/* One breakpoint decides the whole shell: the rail goes, the bar arrives. */
@media (max-width:980px){
  .shell{grid-template-columns:minmax(0,1fr)}
  .rail{display:none}
  .topbar{display:flex}
  .mobmenu:not([hidden]){display:flex}
  .main{padding:22px 16px 70px;gap:34px}
  .cls{scroll-margin-top:70px}
}
/* An admin-only entry is labelled where it is used, so nobody has to remember
   which of these the public can actually see. */
/* De Account-link zegt zelf of je bent ingelogd, in hetzelfde idioom als de
   admin-badge hieronder. Dat hangt aan html.anon, dat in de <head> uit de
   pv_acct-cookie wordt gezet, dus het staat goed voordat er iets is getekend
   en het klopt op elke pagina, niet alleen op de accountpagina zelf. */
.navlink.acct{display:inline-flex;align-items:center;gap:7px}
html:not(.anon) .navlink.acct::after{content:"signed in";font-family:var(--mono);
  font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);
  border:1px solid color-mix(in oklab,var(--accent) 42%,transparent);
  background:color-mix(in oklab,var(--accent) 12%,transparent);padding:1px 4px}
.navlink.adm{display:inline-flex;align-items:center;gap:7px}
.navlink.adm::after{content:"admin";font-family:var(--mono);font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--key);border:1px solid color-mix(in oklab,var(--key) 42%,transparent);background:color-mix(in oklab,var(--key) 12%,transparent);padding:1px 4px}
.adm-note{display:flex;align-items:center;gap:9px;margin:0 0 18px;padding:9px 13px;font-size:13px;color:var(--dim);border:1px solid color-mix(in oklab,var(--key) 34%,transparent);background:color-mix(in oklab,var(--key) 9%,transparent)}
.adm-note b{color:var(--key);font-weight:600}
.tools{display:flex;align-items:center;gap:8px;margin-left:auto}
.tools input{width:190px}
.tools input,.tools select{background:var(--bg2);border:1px solid var(--line);padding:7px 10px;outline:none}
.tools input:focus,.tools select:focus{border-color:var(--accent)}
.card{display:block;background:var(--card);border:1px solid var(--line);color:inherit}
.card.tbl,.card.pad{box-shadow:inset 0 1px 0 color-mix(in oklab,var(--accent) 8%,transparent)}
.card.pad{padding:20px}
.card.soft{background:var(--bg2)}
.grid{display:grid;gap:14px}
.grid.cards{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));margin-bottom:26px}
.grid.two{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.grid.three{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.grid.cls-grid{grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:12px}
.stack{display:flex;flex-direction:column;gap:10px}
.stack.lg{gap:22px}
.stack.sm{gap:7px}
.meta{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.feat{padding:18px}
.feat h3{margin:9px 0 7px;font-size:19px;font-weight:600}
.feat p{margin:0;color:var(--dim);font-size:14.5px}
.feat:hover{border-color:var(--accent);color:inherit}
.ch{margin:0 0 14px;font-size:15px;font-weight:600}
.ch.lg{margin:9px 0 4px;font-size:19px}
.note{color:var(--dim);font-size:14px;margin:0 0 16px}
/* ---- vault hero ---------------------------------------------------------- */
.vhero{display:flex;flex-wrap:wrap;gap:28px;align-items:stretch}
/* A wrapping flex row, not a two-column grid: a hard second column squeezes the
   panel instead of letting the side cards drop beneath it. */
.vpanel{flex:1 1 420px;min-width:0;background:linear-gradient(150deg,#15141a,#0e0d10);
  border:1px solid var(--line);padding:30px;display:flex;flex-direction:column;gap:24px}
.vp-h{display:flex;align-items:baseline;justify-content:space-between;gap:16px}
.lbl{font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--dim2)}
.vp-reset{font-size:11px;color:var(--dim2)}
.vp-reset b{font-weight:400;color:var(--fg)}
/* The panel's heading is the first tab. Alone it is exactly the label it was
   before there was a second one; the switch only appears once the addon has
   sent something to switch to. */
.vp-tabs{display:flex;gap:20px;min-width:0;flex-wrap:wrap}
.vp-tab{background:none;border:0;padding:0 0 5px;font-family:inherit;cursor:pointer;
  border-bottom:1px solid transparent;transition:color .15s,border-color .15s}
.vp-tabs.one .vp-tab{cursor:default}
.vp-tab[aria-selected=true]{color:var(--fg);border-bottom-color:var(--accent)}
.vp-tabs.one .vp-tab[aria-selected=true]{border-bottom-color:transparent;color:var(--dim2)}
.vp-tab:not([aria-selected=true]):hover{color:var(--fg)}
.vp-pane{display:flex;flex-direction:column;gap:24px;min-width:0}
/* ---- what the vault is holding ------------------------------------------- */
.vp-when{margin:0;font-size:11px;color:var(--dim2)}
.gvl{display:flex;flex-direction:column;gap:18px}
.gvg-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  border-bottom:1px solid var(--line);padding-bottom:7px;margin-bottom:9px}
.gvg-t{font-size:13px}
.gvg-n{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim2)}
.gvi{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:2px 11px;
  align-items:center;padding:6px 0}
/* The comparison sits under the name, indented past the slot number, so the
   row still scans as one item rather than two columns of numbers. */
.gvi-c{grid-column:2 / -1;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.05em;color:var(--off)}
.gvi-c.up{color:var(--daily)}
.gvi-c.down{color:var(--faint)}
.gvi-c.open{color:var(--dim2)}
.gvi-c b{font-weight:400;font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent);border:1px solid color-mix(in oklab,var(--accent) 42%,transparent);
  background:color-mix(in oklab,var(--accent) 12%,transparent);padding:1px 4px;cursor:help}
/* The crest cost, on its own line under the comparison and indented to match
   it, so a row reads as one item: what it is, what it beats, what finishing it
   costs. Quieter than the comparison by default -- the comparison is why you
   would take the item at all, this is only what happens next. */
.gvi-k{grid-column:2 / -1;font-size:10px;letter-spacing:.05em;color:var(--off)}
/* Enough in the bag, and not enough. The same two readings the comparison
   above uses, in the same two colours, so one row does not speak two
   languages. */
.gvi-k.ok{color:var(--daily)}
.gvi-k.short{color:var(--faint)}
.gvi-s{font-size:10px;color:var(--faint);width:1.4em}
/* Wowhead's script drops its icon inside the link. Sized here so nine of them
   line up; with the script off the link stands alone and the row still reads. */
.gvi-a{display:flex;align-items:center;gap:9px;min-width:0;font-size:13.5px;font-weight:500;
  text-decoration:none;border:0}
.gvi-a .iconsmall,.gvi-a .icontiny,.gvi-a .iconmedium,.gvi-a .iconlarge{flex:none;width:26px;height:26px;
  display:block;position:relative;overflow:hidden;box-shadow:inset 0 0 0 1px var(--line)}
.gvi-a .iconsmall ins,.gvi-a .icontiny ins,.gvi-a .iconmedium ins,.gvi-a .iconlarge ins{display:block;width:100%;height:100%;
  background-size:cover;background-position:center}
.gvi-a .iconsmall del,.gvi-a .icontiny del,.gvi-a .iconmedium del,.gvi-a .iconlarge del{display:none}
.gvi-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  border-bottom:1px solid color-mix(in oklab,currentColor 28%,transparent)}
.gvi-a:hover .gvi-n{border-bottom-color:currentColor}
/* The track is the quieter half of the pair: the item level is the number you
   compare, the track is what it is on. Empty for an export that predates the
   addon sending it, and an empty span takes no room. */
.gvi-t{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--tc,var(--dim2));
  white-space:nowrap}
.gvi-l{font-size:12px;color:var(--accent)}
.gvi-l.none{color:var(--faint)}
.vp-foot{margin:0;font-size:12px;line-height:1.7;color:var(--dim)}
.vp-b{display:flex;flex-wrap:wrap;gap:28px;align-items:center}
.vslots{flex:none;display:grid;grid-template-columns:repeat(3,46px);grid-auto-rows:46px;gap:7px}
.vslots i{display:flex;align-items:center;justify-content:center;font-style:normal;
  font:500 13px/1 var(--mono);
  background:color-mix(in srgb,var(--fg) 7%,transparent);box-shadow:inset 0 0 0 1px var(--line);transition:background .18s}
/* The number is only ever painted on a slot you have actually opened, so it is
   always read against the gold rather than against the empty square. */
.vslots i.on{background:linear-gradient(180deg,#f0d081,var(--accent));box-shadow:none;
  color:var(--on-accent)}
/* A floor rather than a figure, so it is quieter than one the game reported. */
.vslots i.min{font-size:11px;letter-spacing:-.02em;
  color:color-mix(in oklab,var(--on-accent) 60%,transparent)}
/* A square you have not opened counts down to itself instead of sitting blank.
   Grey and signed, so it can never be misread as one of the gold item levels. */
.vslots i.need{font-size:11px;letter-spacing:-.02em;color:var(--faint)}
/* The open square is its track. A stripe under the gold was invisible at 46px
   and a fade into the gold was still the gold's square with a tint on it, so
   the colour takes the whole cell: nine squares then say which tracks the week
   is paying in one look, in the same five colours the loot tables use.
   Open against closed is unharmed -- a closed square is dark grey and an open
   one is a light saturated fill, which is a wider gap than gold against grey
   ever was -- and the count beside them says the number outright.
   Same shape as the gold it replaces: a lightened top into the colour itself,
   so a track square and a gold one are the same object in two hues. The dark
   item level clears 5.2:1 on all six at full saturation, so nothing here has
   to be lightened to stay readable. A slot with no track at all keeps the
   gold, which is the rule this one overrides. */
.vslots i.on[class*="t-"]{background:linear-gradient(180deg,
  color-mix(in oklab,var(--tc) 70%,#fff2d8),
  var(--tc))}
/* A floor is a bound rather than a reading. It keeps the hue and drops the
   saturation, so it reads as this track un-confirmed rather than as a track of
   its own -- the same distinction its "at least" number already makes. Below
   the .on rule on purpose: both match a floor square at the same weight, and
   this is the one that should win. */
.vslots i.min[class*="t-"]{background:linear-gradient(180deg,
  color-mix(in oklab,var(--tc) 45%,#fff2d8),
  color-mix(in oklab,var(--tc) 62%,#fff2d8))}
.vp-n{flex:1 1 190px;min-width:0;display:flex;flex-direction:column;gap:14px}
.vp-big{display:flex;align-items:baseline;gap:8px;margin:0}
.vp-big #st-slots{font-size:46px;line-height:1;color:var(--accent)}
.vp-of{font-size:16px;color:var(--off)}
.vp-cap{font-size:12px;color:var(--dim);margin-left:4px}
.vp-note{margin:0;font-size:12px;line-height:1.7;color:var(--dim)}
.vp-note b{font-weight:400;color:var(--fg)}
.vp-note .dimmer{color:var(--tc,var(--faint))}
/* One row per vault source. The 1px gaps are the background showing through. */
.vp-rows{display:flex;flex-direction:column;gap:1px;background:color-mix(in srgb,var(--fg) 9%,transparent)}
.vpr{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;align-items:center;
  background:#0e0d10;padding:11px 2px 11px 0}
.vpr-b{width:3px;height:22px;background:color-mix(in srgb,var(--fg) 16%,transparent)}
/* Gold said only "this source has credit", which the count beside it already
   says. The track it is paying is the thing the bar can say that nothing else
   on the line does. No track known and it falls back to the gold. */
.vpr.on .vpr-b{background:var(--tc,var(--accent))}
.vpr-t{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vpr-n{font-size:11px;color:var(--dim2);white-space:nowrap}
.vpr-n i{font-style:normal;color:#4e4a44}
.vside{flex:1 1 260px;max-width:320px;min-width:0;display:flex;flex-direction:column;gap:28px}
.scard{background:var(--card);border:1px solid var(--line);padding:22px;display:flex;flex-direction:column;gap:14px}
.scard.grow{flex:1}
.sbars{display:flex;flex-direction:column;gap:12px}
.sbar{display:flex;flex-direction:column;gap:7px}
.sb-h{display:flex;justify-content:space-between;font-size:12px;color:var(--dim)}
.sb-n{color:var(--fg)}
.sb-t{height:4px;background:color-mix(in srgb,var(--fg) 9%,transparent)}
.sb-t i{display:block;height:100%;width:0;background:var(--accent);transition:width .25s ease}
.sb-t.d i{background:var(--daily)}
.s-p{margin:0;font-size:12px;line-height:1.6;color:var(--dim)}
.s-p code{font-family:var(--mono);color:var(--fg)}
.s-in{display:flex;gap:8px}
.s-in input{flex:1;min-width:0;background:var(--well);border:1px solid color-mix(in srgb,var(--fg) 14%,transparent);color:var(--fg);
  font-family:var(--mono);font-size:12px;padding:9px 10px;outline:none}
.s-in input:focus{border-color:var(--accent)}
.btn-gold{background:var(--accent);color:var(--on-accent);border:0;font-family:inherit;font-size:12px;
  font-weight:600;padding:9px 14px;cursor:pointer}
.btn-gold:hover{background:var(--accent2)}
/* The first download pins itself to the bottom of the card. The second must
   follow it, not claim a second helping of the free space -- with two of them
   both taking auto, the card spreads them to opposite ends of whatever height
   it happens to have. */
.s-dl{font-size:11px;color:var(--dim2);margin-top:auto}
.s-dl + .s-dl{margin-top:0}
.s-dl:hover{color:var(--accent)}

.wk-intro{margin:0;font-size:12px;line-height:1.7;color:var(--faint);max-width:74ch}
/* The checklist switched off site-wide. Hidden rather than dropped: the Great
   Vault panel reads its progress off these cards, so removing them would leave
   the nine squares stuck at zero. Everything you can click on goes. */
#checklist.off .wk-intro,#checklist.off .wk-imp{display:none}
/* ...except the vault band. It was caught by the blanket rule above, which is
   how the nine squares kept working while the thing that says what is in each
   one disappeared. The vault rows are counted off the game's own vault, not
   off a quest id, so they are the half that was never in doubt. The group
   header goes: its running total counts the hidden quest rows. */
#checklist.off .band:not(.vault),#checklist.off .wk-grp .wk-h{display:none}
#checklist.off .wk-grp:not(:has(.band.vault)){display:none}
.wk-btn{background:none;border:1px solid var(--line);padding:4px 10px;font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim2);cursor:pointer;transition:border-color .15s,color .15s}
.wk-btn:hover{border-color:var(--accent);color:var(--accent)}
.wk-btn[aria-pressed=true]{border-color:color-mix(in oklab,var(--accent) 45%,var(--line));background:color-mix(in oklab,var(--accent) 14%,transparent);color:var(--accent)}
#wk-notes{margin-left:auto}
.wk-grp{display:flex;flex-direction:column;gap:22px}
.wk-grp+.wk-grp{margin-top:42px}
.wk-h{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap;
  border-bottom:1px solid var(--line);padding-bottom:12px;margin:0}
.wk-hl{margin:0;font-family:Cinzel,Georgia,serif;font-weight:400;font-size:26px;letter-spacing:.02em}
.wk-sum,.wk-cd,.wk-clr{font-family:var(--mono);font-size:11px}
.wk-sum{color:var(--dim2);margin-left:auto}
.wk-cd{letter-spacing:0;text-transform:none;color:#4e4a44}
.wk-clr{background:none;border:0;padding:0;color:var(--dim2);cursor:pointer}
.wk-clr:hover{color:var(--danger-fg)}
.band{display:flex;flex-direction:column;gap:12px}
.band+.band{margin-top:10px}
.wk-sub{display:flex;align-items:baseline;gap:9px;margin:0}
.wk-bsum{margin-left:auto;font-size:10px;letter-spacing:.06em;color:var(--off)}
.wk-bsum.full{color:var(--accent)}
.wk-sub .n,.wk-sub h4{font-family:var(--mono);font-size:10px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--off);font-weight:400;margin:0}
.lnk{color:inherit}
.lnk:hover{color:var(--accent)}
.lnk::after{content:"\2197";font-size:.72em;margin-left:3px;color:var(--dim2);vertical-align:super}
.lnk:hover::after{color:var(--accent)}

.wk-ticks{display:flex;gap:3px;width:100%}
.tick{position:relative;flex:1;min-width:0;height:15px;padding:0;border:0;
  background:color-mix(in srgb,var(--fg) 12%,transparent);cursor:pointer;transition:background .12s}
.tick:hover{background:color-mix(in srgb,var(--fg) 22%,transparent)}
.tick:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tick.on{background:var(--accent)}
/* A single-step entry is a checkbox, not a bar: it reads as a thing you tick. */
.wk-ticks.one{justify-content:flex-start}
.wk-ticks.one .tick{flex:none;width:15px;height:15px;background:none;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg) 28%,transparent)}
.wk-ticks.one .tick:hover{box-shadow:inset 0 0 0 1px var(--accent)}
.wk-ticks.one .tick.on{background:var(--accent);box-shadow:none}
.wk-ticks.one .tick.on::after{content:"";position:absolute;left:4px;top:4px;width:7px;height:7px;background:var(--on-accent)}
.wk-ticks.pips .tick{height:8px}

.vgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.vcard{background:var(--card);border:1px solid var(--line);padding:16px;display:flex;flex-direction:column;gap:12px}
.vc-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
/* Slot state is read by the hero panel and the band summary; drawing it a
   second time inside every card only repeats what the nine squares say. */
.vc-slots{display:none}
.vc-t{display:block;font-size:14px;font-weight:500;line-height:1.3}
.vc-h .wk-c{font-size:11px;color:var(--dim2)}
.vc-m{display:flex;align-items:baseline;justify-content:flex-end;gap:10px}
.vc-next{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:color-mix(in oklab,var(--key) 78%,var(--fg));text-align:right}
.vc-r{border-top:1px solid var(--line);padding-top:7px;margin-top:1px;display:flex;flex-direction:column;gap:1px}
.vslot{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:22px}
.vs-req{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--dim2);white-space:nowrap}
.vs-pick{max-width:64%;border:0;background:none;padding:2px 0;font-size:12.5px;color:var(--tc,var(--fg));text-align:right;text-align-last:right;cursor:pointer;outline:none;border-bottom:1px dotted transparent}
.vs-pick:hover:not(:disabled){border-bottom-color:var(--accent);color:var(--accent)}
.vs-pick:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.vs-pick:disabled{color:var(--dim2);opacity:.5;cursor:default}
.vslot.locked .vs-req{opacity:.5}
.vs-pick option{background:var(--card);color:var(--tc,var(--fg))}
/* The closed select wears the chosen track's colour, so --tc is set on the
   select and inherited by the whole list. The empty first option carries no
   track of its own and must not borrow that one: initial makes var() fall
   through to the plain text colour, which is what a dash should read as. */
.vs-pick option:not([class]){--tc:initial}

/* The tick column is a fixed width so a lone checkbox and a group of three or
   five pips all align on the same two edges. That is the difference between
   this reading as a list and reading as noise. */
.wk{display:grid;grid-template-columns:58px minmax(0,1fr) auto auto;gap:14px;align-items:center;
  background:var(--bg2);padding:13px 16px;cursor:pointer}
.wk:hover{background:var(--row-hover)}
.rows{display:flex;flex-direction:column;gap:1px;background:color-mix(in srgb,var(--fg) 8%,transparent)}
.wk-t{font-size:13px;font-weight:400;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wk-c{font-size:11px;color:var(--off);text-align:right}
.wk-tag{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim2);
  background:color-mix(in srgb,var(--fg) 6%,transparent);padding:3px 7px;justify-self:end;white-space:nowrap}
.wk-tag.paid{color:var(--fg);letter-spacing:.04em}
.wk-tag.paid b{font-weight:600}
.wk-w,.wk-n{display:none}
.wk-w{align-items:center;gap:6px;font-size:12px;color:var(--dim2);padding-top:2px}
.wk .wk-w,.wk .wk-n{grid-column:2/-1}
.wk-n{font-size:13px;line-height:1.5;color:var(--dim);padding:1px 0 6px;max-width:74ch}
.pin{flex:none;color:var(--accent);opacity:.8}
#checklist.notes .wk-w{display:flex}
#checklist.notes .wk-n{display:block}
#checklist.notes .wk-t{white-space:normal}
#checklist.notes .vcard .wk-n{padding-bottom:0}
.wk.synced .wk-t::before,.vcard.synced .vc-t::before,.wk.manual .wk-t::before,.vcard.manual .vc-t::before{content:"";display:inline-block;width:5px;height:5px;margin-right:7px;vertical-align:middle}
.wk.synced .wk-t::before,.vcard.synced .vc-t::before{background:var(--accent);opacity:.85}
.wk.manual .wk-t::before,.vcard.manual .vc-t::before{box-shadow:inset 0 0 0 1px var(--dim2)}
.wk.done .wk-t{color:var(--dim2);text-decoration:line-through;text-decoration-color:color-mix(in oklab,var(--dim2) 55%,transparent)}
.wk.done .wk-tag{opacity:.5}

.wk-imp{margin-top:28px;padding-top:18px;border-top:1px solid var(--line)}
.wk-imp summary{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim2);gap:8px}
.wk-imp summary:hover{color:var(--accent)}
.wk-imp-h{margin:12px 0 10px;font-size:13.5px;color:var(--dim);max-width:70ch}
.wk-imp-h code,.wk-imp-k code{font-family:var(--mono);font-size:12.5px;color:var(--accent)}
.wk-imp-dl{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 14px}
.wk-imp-dl .btn{margin-top:0}
.wk-imp-dl code{font-family:var(--mono);font-size:12px;color:var(--dim)}
.wk-imp-r{display:flex;gap:8px;flex-wrap:wrap}
.wk-imp-r input{flex:1 1 320px;min-width:0;background:var(--bg2);border:1px solid var(--line);padding:8px 10px;outline:none}
.wk-imp-r input:focus{border-color:var(--accent)}
.wk-imp-m{margin:10px 0 0;font-size:11.5px;color:var(--dim2);min-height:1.2em}
.wk-imp-m.bad{color:var(--accent)}
.wk-imp-k{margin:8px 0 0;font-size:11px;color:var(--dim2);max-width:74ch;line-height:1.8}
.key-dot{display:inline-block;width:5px;height:5px;vertical-align:middle}
.key-dot.on{background:var(--accent)}
.key-dot.off{box-shadow:inset 0 0 0 1px var(--dim2)}
.kvs{display:flex;flex-direction:column}
.kv{display:flex;justify-content:space-between;gap:14px;padding:9px 0;border-bottom:1px solid var(--line);font-size:14.5px}
/* Inside a delve card the pair is label left, value right, and the value gets
   the room: these are short numbers with long names beside them. */
.dcard .kvs{gap:0}
.dcard .kv{font-size:12px;gap:12px;align-items:baseline;padding:8px 0;color:var(--dim2)}
.dcard .kv:last-child{border-bottom:0;padding-bottom:0}
.dcard .kv>span:first-child{flex:0 1 auto;min-width:0}
.dcard .kv>span:last-child{flex:0 0 auto;text-align:right;color:var(--fg);font-size:11.5px}
.kv span:first-child{color:var(--dim)}
.kv.top{border-bottom:0;border-top:1px solid var(--line);padding:8px 0 0;margin-bottom:8px;align-items:baseline}
.g2,.g4{display:grid;gap:12px;align-items:center}
.g2{grid-template-columns:1fr auto}
.g4{grid-template-columns:1.5fr 1.05fr 1.05fr .95fr}
.g2.head,.g4.head{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim2);padding-bottom:7px;border-bottom:1px solid var(--line)}
.g2.r,.g4.r{font-size:14.5px;padding:9px 0;border-bottom:1px solid var(--line)}
.g2.r>span:first-child,.g4.r>span:first-child{color:var(--dim)}
.g2.r .strong,.g4.r .strong{color:var(--fg)}
.il{display:inline-flex;flex-direction:column;gap:1px;min-width:0}
/* ---- loot and delve tables ----------------------------------------------- */
.page-h{display:flex;flex-direction:column;gap:12px}
.page-s{margin:0;font-size:13px;color:var(--dim2);max-width:60ch;text-wrap:pretty}
.legend{display:flex;gap:10px;flex-wrap:wrap;font-size:10px;letter-spacing:.14em;text-transform:uppercase}
.lg-i{display:flex;align-items:center;gap:7px;color:var(--dim2)}
.lg-i i{width:9px;height:9px;background:currentColor}
.sec-h.col{flex-direction:column;align-items:stretch;gap:7px}
.sec-n{margin:0;font-size:12px;color:var(--dim2);text-wrap:pretty}
/* A wide table scrolls inside its own box; the page never scrolls sideways.
   Same thin, translucent bar as the rail, so it reads as the site's own
   scrollbar rather than the browser's default. */
.tw{overflow-x:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--fg) 14%,transparent) transparent}
.tw::-webkit-scrollbar{height:6px}
.tw::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--fg) 14%,transparent)}
.tw::-webkit-scrollbar-track{background:transparent}
.tbl{border-collapse:collapse;width:100%;min-width:600px;font-size:12px;text-align:left}
.tbl th{font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim2);font-weight:400;padding:0 14px 10px 0}
.tbl th:last-child,.tbl td:last-child{padding-right:0}
.tbl td{padding:11px 14px 11px 0;border-top:1px solid color-mix(in srgb,var(--fg) 8%,transparent);vertical-align:top}
.tbl tr.best{background:color-mix(in srgb,var(--accent) 5%,transparent)}
.tbl .tier{display:flex;flex-direction:column;gap:2px}
.t-n{font-size:12px}
.t-q{font-size:10px;color:var(--faint)}
/* Track colours, Blizzard's own ladder from Adventurer up to Myth: green,
   blue, gold, red, purple. The site used to run its own ordering, grey up to
   gold, which reads fine on its own page and wrong beside the game and beside
   every cheat sheet built from it. Darkened from the in-game hues rather than
   taken raw, which on a near-black background glare. */
.t-adventurer{--tc:#78ab6e}
.t-veteran{--tc:#5d9bd6}
.t-champion{--tc:#dba63c}
.t-hero{--tc:#d4705c}
.t-myth{--tc:#a683da}
.t-pvp{--tc:#8d867a}
/* Naming the colour and taking it are two steps on purpose. Anything that
   declares a colour of its own -- .il-t, .gvi-t, an <option> -- matches at the
   same weight as a single-class .t-hero on the same element and wins on source
   order alone, which is how the table labels the legend promises came out
   grey. Those read var(--tc,<their own colour>) instead: the track wins when
   the element carries one, the component's own colour stands when it does not,
   and neither answer depends on where in this file the rules sit. --tc
   inherits, so a chip carries the class on its outer span and both halves
   follow. A rule with two classes still outranks all of this, which is what
   keeps a capped crest red and an empty vault slot grey. */
.t-adventurer,.t-veteran,.t-champion,.t-hero,.t-myth,.t-pvp{color:var(--tc)}
.dgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.dcard{background:var(--card);border:1px solid var(--line);padding:18px;display:flex;flex-direction:column;gap:12px}
.dcard.hi{border-color:color-mix(in srgb,var(--accent) 22%,transparent)}
.dc-p{margin:0;font-size:12px;line-height:1.6;color:var(--dim)}
.il-n{display:flex;align-items:center;gap:6px;font-size:14.5px;white-space:nowrap}
.il-i{width:13px;height:13px;flex:none;color:var(--dim2)}
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.il-drop .il-i{color:var(--accent)}
.il-vault .il-n{color:var(--dim)}
.il-crest .il-n{color:var(--dim)}
.il-t{font-size:10.5px;line-height:1.35;letter-spacing:.08em;text-transform:uppercase;color:var(--tc,var(--dim2));text-wrap:pretty}
/* Inside a table the cell is one line: the number, then the track beside it in
   the track's colour. The stacked form stays for the cards on Home. */
.tbl .il{display:flex;flex-direction:row;align-items:baseline;gap:7px;flex-wrap:wrap}
.tbl .il-l{display:none}
.tbl .il-t{font-size:11px;letter-spacing:0;text-transform:none}
/* At 11px the hue on its own is too thin a signal to scan a column by, so the
   track label carries a wash of its own colour. Only a real track gets one:
   "no vault slot" would otherwise be washed in the inherited text colour and
   read as a tier of its own. */
.tbl .il-t[class*=" t-"]{padding:2px 6px;background:color-mix(in oklab,currentColor 14%,transparent)}
/* The number takes the track's colour too, but pulled most of the way back to
   the body text: the item level is the thing you read, the tier is the thing
   you glance at, and full saturation on both leaves neither in front. */
.tbl .il-n{font-size:12px;gap:0;color:color-mix(in oklab,currentColor 42%,var(--fg))}
.tbl .il-none .il-n,.tbl .il-none .il-t{color:var(--off)}
.tbl tbody tr:hover{background:var(--row-hover)}
.tbl tbody tr.best:hover{background:color-mix(in oklab,var(--accent) 9%,var(--row-hover))}
/* Source column: the affix marker and the "4 a week" style cap under a row. */
.rw-x{text-decoration:none;color:var(--accent);cursor:help;margin-left:2px}
.rw-c{display:block;margin-top:3px;font-size:10.5px;color:var(--faint)}
/* The level flow builder: an ordered list of zones with reorder/remove
   buttons, then the same row shape again for the saved routes below it. */
.zf-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.zf-row{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--line);font-size:12.5px}
.zf-row .zf-n{font-family:var(--mono);font-size:11px;color:var(--dim2);min-width:1.4em;text-align:right}
.zf-row .zf-lv{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--dim2)}
.zf-row .zf-btns{display:flex;gap:10px;flex-shrink:0}
.zf-empty{margin:0;font-size:12px;color:var(--dim2)}
/* The two ladders. Numbers only, so the columns are narrow and the row's own
   track colour does the labelling. */
.lad td{white-space:nowrap}
.lad .sp{margin-left:6px;font-size:10px;color:var(--accent)}
.lad-h{margin:0;font-size:12px;line-height:1.7;color:var(--dim)}
.lad-s{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;margin-top:2px}
.lad-s div{background:var(--card);border:1px solid var(--line);padding:14px 16px}
.lad-s b{display:block;font-weight:500;font-size:12px;margin-bottom:4px}
.lad-s span{font-size:11.5px;line-height:1.6;color:var(--dim)}
.il-none{opacity:.5}
.il-l{display:none;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim2)}
.ilvl-block{margin-top:18px;border-top:1px solid var(--line);padding-top:14px}
.row.three{grid-template-columns:1.5fr 1.1fr 1.1fr}
.btn{display:inline-block;white-space:nowrap;margin-top:16px;border:1px solid var(--line);padding:8px 12px;font-size:14px;font-family:inherit}
.btn:hover{border-color:var(--accent)}
details.card{padding:18px 20px}
summary{display:flex;align-items:center;gap:14px;list-style:none;cursor:pointer}
summary::-webkit-details-marker{display:none}
.sum-kind{min-width:84px}
.sum-t{font-size:19px;font-weight:600;flex:1}
.det{padding-top:14px}
.steps{margin:0;padding-left:18px;display:grid;gap:6px;font-size:14.5px}
h4.kicker{margin:0 0 9px}
.tbl{overflow:hidden}
.tbl-h{padding:15px 20px;border-bottom:1px solid var(--line);display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.tbl-h h2{margin:0;font-size:17px;font-weight:600}
.row{display:grid;gap:8px;padding:12px 20px;border-bottom:1px solid var(--line);font-size:14.5px;align-items:center}
.row.four{grid-template-columns:1.5fr 1.05fr 1.05fr .95fr}
.row.five{grid-template-columns:.75fr 1fr 1fr 1fr .9fr}
.row.bis{grid-template-columns:.8fr 1.9fr 1.1fr}
.panel>*+*{margin-top:14px}
.steps.num{padding-left:20px}
.src a{color:color-mix(in oklab,var(--cc,var(--accent)) 80%,var(--fg))}
.stale{color:var(--accent);font-weight:500}
.row.head{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim2);padding:10px 20px}
.row-card{display:flex;gap:18px;align-items:baseline;flex-wrap:wrap;padding:17px 20px}
.row-card:hover{border-color:var(--accent)}
.pid{font-size:15px;min-width:56px}
.rc-t{font-size:16.5px;font-weight:600;flex:1 1 200px}
.rc-s{flex:1 1 100%;max-width:70ch}
.cc{color:color-mix(in oklab,var(--cc) 88%,var(--fg))}
.back{display:inline-block;color:var(--dim);font-size:14px;margin-bottom:18px}
.tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:20px}
.tab{background:none;border:1px solid var(--line);padding:8px 14px;font-family:inherit;font-size:14.5px;font-weight:500;color:var(--dim);cursor:pointer}
.tab.on{background:color-mix(in oklab,var(--cc) 18%,transparent);border-color:color-mix(in oklab,var(--cc) 45%,var(--line));color:color-mix(in oklab,var(--cc) 88%,var(--fg))}
.panel{display:none}
.panel.on{display:block}
.src{margin:18px 0 0;padding:0;font-size:11.5px;color:var(--dim2);text-align:right}
.src a{color:var(--dim2);text-decoration:underline;text-decoration-color:color-mix(in oklab,var(--dim2) 45%,transparent)}
.src a:hover{color:var(--accent)}
.ftr{display:flex;flex-wrap:wrap;gap:10px 20px;justify-content:space-between;align-items:center;
  border-top:1px solid var(--line);padding-top:20px;margin-top:auto;font-size:11px;color:var(--off)}
.ftr-l{color:var(--off);margin-right:auto}
.ftr-l:hover{color:var(--accent)}
.ftr-bsky{display:inline-flex;align-items:center;gap:7px;color:var(--off);text-decoration:none}
.ftr-bsky:hover{color:var(--accent)}
/* A finger is not a mouse pointer. On a touch screen the tick boxes and the
   small controls grow to a real hit area; the dense look stays on desktop. */
@media (pointer:coarse){
  .wk-ticks{gap:6px}
  .tick{width:24px;height:24px}
  .tick.on::after{left:8px;top:4px;width:6px;height:12px;border-width:0 2.5px 2.5px 0}
  .wk-btn{min-height:34px;padding:8px 12px}
  .vs-pick{min-height:34px}
  .navlink{padding:10px 12px}
  .wk{min-height:44px}
}
@media (max-width:720px){
  .tools{margin-left:0;width:100%}
  .tools input{flex:1;width:auto}
  .row.four,.row.five{grid-template-columns:1fr 1fr}
  .row.head{display:none}
  .il-l{display:inline}
  .g4{grid-template-columns:1fr 1fr;row-gap:10px}
  .g4.head{display:none}
  .g4.r>span:first-child{grid-column:1/-1}
  .vgrid{grid-template-columns:1fr}
  .wk{grid-template-columns:minmax(0,1fr) auto;gap:3px 10px;padding:9px 0}
  .wk-t{grid-row:1;grid-column:1;white-space:normal}
  .wk-tag{grid-row:1;grid-column:2}
  .wk-ticks{grid-row:2;grid-column:1}
  .wk-c{grid-row:2;grid-column:2}
  .wk .wk-n,.wk .wk-w{grid-column:1/-1}
  .g2,.g2.head{grid-template-columns:1fr auto}
  .g2 .il-l{display:none}
}

/* ---- class anchors ------------------------------------------------------- */
/* Nothing sticky covers the top of the content column on desktop, so the
   anchor only has to clear the mobile bar. */
.cls{scroll-margin-top:24px}

/* ---- classes directory --------------------------------------------------- */
/* One section per class: a colour bar, the name in the class colour, and a
   hairline that fades out of that colour into the ordinary rule. */
.cls{display:flex;flex-direction:column;gap:14px}
.cls+.cls{margin-top:32px}
.cls-h{display:flex;align-items:center;gap:14px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.cls-bar{width:4px;height:20px;background:var(--cc);flex:none}
.cls-n{margin:0;font-size:22px;color:var(--cc)}
.cls-rule{flex:1;height:1px;background:linear-gradient(90deg,var(--cc),var(--line) 40%)}
.cls-c{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--off);white-space:nowrap}
.cgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}
.scell{background:var(--card);box-shadow:inset 0 0 0 1px var(--line);padding:16px;
  display:flex;flex-direction:column;gap:14px}
.scell-h{display:flex;align-items:center;gap:11px}
.crow-i{width:32px;height:32px;flex:none;background:#0d0c0b;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.6),0 0 0 1px var(--cc)}
.scell-n{display:flex;flex-direction:column;gap:3px;min-width:0}
.scell-n b{font-size:14px;font-weight:500}
.scell-n .mono{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim2)}
.scell-l{display:flex;flex-direction:column;gap:8px}
.gset{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.gsrc{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--off);width:52px;flex:none}
.glink{font-size:12px;color:var(--accent)}
.glink:hover{color:var(--accent2)}
@media (pointer:coarse){.glink{padding:4px 0}}

/* ---- class pages -------------------------------------------------------- */
/* Item quality colours are Blizzard's own scale. They are the fastest way to
   read a gear list, with or without the tooltip script attached. */
.itm{font-weight:500}
.q0{color:#9d9d9d}.q1{color:#ffffff}.q2{color:#1eff00}.q3{color:#0070dd}.q4{color:#a335ee}.q5{color:#ff8000}
a.itm{text-decoration:none;border-bottom:1px solid color-mix(in oklab,currentColor 32%,transparent)}
a.itm:hover{border-bottom-color:currentColor}
/* No item id yet, so this is a name search rather than the item itself. */
a.itm.noid{border-bottom-style:dotted;border-bottom-color:color-mix(in oklab,currentColor 40%,transparent)}
.row.bis{grid-template-columns:104px minmax(0,1.1fr) minmax(0,.8fr) minmax(0,1.2fr);align-items:start}
.row.bis .kicker{padding-top:2px}
.alts{display:flex;flex-direction:column;gap:5px;min-width:0}
.alt{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;font-size:13px}
.alt-src{font-family:var(--mono);font-size:10px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--dim2)}
.alt-note{font-size:12px;color:var(--dim2)}
.ld-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px}
.ld-top .kicker{margin:0}
.ld-when{font-size:10px;letter-spacing:.08em;color:var(--dim2)}
.ld{border:1px solid var(--line);padding:13px 15px;background:var(--bg2)}
.ld+.ld{margin-top:10px}
.ld-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}
.ld-n{font-size:15px;font-weight:600}
.ld-calc{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase}
.ld-note{margin:7px 0 0;font-size:13.5px;color:var(--dim)}
.ld-copy{display:flex;align-items:center;gap:9px;margin-top:10px}
.ld-str{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  background:var(--bg);border:1px solid var(--line);padding:7px 9px;
  font-family:var(--mono);font-size:11.5px;color:var(--dim)}
.ld-btn{flex:none}
.ld-btn.done{border-color:color-mix(in oklab,var(--key) 55%,var(--line));color:var(--key)}
.kvs.items .kv{display:block;padding:11px 0}
.kvs.items .kv:first-child{padding-top:2px}
.kvs.items .kv:last-child{border-bottom:0;padding-bottom:2px}
.kv-k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--dim2);margin-bottom:5px}
.kv-v{display:block;line-height:1.5}
.kvs.items .kv-v a{margin-right:2px}
.kv-or{color:var(--dim2);font-size:12px}
.fine-note{margin:12px 0 0;font-size:12.5px;color:var(--dim2)}
@media (max-width:720px){
  .row.bis{grid-template-columns:1fr 1fr}
  .row.bis>span:first-child{grid-column:1/-1}
  .alts{grid-column:1/-1}
}

/* ---- settings ---------------------------------------------------------- */
/* ---- signed-out notice ---------------------------------------------------- */
/* Hidden by default and revealed only for a visitor with no account cookie, so
   the wrong state is never shown even for one frame. */
/* De tegenhanger van de anonbalk: hetzelfde signaal, andere kant op. Beide
   hangen aan html.anon, dat in de <head> wordt gezet voordat er iets
   getekend is, zodat geen van beide even verkeerd staat. */
/* Vaste paginatekst die alleen klopt als je uitgelogd bent. Hij stond er
   altijd, ook boven "Signed in" en boven de storingsmelding, waar hij het
   tegendeel beweerde van wat eronder stond. */
html:not(.anon) .anon-only{display:none}
.anonbar{display:none}
/* A preview page explains itself in its own banner, and "not signed in"
   beside a page full of somebody's characters would only confuse. */
html.anon body[data-demo] .anonbar{display:none}
/* Preview is for people without an account yet. html.anon is set in <head>
   from the pv_acct cookie, before first paint, so a signed-in visitor never
   sees the entry flash in and out. */
html:not(.anon) .navlink.demo{display:none}

/* The way into the preview from a home page. Loud on purpose: it is the one
   thing a first visit with nothing synced can do besides read. The script
   sets [hidden] once the browser has characters of its own, and display:flex
   would otherwise win over it. */
.try{display:flex;align-items:center;gap:18px;margin:0 0 22px;padding:16px 18px 16px 20px;
  border:1px solid color-mix(in srgb,var(--accent) 45%,transparent);border-radius:4px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--accent) 15%,transparent),color-mix(in srgb,var(--accent) 4%,transparent));
  color:var(--fg);text-decoration:none;transition:border-color .15s,transform .15s}
.try[hidden]{display:none}
.try:hover,.try:focus-visible{border-color:var(--accent);transform:translateY(-1px)}
.try-k{flex:none;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.try-b{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}
.try-t{font-size:17px;font-weight:600;line-height:1.3}
.try-s{font-size:13px;line-height:1.5;color:var(--dim);text-wrap:pretty}
.try-go{flex:none;padding:9px 14px;background:var(--accent);color:var(--on-accent);font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;border-radius:3px}
.try:hover .try-go{background:var(--accent2)}
body[data-flavor="forever"] .try-go{background:#0f6064;color:#fdf6e6;box-shadow:inset 0 0 0 1px rgba(143,201,160,.45)}
body[data-flavor="forever"] .try:hover .try-go{background:#13767a}
@media (max-width:640px){
  .try{flex-wrap:wrap;gap:10px 14px}
  .try-k{width:100%}
  .try-go{width:100%;text-align:center}
}

/* The preview's own banner, and the three steps at its foot. */
.demo-bar{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:16px 28px;align-items:end;
  margin:0 0 26px;padding:22px 24px;border:1px solid color-mix(in srgb,var(--accent) 40%,transparent);border-radius:4px;
  background:linear-gradient(135deg,color-mix(in srgb,var(--accent) 12%,var(--card)),var(--card) 70%)}
.demo-bar h1{margin:6px 0 8px}
.demo-bar .lede{margin:0}
.demo-bar-a{display:flex;flex-direction:column;align-items:flex-end;gap:8px}
.demo-bar-a .btn-gold{text-decoration:none;display:inline-block}
.demo-bar-n{font-size:11px;color:var(--dim2)}
@media (max-width:760px){
  .demo-bar{grid-template-columns:minmax(0,1fr);padding:18px 16px}
  .demo-bar-a{align-items:flex-start}
}
.demo-steps{list-style:none;margin:0;padding:0;counter-reset:st;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr));gap:14px}
.demo-steps li{counter-increment:st;padding:16px 18px;background:var(--card);border:1px solid var(--line);
  font-size:13.5px;line-height:1.6;color:var(--dim)}
.demo-steps li::before{content:counter(st);display:block;font-family:var(--mono);font-size:22px;line-height:1;
  color:var(--accent);margin-bottom:10px}
.demo-steps b{color:var(--fg);font-weight:600}
.pick-demo{margin:22px 0 0;display:flex;flex-direction:column;align-items:center;gap:12px}
.pick-demo-t{font-size:14px;color:var(--fg)}
.pick-demo-l{display:flex;flex-wrap:wrap;justify-content:center;gap:10px}
.pick-demo-a{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;padding:10px 16px;
  color:var(--accent);border:1px solid color-mix(in srgb,var(--accent) 55%,transparent);text-decoration:none;
  transition:background .15s,border-color .15s}
.pick-demo-a:hover,.pick-demo-a:focus-visible{background:color-mix(in srgb,var(--accent) 12%,transparent);border-color:var(--accent)}
.pick-demo-a[data-flavor="forever"]{color:#8fc9a0;border-color:rgba(143,201,160,.5)}
.pick-demo-a[data-flavor="forever"]:hover{background:rgba(143,201,160,.1);border-color:#8fc9a0}

html.anon .anonbar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;padding:11px 14px;background:color-mix(in srgb,var(--accent) 7%,transparent);
  box-shadow:inset 2px 0 0 var(--accent);font-size:12px;color:var(--dim)}
.anonbar-t{min-width:0}
/* Two ways in, because half the people reading this line already have an
   account and "Create an account" is not an invitation they need. */
.anonbar-l{display:flex;align-items:center;gap:18px;white-space:nowrap}
.anonbar-a{font-size:12px;color:var(--accent);white-space:nowrap}
.anonbar-a:hover{color:var(--accent2)}
.anonbar-a.dim{color:var(--dim)}
.anonbar-a.dim:hover{color:var(--accent)}
@media(max-width:560px){.anonbar-l{gap:12px}.anonbar-a.dim{display:none}}

/* ---- prose pages ---------------------------------------------------------- */
.prose{max-width:68ch;display:flex;flex-direction:column;gap:0}
.prose h2{font-size:22px;margin:34px 0 0;padding-bottom:10px;border-bottom:1px solid var(--line)}
.prose h2:first-child{margin-top:0}
.prose h3{font-size:15px;font-weight:500;font-family:'IBM Plex Sans',system-ui,sans-serif;
  letter-spacing:0;margin:22px 0 0}
.prose p{margin:14px 0 0;font-size:13px;line-height:1.75;color:var(--dim);text-wrap:pretty}
.prose ul,.prose ol{margin:12px 0 0;padding-left:18px;display:flex;flex-direction:column;gap:8px}
.prose li{font-size:13px;line-height:1.7;color:var(--dim);text-wrap:pretty}
.prose li b,.prose p b{color:var(--fg);font-weight:500}
.prose code{font-family:var(--mono);font-size:12px;color:var(--fg)}

/* ---- account -------------------------------------------------------------- */
.acc-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:46px}
.acc-pane{display:flex;flex-direction:column;gap:46px}
/* A flex display beats the hidden attribute, so say it again explicitly. */
.acc-pane[hidden]{display:none}
.acc-f{display:flex;flex-direction:column;gap:14px;max-width:44ch}
.acc-f label{display:flex;flex-direction:column;gap:6px;font-size:12px;color:var(--dim)}
.acc-f input{background:var(--well);border:1px solid var(--line);color:var(--fg);
  font-family:inherit;font-size:13px;padding:10px 11px;outline:none}
.acc-f input:focus{border-color:var(--accent)}
.acc-f input:disabled{opacity:.5}
.acc-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:4px}
.lnk-btn{background:none;border:0;padding:0;font-family:inherit;font-size:12px;
  color:var(--dim2);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.lnk-btn:hover{color:var(--accent)}
a.obtn{display:inline-block}
/* The status line holds its height so an answer never shifts the form. */
.acc-msg{min-height:1.4em;font-size:11.5px;color:var(--dim2)}
.acc-msg.on{border-left:2px solid var(--accent);padding-left:10px}
.acc-msg.bad{color:var(--danger-fg);border-left-color:var(--danger)}
#account{display:flex;flex-direction:column;gap:24px}

/* ---- settings ------------------------------------------------------------ */
.set-stack{display:flex;flex-direction:column;gap:46px}
/* The region is a choice between two things, so it reads as two cards with a
   radio dot rather than as a pair of buttons. */
.seg{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.seg-b{display:flex;align-items:center;gap:12px;text-align:left;background:var(--card);
  border:1px solid var(--line);padding:16px;cursor:pointer;font-family:inherit;color:var(--dim)}
.seg-b i{width:13px;height:13px;flex:none;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg) 28%,transparent)}
.seg-b span{display:flex;flex-direction:column;gap:3px;font-size:11px;
  font-family:var(--mono);letter-spacing:.06em;color:var(--dim2)}
.seg-b b{font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:13px;font-weight:500;
  letter-spacing:0;color:var(--fg)}
.seg-b:hover{border-color:color-mix(in oklab,var(--accent) 40%,var(--line))}
.seg-b[aria-pressed=true]{border-color:color-mix(in srgb,var(--accent) 45%,transparent);background:color-mix(in srgb,var(--accent) 7%,transparent)}
.seg-b[aria-pressed=true] i{background:var(--accent);box-shadow:inset 0 0 0 1px var(--accent),inset 0 0 0 4px #12100c}
/* An outline button: used for the two bulk actions and for clearing data. */
.obtn{background:none;border:1px solid var(--line);padding:6px 12px;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim2);cursor:pointer;transition:border-color .15s,color .15s}
.obtn:hover{border-color:var(--accent);color:var(--accent)}
.obtn.danger:hover{border-color:var(--danger);color:var(--danger-fg)}
.chips{display:flex;gap:4px;flex-wrap:wrap}
.chip{background:none;border:1px solid var(--line);padding:4px 8px;font-family:inherit;font-size:10px;
  letter-spacing:.06em;color:var(--off);cursor:pointer;white-space:nowrap;transition:border-color .15s,color .15s}
.chip:hover{border-color:var(--accent);color:var(--accent)}
.chip[aria-pressed=true]{border-color:color-mix(in srgb,var(--accent) 45%,transparent);background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent)}
.set-warn{margin:0;font-size:12px;color:var(--faint);max-width:70ch}
.set-grp{display:flex;flex-direction:column;gap:0}
.set-grp+.set-grp{margin-top:22px}
.set-grp .wk-sub{margin:0 0 8px}
.set-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto 40px;gap:14px;align-items:center;
  padding:10px 0;border-bottom:1px solid color-mix(in oklab,var(--line) 50%,transparent);cursor:pointer;
  position:relative;min-height:44px}
.set-row:last-child{border-bottom:0}
.set-one{border-bottom:0;padding-top:2px}
.set-t{font-size:13px}
/* A row switched off says so by going quiet, not by disappearing. */
.set-row:has(.set-x:not(:checked)) .set-t{color:var(--off)}
.set-b{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim2);white-space:nowrap}
.set-x{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.sw{justify-self:end;width:38px;height:20px;background:color-mix(in srgb,var(--fg) 9%,transparent);
  border:1px solid var(--line);position:relative;transition:background .15s,border-color .15s}
.sw::after{content:"";position:absolute;left:3px;top:3px;width:14px;height:14px;background:var(--dim2);transition:left .12s ease,background .12s}
.set-x:checked+.sw{background:color-mix(in oklab,var(--accent) 26%,transparent);
  border-color:color-mix(in oklab,var(--accent) 55%,var(--line))}
.set-x:checked+.sw::after{left:21px;background:var(--accent)}
.set-x:focus-visible+.sw{outline:2px solid var(--accent);outline-offset:2px}
.set-row:hover .sw{border-color:color-mix(in oklab,var(--accent) 45%,var(--line))}
.set-g{min-width:0}
.set-goal{background:var(--bg2);border:1px solid var(--line);padding:5px 8px;
  font-size:11px;color:var(--dim);outline:none;cursor:pointer}
.set-goal:hover,.set-goal:focus{border-color:color-mix(in oklab,var(--accent) 45%,var(--line));color:var(--fg)}
.set-goal option{background:var(--card);color:var(--fg)}
.set-n{margin-left:auto;font-size:10.5px;letter-spacing:.06em;color:var(--dim2)}
.set-btns{display:flex;gap:8px;flex-wrap:wrap;margin-left:auto}
/* Which alt's week you are looking at. Only drawn once there are two. */
.wk-who{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:0 0 20px;
  padding-bottom:16px;border-bottom:1px solid var(--line2)}
.wk-who .chip{font-size:11px;padding:5px 10px}
.wk-who .chip:disabled{cursor:default}
.wk-who .chip:disabled:hover{border-color:color-mix(in srgb,var(--accent) 45%,transparent);color:var(--accent)}
/* Paired machines on the account page. */
.dev-l{display:flex;flex-direction:column;gap:0;margin:0}
.dev-r{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding:11px 0;border-bottom:1px solid var(--line2)}
.dev-r:last-child{border-bottom:0}
.dev-n{font-size:13.5px}
.dev-m{font-size:11px;color:var(--faint);letter-spacing:.06em}
.dev-code{font-family:var(--mono);font-size:26px;letter-spacing:.34em;color:var(--accent);
  padding:14px 0 4px}
/* A rule with a word in it, to separate the password form from the other way in. */
.bnet-or{display:flex;align-items:center;gap:12px;margin:16px 0 14px;color:var(--off);
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase}
.bnet-or::before,.bnet-or::after{content:"";flex:1;height:1px;background:var(--line)}
.bnet-btn{display:inline-block}
.bnet-n{margin-top:10px}
.bnet-tag{font-family:var(--mono);font-size:13px;color:var(--accent)}
/* Fifty alts is a normal number, so this has to stay readable at that size:
   a dense wrapping grid rather than a list, sorted so the ones you actually
   play are at the top. */
.chars-tools{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap}
.chars-count{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim2)}
.chars-grid{display:flex;flex-wrap:wrap;gap:6px;max-height:340px;overflow-y:auto;
  padding:2px 2px 4px;margin-top:2px}
.chr{background:none;border:1px solid var(--line);padding:6px 10px;cursor:pointer;
  font-family:inherit;font-size:12px;color:var(--dim);display:flex;align-items:baseline;gap:7px;
  transition:border-color .15s,color .15s,background .15s}
.chr:hover{border-color:var(--accent);color:var(--fg)}
.chr[aria-pressed=true]{border-color:color-mix(in srgb,var(--accent) 45%,transparent);background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent)}
.chr i{font-style:normal;font-family:var(--mono);font-size:10px;color:var(--off)}
.chr[aria-pressed=true] i{color:color-mix(in oklab,var(--accent) 70%,transparent)}
/* The class colour names the character; the gold border says it is picked. Two
   different questions, so they are answered by two different properties rather
   than fighting over the text colour. */
/* ---- every alt at once ---------------------------------------------------- */
.week{display:flex;flex-direction:column;gap:12px;margin-bottom:26px}
.week-h{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding-bottom:11px;border-bottom:1px solid var(--line)}
.week-list{display:flex;flex-direction:column;gap:1px;background:var(--line2);
  border:1px solid var(--line)}
/* Name, the nine squares, the count, gear, score, and what is left to do.
   Tabular figures so the three number columns line up down the list. */
.wk-r{background:var(--card);display:grid;
  grid-template-columns:minmax(90px,1.1fr) auto 46px 54px 54px auto minmax(0,1.4fr);
  gap:14px;align-items:center;padding:11px 16px;font-variant-numeric:tabular-nums}
.wk-r:hover{background:var(--row-hover)}
.wk-r-n{font-size:13.5px;color:var(--cc,var(--fg));text-decoration:none;border:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wk-r-n:hover{color:var(--cc,var(--accent));text-decoration:underline;
  text-underline-offset:2px}
.wk-sq{display:grid;grid-template-columns:repeat(3,7px);grid-auto-rows:7px;gap:2px}
.wk-sq i{background:color-mix(in srgb,var(--fg) 8%,transparent);box-shadow:inset 0 0 0 1px var(--line2)}
.wk-sq i.on{background:var(--accent);box-shadow:none}
.wk-r-c{font-size:11px;color:var(--dim2);text-align:right}
.wk-r-i{font-size:12px;color:var(--accent);text-align:right}
.wk-r-m{font-size:12px;color:var(--dim);text-align:right}
.wk-r-x{font-size:11.5px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* One bar per crest tier, in the same colours the loot table gives the gear
   tracks, because in this game a crest tier and a gear track are the same word.
   The fill is a hard-stopped gradient rather than a nested element: it is one
   node per tier either way, and currentColor then means the bar is coloured by
   its track class alone, with nothing to keep in step. */
/* One column per crest tier: its initial over a bar of how full its cap is.
   Five thin bars alone were a smudge at this size and needed a legend the row
   has no space for; the letter carries the name and the colour then only has
   to agree with it. */
.wk-cr{display:flex;gap:5px;color:var(--off)}
.wk-crc{display:flex;flex-direction:column;align-items:stretch;gap:2px;width:13px;cursor:help}
/* The colour is set on the column and inherited by both halves, never declared
   on them: a declared .wk-crc b would outrank the single-class .t-hero and
   every letter would come out grey. Inheritance loses to any rule at all, which
   is exactly the precedence wanted. */
.wk-crc b{font-family:var(--mono);font-weight:500;
  font-size:9.5px;line-height:1;letter-spacing:0;text-align:center;color:inherit}
.wk-crc i{height:3px;
  background:linear-gradient(to right,currentColor var(--f,0%),color-mix(in srgb,var(--fg) 9%,transparent) var(--f,0%))}
/* Nothing against this tier's name: the letter stays, so the column still reads
   left to right, and it drops back to the dimmest text on the site. */
.wk-crc.off{color:var(--off);opacity:.55}
/* Full is the one reading here that is bad news - everything that tier pays
   from now on is thrown away - so it is the one that gets the warning colour
   rather than the gold a finished vault slot gets. */
.wk-crc.cap{color:var(--danger-fg)}
.wk-crc.cap i{background:var(--danger)}
.wk-cr.none{width:0}
@media (max-width:720px){
  .wk-r{grid-template-columns:minmax(0,1fr) auto auto auto;gap:8px 12px}
  .wk-r-i,.wk-r-m{display:none}
  .wk-r-x{grid-column:1 / -1;white-space:normal}
}
/* ---- the roster page ----------------------------------------------------- */
.ros-tools{display:flex;align-items:center;justify-content:space-between;gap:14px 20px;flex-wrap:wrap;
  padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:22px}
.ros-r{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
#ros-tabs .chip{font-size:11.5px;padding:6px 11px;color:var(--cc,var(--off))}
#ros-tabs .chip:hover{color:var(--cc,var(--accent))}
#ros-tabs .chip[aria-selected=true]{border-color:color-mix(in srgb,var(--accent) 45%,transparent);
  background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--cc,var(--accent))}
.ros-list{display:flex;flex-direction:column;gap:1px;background:var(--line2);border:1px solid var(--line)}
.rosc{background:var(--card);padding:22px;display:grid;
  grid-template-columns:minmax(0,1fr);gap:20px}
/* The armory shape: gear down both flanks, the character between them. The
   render is Blizzard's own and arrives at whatever size they drew it, so the
   column is fixed and the image scales into it. */
/* Capped and centred: stretched across a wide screen the two gear columns drift
   to the far edges and the render is marooned in the middle of an empty card. */
.rosc-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,400px) minmax(0,1fr);
  gap:10px 26px;align-items:start;max-width:1040px;margin:0 auto;width:100%}
.rosc-col{display:flex;flex-direction:column;gap:11px;min-width:0}
.rosc-col.r{text-align:right}
.rosc-art{position:relative;display:flex;align-items:flex-start;justify-content:center;
  margin-top:-6px}
.rosc-art img{width:100%;height:auto;display:block;
  -webkit-mask-image:linear-gradient(180deg,#000 72%,transparent);
  mask-image:linear-gradient(180deg,#000 72%,transparent)}
/* An item is a Wowhead link, exactly as in the vault panel: with the script
   attached it gains the icon and the hover card, and without it the quality
   colour and the name still say what the thing is.
   
   The icon is injected INSIDE the link, as its first child, so the link itself
   has to be the flex row -- an earlier version reversed the row instead and the
   icons ended up wherever the text happened to leave them. */
.gi{display:flex;flex-direction:column;gap:1px;min-width:0}
.gi.r{text-align:right}
.gi-t{display:contents}
.gi a{text-decoration:none;border:0;min-width:0;display:flex;align-items:center;gap:9px}
.gi.r a{flex-direction:row-reverse}
.gi .iconsmall,.gi .icontiny,.gi .iconmedium,.gi .iconlarge{flex:none;width:26px;height:26px;
  display:block;position:relative;overflow:hidden;box-shadow:inset 0 0 0 1px var(--line)}
.gi .iconsmall ins,.gi .icontiny ins,.gi .iconmedium ins,.gi .iconlarge ins{display:block;
  width:100%;height:100%;background-size:cover;background-position:center}
.gi .iconsmall del,.gi .icontiny del,.gi .iconmedium del,.gi .iconlarge del{display:none}
.gi-n{font-size:12.5px;min-width:0}
.gi-n a{overflow:hidden}
.gi-n a > :last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gi-m{font-family:var(--mono);font-size:10px;color:var(--off);letter-spacing:.06em;
  padding-left:35px}
.gi.r .gi-m{padding-left:0;padding-right:35px}
.gi-m b{font-weight:400;color:var(--accent)}
.gi.empty .gi-n{color:var(--off)}
.rosc-reps{display:flex;flex-direction:column;gap:1px;padding-top:18px;
  border-top:1px solid var(--line2)}
.repg{border-bottom:1px solid var(--line2)}
.repg:last-child{border-bottom:0}
.repg summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;
  align-items:baseline;gap:14px;padding:9px 0;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim2)}
.repg summary::-webkit-details-marker{display:none}
.repg summary:hover{color:var(--accent)}
.repg[open] summary{color:var(--accent)}
.repg-n{color:var(--off)}
.repg-b{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  gap:10px 26px;padding:4px 0 16px}
@media (max-width:720px){
  .rosc-body{grid-template-columns:minmax(0,1fr)}
  .rosc-col.r{text-align:left}
  .rosc-art{order:-1;max-width:220px;margin:0 auto}
}
.rosc-h{display:flex;flex-direction:column;gap:3px;min-width:0}
.rosc-n{font-family:Cinzel,Georgia,serif;font-size:19px;letter-spacing:.02em;color:var(--cc,var(--fg))}
.rosc-m{font-size:11px;letter-spacing:.08em;color:var(--faint);font-family:var(--mono)}
.rosc-il{display:flex;align-items:baseline;gap:9px;margin-top:9px}
.rosc-il b{font-family:var(--mono);font-size:27px;font-weight:400;color:var(--accent);line-height:1}
.rosc-il span{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim2)}
.rosc-il.mp{margin-top:6px}
.rosc-il.mp b{font-size:21px}
.rep-r.untimed{color:var(--faint)}
.rep.run{grid-template-columns:minmax(0,1fr) auto}
.rosc-gear{display:flex;flex-wrap:wrap;gap:3px;margin-top:12px}
.gslot{font-family:var(--mono);font-size:10px;padding:2px 5px;border:1px solid var(--line);color:var(--dim2)}
.gslot b{font-weight:400;color:var(--fg)}
.gslot.low{border-color:color-mix(in oklab,var(--danger) 40%,transparent);color:var(--danger-fg)}
.rep{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 12px;align-items:baseline;
  cursor:help}
.rep.run{cursor:default}
.rep-n{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rep-r{font-family:var(--mono);font-size:11px;color:var(--accent)}
.rep-t{grid-column:1 / -1;height:2px;background:var(--line);position:relative}
.rep-t i{position:absolute;inset:0 auto 0 0;background:var(--accent);display:block}
.ros-more{background:none;border:0;padding:4px 0;font-family:var(--mono);
  font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim2);cursor:pointer}
.ros-more:hover{color:var(--accent)}
@media (max-width:720px){.rosc{grid-template-columns:minmax(0,1fr)}}
.chr span:first-child{color:var(--cc,inherit)}
.chr:hover span:first-child{color:var(--cc,var(--fg))}
.wk-who .chip{color:var(--cc,var(--off))}
.wk-who .chip:hover{color:var(--cc,var(--accent))}
.wk-who .chip[aria-pressed=true]{color:var(--cc,var(--accent))}
.hid{display:none !important}

/* ---- patch art -----------------------------------------------------------
   --key and --key2 come from the patch's index.md theme, so the isle a
   patch is set on colours its own pages. Gold stays gold: it means "reward".
   Everything below no-ops on a patch with no theme and no art. */
/* The stage has no picture in it: an aurora mesh in the patch's two colours,
   a fine diagonal weave for structure, and turbulence grain so nothing is a
   flat fill. All of it follows --key, so each patch gets its own sky. */
.stage{position:relative;overflow:hidden;margin-bottom:-1px;isolation:isolate;padding:24px 0 40px;
  background:
    repeating-linear-gradient(114deg,transparent 0 24px,color-mix(in oklab,var(--key) 8%,transparent) 24px 25px),
    radial-gradient(96% 86% at 6% 88%,color-mix(in oklab,var(--key) 46%,transparent),transparent 64%),
    radial-gradient(74% 82% at 72% 6%,color-mix(in oklab,var(--key2) 44%,transparent),transparent 66%),
    radial-gradient(52% 88% at 40% 102%,color-mix(in oklab,var(--accent) 20%,transparent),transparent 58%),
    radial-gradient(60% 70% at 92% 78%,color-mix(in oklab,var(--key) 26%,transparent),transparent 62%),
    linear-gradient(180deg,#0d121c 0%,#080a10 100%)}
.stage::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E")}

/* Nine arcs, one per vault slot; the ones you have earned burn gold. */
.vring{position:absolute;right:52px;top:50%;transform:translateY(-50%);
  width:148px;height:148px;z-index:1;pointer-events:none}
.vr-o{fill:none;stroke:color-mix(in oklab,var(--key) 20%,transparent);stroke-width:.7}
.vr-s{fill:none;stroke:color-mix(in oklab,var(--key) 30%,transparent);stroke-width:5.5;stroke-linecap:round;
  transition:stroke .3s}
.vr-s.on{stroke:color-mix(in oklab,var(--accent) 78%,transparent);
  filter:drop-shadow(0 0 6px color-mix(in oklab,var(--accent) 45%,transparent))}
.stage>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.stage .scrim{position:absolute;inset:0;background:
  linear-gradient(180deg,color-mix(in oklab,var(--bg) 58%,transparent) 0%,color-mix(in oklab,var(--bg) 6%,transparent) 30%,color-mix(in oklab,var(--bg) 52%,transparent) 66%,var(--bg) 100%),
  radial-gradient(90% 74% at 16% 82%,color-mix(in oklab,var(--bg) 80%,transparent),transparent 72%),
  radial-gradient(70% 90% at 86% 6%,color-mix(in oklab,var(--key) 12%,transparent),transparent 70%)}
.stage-in{position:relative;z-index:2}
.st{display:flex;align-items:flex-end;gap:30px;flex-wrap:wrap}
.st-l{display:flex;flex-direction:column;gap:6px;min-width:0}
.st-n{display:flex;align-items:flex-end;gap:14px}
.st-big{font-size:clamp(48px,6.4vw,72px);line-height:.86;font-weight:700;letter-spacing:-.045em;
  margin:2px 0 0;background:linear-gradient(172deg,#fff6e2 0%,#e9c883 46%,#b98f36 100%);
  -webkit-background-clip:text;background-clip:text;color:#e9c883;-webkit-text-fill-color:transparent}
.st-big i{font-style:normal;font-size:.44em;-webkit-text-fill-color:var(--dim2);color:var(--dim2)}
.st-cap{margin:0 0 9px;font-size:16.5px;color:var(--fg)}
.st-cap b{color:var(--accent);font-weight:600}
.st-c{display:flex;gap:8px;flex-wrap:wrap;padding-bottom:5px}
.st-chip{display:flex;align-items:baseline;gap:7px;border:1px solid color-mix(in oklab,var(--accent) 34%,transparent);
  background:color-mix(in oklab,var(--accent) 10%,transparent);padding:7px 12px;backdrop-filter:blur(6px)}
.st-chip .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim)}
.st-chip .v{font-family:var(--mono);font-size:14px;color:var(--accent)}
.st-chip.q{border-color:var(--line);background:color-mix(in oklab,var(--bg2) 72%,transparent)}
.st-chip.q .v{color:var(--fg)}
.stage .hdr-sub{font-family:var(--mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim)}
.has-stage .hdr{transition:background .18s,border-color .18s}
.has-stage .hdr.ontop{background:transparent;backdrop-filter:none;border-bottom-color:transparent}
.has-stage .main{padding-top:30px}

.orn{display:flex;align-items:center;gap:16px;margin:0 0 14px}
.orn span{flex:1 1 auto;height:1px}
.orn .l{background:linear-gradient(90deg,transparent,color-mix(in oklab,var(--key) 46%,transparent))}
.orn .r{background:linear-gradient(270deg,transparent,color-mix(in oklab,var(--key) 46%,transparent))}
.orn svg{flex:none;color:var(--key)}
/* A section on a content page: a Cinzel heading with a mono qualifier beside it,
   then a hairline. Same rhythm as the checklist's own section heads. */
.sec{display:flex;flex-direction:column;gap:18px}
.sec-h{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap;
  border-bottom:1px solid var(--line);padding-bottom:12px}
.sec-h h2{margin:0;font-size:26px}
.sec-h .mono{font-size:11px}
.sec-t{text-align:center;margin:0 0 3px;font-size:22px;font-weight:600;letter-spacing:-.02em}
.sec-s{text-align:center;margin:0 0 20px;color:var(--dim);font-size:14px}

/* A vault card with art behind it: the scrim, not the card, carries the dark. */
.vcard.art{position:relative;border:1px solid var(--line);padding:0;overflow:hidden;min-height:340px;
  justify-content:flex-end;background:var(--bg2);box-shadow:0 18px 40px -26px #000}
.vcard.art>picture{position:absolute;inset:0;z-index:0}
.vcard.art>picture>img{width:100%;height:100%;object-fit:cover;display:block}
.vcard.art::before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,
  color-mix(in oklab,var(--bg) 28%,transparent) 0%,color-mix(in oklab,var(--bg) 74%,transparent) 46%,
  color-mix(in oklab,var(--bg) 96%,transparent) 100%)}
.vcard.art.lit{border-color:color-mix(in oklab,var(--accent) 42%,var(--line));
  box-shadow:0 0 0 1px color-mix(in oklab,var(--accent) 10%,transparent),0 20px 44px -24px color-mix(in oklab,var(--accent) 30%,#000)}
.vcard.art>*{position:relative;z-index:2}
.vcard.art .vc-h{position:absolute;left:15px;right:15px;top:14px;z-index:2}
.vcard.art .vc-t{padding:0 15px}
.vcard.art .wk-ticks{padding:0 15px}
.vcard.art .vc-m{padding:0 15px}
.vcard.art .vc-r{margin:0 15px 13px;border-top-color:color-mix(in oklab,var(--fg) 14%,transparent)}
.vcard.art .wk-n,.vcard.art .wk-w{padding-left:15px;padding-right:15px}
.vcard.art .vc-slot{border-color:color-mix(in oklab,var(--fg) 26%,transparent);
  background:color-mix(in oklab,var(--bg) 55%,transparent)}
.vcard.art .vc-slot.on{background:var(--accent);border-color:var(--accent);
  box-shadow:0 0 10px color-mix(in oklab,var(--accent) 80%,transparent)}
@media(max-width:720px){.stage{padding:18px 0 30px}.orn{gap:10px}
  .set-row{grid-template-columns:minmax(0,1fr) auto 40px}.set-b{display:none}
  .vring{width:150px;height:150px;right:-34px;opacity:.75}}
