/* WoW Forever DB: twilight vellum.
   Night-blue vellum, antique gold rules, verdigris for "live", and each class's own color as --c.
   No inline styles anywhere (strict CSP): per-class and per-tree colors come from classes.css. */

@font-face {
  font-family: "Fell SC";
  src: url("/fonts/im-fell-english-sc-normal-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("/fonts/literata-normal-400-700.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("/fonts/literata-italic-400.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Barlow SC";
  src: url("/fonts/barlow-semi-condensed-normal-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Barlow SC";
  src: url("/fonts/barlow-semi-condensed-normal-600.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
/* Fallbacks scaled to each web font's width and line box, so the swap does not shift layout (SEO-M8,
   UX-P3-08). Generated by tools/font_fallbacks.py from the woff2 files; rerun it when a font changes. */
@font-face {
  font-family: "Literata Fallback";
  src: local("Times New Roman"), local("Liberation Serif"), local("Tinos");
  size-adjust: 118.65%;
  ascent-override: 99.20%;
  descent-override: 25.96%;
  line-gap-override: 0.00%;
}
@font-face {
  font-family: "Fell SC Fallback";
  src: local("Times New Roman"), local("Liberation Serif"), local("Tinos");
  size-adjust: 108.12%;
  ascent-override: 83.73%;
  descent-override: 33.60%;
  line-gap-override: 0.00%;
}
@font-face {
  font-family: "Barlow SC Fallback";
  src: local("Arial"), local("Liberation Sans"), local("Arimo");
  size-adjust: 88.66%;
  ascent-override: 112.79%;
  descent-override: 22.56%;
  line-gap-override: 0.00%;
}
@font-face {
  font-family: "Barlow SC Caps Fallback";
  src: local("Arial Bold"), local("Liberation Sans Bold"), local("Arimo Bold");
  font-weight: 500 700;
  size-adjust: 76.97%;
  ascent-override: 129.93%;
  descent-override: 25.99%;
  line-gap-override: 0.00%;
}

:root {
  /* Every color is light-dark(light, dark): color-scheme picks one, from the device unless the reader
     chose (data-theme, set by js/head-init.js before first paint). "Vellum by day", the night sky by night. */
  --ink-0: light-dark(#f5efe0, #0d0f17);
  /* A zone map pin's halo: a dark disc under the icon and a light ring round it, the same in both themes because
     the map art is. One of the two reaches 3:1 on any color; tools/pin_contrast.py checks it on every pin. */
  --halo-in: #1d1408;
  --halo-out: #f4e7c5;
  --ink-1: light-dark(#fbf7ee, #131726);
  --ink-2: light-dark(#f0e8d6, #1a1f31);
  --ink-3: light-dark(#e6dbc3, #242a40);
  --line: light-dark(#dccfb2, #2e3550);
  --line-2: light-dark(#c9b994, #3d4566); /* decorative rules only */
  --line-ui: light-dark(
    #8c7b57,
    #616a8d
  ); /* the edge of a control: 3:1 on ink-1 and ink-2 (WCAG 1.4.11) */
  /* The sticky masthead's height, measured at each of its layouts (tests/browser/test_css_a11y.py fails when
     one drifts): one row above 700 px, two rows at 700 px and under, tighter at 640 and at 480. Table heads
     stick below it, the theme popover opens under it, and anchored headings scroll clear of it. */
  --mast-h: 54px;
  --anchor-gap: 22px; /* air between the masthead and a heading a link scrolled to */
  /* Text: 4.5:1 on ink-0 to ink-2 in both themes (tests/test_contrast.py). */
  --text: light-dark(#221c12, #e8e2d3);
  --muted: light-dark(#5b5242, #aaa392);
  --faint: light-dark(#675d4a, #8d8879);
  --head: light-dark(#2b2112, #f4ead0);
  --strong: light-dark(#1c160d, #f6f0e1);
  --gold: light-dark(#7a5814, #d4b26a);
  --gold-2: light-dark(#6b4a0c, #f1d99a);
  --gold-dim: light-dark(#6f5829, #9d8555);
  --link-hover: light-dark(#3d2a05, #fff3cf);
  --pressed: light-dark(#1c160d, #fff7e2);
  --code: light-dark(#1d5146, #d8f0e9);
  --blue-text: light-dark(#1d58a5, #9cc5f2);
  /* The accents as text; as fills (below) they stay bright in both themes, under dark text. */
  --verd-ink: light-dark(#1d6b5c, #63b3a2);
  --sky-ink: light-dark(#2554a0, #79a5e6);
  --amber-ink: light-dark(#835400, #e0a646);
  --rose-ink: light-dark(#9e3450, #d9798f);
  --mast-bg: light-dark(rgb(245 239 224 / 0.92), rgb(13 15 23 / 0.92));
  --ic-edge: light-dark(#8c7b57, #000);
  /* Fills, the same in both themes, and the text on them. */
  --verd: #63b3a2;
  --sky: #79a5e6;
  --amber: #e0a646;
  --rose: #d9798f;
  --violet: #a68bdc;
  --ember: #d9674f;
  --gold-fill: #d4b26a;
  --muted-fill: #aaa392;
  --slate-fill: #8d93a8;
  --frost-fill: #b9c2d9;
  --on-fill: #0d0f17;
  --map-label: #fbf3dc; /* pin labels on the client's map, which is the same picture in both themes */
  --c: var(--gold);
  --t: var(--gold);
  --radius: 10px;
  --display: "Fell SC", "Fell SC Fallback", "Iowan Old Style", Georgia, serif;
  --body: "Literata", "Literata Fallback", Georgia, "Times New Roman", serif;
  --label: "Barlow SC", "Barlow SC Fallback", "Arial Narrow", system-ui, sans-serif;
  --label-caps:
    "Barlow SC", "Barlow SC Caps Fallback", "Arial Narrow", system-ui, sans-serif; /* uppercase labels */
  /* The uppercase label recipe's sizes and trackings, smallest first (S-052 C1). The values are the ones the
     labels had; snapping the odd sizes (--label-3 to --label-10) onto fewer steps is OD-2's open question. */
  --label-1: 0.62rem;
  --label-2: 0.72rem;
  --label-3: 0.74rem;
  --label-4: 0.76rem;
  --label-5: 0.78rem;
  --label-6: 0.8rem;
  --label-7: 0.82rem;
  --label-8: 0.84rem;
  --label-9: 0.85rem;
  --label-10: 0.86rem;
  --label-11: 0.9rem;
  --label-12: 0.95rem;
  --track-1: 0.05em;
  --track-2: 0.06em;
  --track-3: 0.08em;
  --track-4: 0.1em;
  --track-5: 0.12em;
  --track-6: 0.16em;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  color-scheme: light dark;
}
:root[data-theme="light"] {
  color-scheme: light;
}
:root[data-theme="dark"] {
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--mast-h) + var(--anchor-gap));
}
body {
  margin: 0;
  background: var(--ink-0);
  color: var(--text);
  font:
    1.0625rem / 1.62 var(--body); /* 17px at the browser's default size, and it follows a larger one */
  font-optical-sizing: auto;
  background-image:
    radial-gradient(1200px 600px at 85% -10%, rgb(99 179 162 / 0.07), transparent 60%),
    radial-gradient(900px 500px at -10% 10%, rgb(212 178 106 / 0.06), transparent 60%);
  background-attachment: fixed;
}
img {
  max-width: 100%;
}
a {
  color: var(--gold-2);
  text-decoration-color: color-mix(in srgb, var(--gold-2) 40%, transparent);
  text-underline-offset: 3px;
}
a:hover {
  color: var(--link-hover);
  text-decoration-color: currentColor;
}
:focus-visible {
  outline: 2px solid var(--gold-2);
  outline-offset: 2px;
  border-radius: 3px;
}
b,
strong {
  font-weight: 650;
  color: var(--strong);
}
h1,
h2,
h3,
h4 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.15;
  color: var(--head);
  margin: 0 0 0.5em;
  letter-spacing: 0.01em;
  text-wrap: balance; /* L-38 */
}
h1 {
  font-size: clamp(2.1rem, 5vw, 3.3rem);
}
h2 {
  font-size: 1.65rem;
  margin-top: 1.2em;
}
h3 {
  font-size: 1.28rem;
}
/* Section anchors (UX-P3-06, anchors.py): a heading's text links to itself; a # shows on hover and
   focus, and stays out of its accessible name where the browser supports alt text for content. */
.hl {
  color: inherit;
  text-decoration: none;
  display: inline-block;
  min-height: 24px;
} /* WCAG 2.5.8 on a short heading */
.hl:hover::after,
.hl:focus-visible::after {
  content: " #";
  /* biome-ignore lint/suspicious/noDuplicateProperties: a fallback for browsers without alt text */
  content: " #" / "";
  color: var(--gold-dim);
}
.hl-row {
  display: inline-block;
  min-width: 24px;
  margin-left: 2px;
  text-align: center;
  color: var(--gold-dim);
  text-decoration: none;
  visibility: hidden;
}
tr:hover .hl-row,
tr:focus-within .hl-row,
.hl-row:focus-visible {
  visibility: visible;
}
@media (hover: none) {
  .hl-row {
    visibility: visible;
  }
} /* a touch screen has no hover to reveal it */
h4 {
  font-size: 1.1rem;
}
p {
  margin: 0 0 0.9em;
  text-wrap: pretty; /* L-38: no one-word last lines in body text */
}
.skip {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 50;
  background: var(--gold);
  color: var(--ink-0);
  padding: 8px 14px;
  border-radius: 6px;
}
.skip:focus {
  top: 12px;
}
main:focus {
  outline: none;
}

/* masthead */
.mast {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--mast-bg);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 rgb(212 178 106 / 0.14);
}
.mast-in {
  max-width: 1180px;
  margin: 0 auto;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 16px;
  justify-content: space-between;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--gold-2);
  text-decoration: none;
  font: 1.35rem / 1 var(--display);
  letter-spacing: 0.03em;
}
.sigil {
  width: 26px;
  height: 26px;
  color: var(--gold);
}
.sigil circle {
  stroke: var(--ink-0);
}
.mast-nav {
  list-style: none;
  display: flex;
  gap: 4px;
  margin: 0;
  padding: 0;
}
.mast-nav a {
  white-space: nowrap;
  font: 600 var(--label-12) / 1 var(--label-caps);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  padding: 9px 12px;
  border-radius: 6px;
  display: block;
}
.mast-nav a:hover,
.mast-nav a[aria-current] {
  color: var(--gold-2);
  background: var(--ink-2);
}

.crumbbar {
  max-width: 1180px;
  margin: 0 auto;
  padding: 12px 16px 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
}
.crumbs {
  margin: 0;
  padding: 0;
}
.crumbs ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font: 500 0.86rem / 1.4 var(--label);
  letter-spacing: 0.04em;
  color: var(--faint);
}
.crumbs li + li::before {
  content: "›";
  margin-right: 6px;
  color: var(--gold-dim);
}
.crumbs a {
  color: var(--muted);
  text-decoration: none;
}
.crumbs a:hover {
  color: var(--gold-2);
}

/* hero */
.hero {
  max-width: 1180px;
  margin: 14px auto 0;
  padding: 0 16px;
}
.hero-in {
  position: relative;
  display: flex;
  gap: 22px;
  align-items: center;
  padding: 30px 28px 26px;
  border: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
  overflow: hidden;
  background:
    radial-gradient(
      520px 260px at 0% 0%,
      color-mix(in srgb, var(--c) 30%, transparent),
      transparent 70%
    ),
    linear-gradient(180deg, var(--ink-2), var(--ink-1));
}
.hero-home .hero-in,
.hero:not(:has(.tabs)) .hero-in {
  border-radius: var(--radius);
}
.hero-in::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--c), var(--gold) 40%, transparent);
}
.hero .ic-lg {
  border-radius: 12px;
  border: 2px solid var(--c);
  box-shadow:
    0 0 0 4px var(--ink-0),
    0 0 28px color-mix(in srgb, var(--c) 45%, transparent);
  flex: none;
}
.hero h1 {
  margin-bottom: 0.2em;
}
/* --c and --t darkened for a light page (S-052 C7). A custom property's var() resolves where it is declared, so
   each element that uses one declares it here rather than :root. */
.eyebrow,
.cc-head h2,
.cc-head h3 {
  --c-ink: color-mix(in oklab, var(--c) 50%, #000);
}
.role .eyebrow,
ol.prio li::before,
.tree-h {
  --t-ink: color-mix(in oklab, var(--t) 50%, #000);
}
.eyebrow {
  font: 600 var(--label-6) / 1.2 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-6);
  color: light-dark(var(--c-ink), var(--c));
  margin: 0 0 0.4em;
}
.hero-home .hero-in {
  padding: 46px 32px;
}
.hero-compact .hero-in {
  padding: 18px 24px 16px;
  gap: 16px;
}
.hero-compact .ic-lg {
  width: 48px;
  height: 48px;
  border-radius: 9px;
}
.hero-compact h1 {
  font-size: clamp(1.8rem, 4vw, 2.5rem);
  margin-bottom: 0.1em;
}
.hero-home h1 {
  font-size: clamp(2.6rem, 7vw, 4.4rem);
  color: var(--gold-2);
}

/* class tabs */
.tabs {
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--ink-1);
  overflow-x: auto;
  scrollbar-width: thin;
}
/* A row that scrolls fades at its right edge, so the reader sees there is more (UX-P2-10). */
.tabs.scrolls {
  mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
}
.tabs ul {
  list-style: none;
  display: flex;
  margin: 0;
  padding: 0 8px;
  min-width: max-content;
}
.tabs a {
  display: block;
  padding: 12px 13px 11px;
  font: 600 var(--label-11) / 1 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}
.tabs a:hover {
  color: var(--text);
}
.tabs a[aria-current] {
  color: var(--gold-2);
  border-bottom-color: var(--c);
}
/* Spec pages: their own tab row under the class tabs. */
.tabs:has(+ .subtabs) {
  border-radius: 0;
}
.subtabs {
  background: var(--ink-0);
}
.subtabs a {
  padding: 10px 13px 9px;
  font-size: 0.82rem;
}
.go-row {
  margin: 12px 0 0;
  font: 600 0.85rem / 1.6 var(--label);
  letter-spacing: 0.04em;
}
details.more > summary {
  cursor: pointer;
  list-style-position: inside;
}

/* body column */
.guide {
  max-width: 1180px;
  margin: 0 auto;
  padding: 8px 16px 40px;
}
.sec {
  margin-top: 26px;
}
.sec > h2:first-child {
  margin-top: 0;
}
.lede {
  font-size: 1.12rem;
}
.note {
  color: var(--muted);
  font-size: 0.95rem;
}
.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: 0 34px;
}
ul.tight,
ol.tight {
  margin: 0 0 1em;
  padding-left: 1.2em;
}
ul.tight li {
  margin: 0.32em 0;
}
ul.tight li::marker {
  color: var(--gold-dim);
}
details.how {
  margin: -0.4em 0 1em;
  color: var(--muted);
}
details.how summary {
  cursor: pointer;
  font: 600 var(--label-10) / 1.6 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--gold);
}
.more {
  font-size: 0.95rem;
}
.open-all {
  margin: 0 0 1em;
}
/* The spell filter's empty state (site.js): it keeps the space the tables left, so the footer does not jump up. */
.no-match {
  min-height: 12em;
  padding: 1em 0;
}
.no-match p {
  margin: 0 0 0.6em;
  font-size: 1.05rem;
}

/* icons and references */
.ic {
  vertical-align: -3px;
  border-radius: 4px;
  border: 1px solid var(--ic-edge);
  box-shadow: 0 0 0 1px var(--line-2);
  background: var(--ink-3);
}
.ic-xs {
  width: 18px;
  height: 18px;
}
.ic-sm {
  width: 28px;
  height: 28px;
  vertical-align: middle;
}
.ic-md {
  width: 40px;
  height: 40px;
}
.ic-lg {
  width: 56px;
  height: 56px;
}
.ic-none {
  display: inline-block;
}
.ref {
  white-space: nowrap;
  text-decoration: none;
}
/* A crosslink keeps its icon on its word's line (S-003 2.10). */
.ml,
.ent {
  white-space: nowrap;
}
:is(.ref, .ml, .ent) > .ic:first-child {
  margin-right: 4px;
}
a.ref b {
  color: var(--gold-2);
  border-bottom: 1px dotted color-mix(in srgb, var(--gold-2) 50%, transparent);
}
a.ref:hover b {
  border-bottom-style: solid;
}

/* chips */
.chip {
  display: inline-block;
  font: 600 var(--label-2) / 1 var(--label-caps);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  padding: 4px 7px 3px;
  border-radius: 99px;
  vertical-align: 2px;
  white-space: nowrap;
}
.cert {
  border: 1px solid currentColor;
  background: transparent;
}
.c-live {
  color: var(--verd-ink);
}
.c-announced {
  color: var(--sky-ink);
}
.c-unconfirmed {
  color: var(--amber-ink);
}
.c-rumored {
  color: var(--rose-ink);
}
.c-classic {
  color: var(--muted);
}
.c-untested {
  color: var(--amber-ink);
}
.c-tested {
  color: var(--verd-ink);
}
.chg {
  color: var(--on-fill);
  background: var(--muted-fill);
}
.g-new {
  background: var(--verd);
}
.g-changed {
  background: var(--gold-fill);
}
.g-reworded {
  background: var(--slate-fill);
}
.g-baseline {
  background: var(--violet);
}
.g-earlier {
  background: var(--sky);
}
.g-renamed {
  background: var(--amber);
}
.g-race {
  background: var(--rose);
}
.g-talent {
  background: var(--frost-fill);
}
.g-same {
  background: var(--ink-3);
  color: var(--muted);
}
.g-added {
  background: var(--verd);
}
.g-modified {
  background: var(--gold-fill);
}
.g-moved {
  background: var(--sky);
}
.legend-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1em;
  display: grid;
  gap: 8px;
}
.legend-list .chip {
  min-width: 108px;
  text-align: center;
  margin-right: 8px;
}
/* A PvP tab's leveling timeline (S-046): an ordered list drawn as a track, so it reads in order without CSS. */
.pvp-track {
  list-style: none;
  padding: 0 0 0 14px;
  border-left: 3px solid var(--line);
}
.pvp-track li {
  margin: 0 0 8px;
}
.pvp-track .lvl {
  display: inline-block;
  min-width: 5.5em;
  font-weight: 600;
}
/* /pvp/'s claims (S-046): each line led by its status chip, which wraps onto its own line on a phone. */
.claims {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 10px;
}
.claims .chip {
  margin-right: 6px;
}
/* A recipe's skill-up colors: always the word and the number, outlined in the color, never color alone (S-019). */
.sk {
  border: 1px solid currentColor;
  background: transparent;
}
.sk-orange {
  color: var(--amber-ink);
}
.sk-yellow {
  color: var(--gold-2);
}
.sk-green {
  color: var(--verd-ink);
}
.sk-gray {
  color: var(--muted);
}
.skills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
.role-tag {
  font: 500 0.8rem / 1 var(--label);
  letter-spacing: 0.04em;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 2px 5px;
  white-space: nowrap;
}

/* tables */
.tablewrap {
  position: relative;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-1);
}
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.96rem;
}
th,
td {
  text-align: left;
  vertical-align: top;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}
thead th {
  font: 600 var(--label-6) / 1.2 var(--label-caps);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--gold);
  background: var(--ink-2);
}
/* A scroll box can be scrolled from the keyboard (UX-P1-04); site.js drops the tab stop when it fits. */
.tablewrap:focus-visible,
.macro pre:focus-visible {
  outline: 2px solid var(--gold-2);
  outline-offset: 2px;
}
/* Column heads stay in view on wide screens. Only a table that fits (site.js marks it) can stick:
   a scroll box is the sticky element's scroll container, so the page scroll would not move it. */
/* bp: 900 */
@media (min-width: 900px) {
  .tablewrap.fits {
    overflow: visible;
  }
  .tablewrap.fits thead th {
    position: sticky;
    top: var(--mast-h);
    z-index: 1;
  }
}
tbody tr:last-child > * {
  border-bottom: 0;
}
tbody th {
  font-weight: 650;
  color: var(--strong);
}
tbody th small,
td small {
  display: block;
  font: 500 0.8rem / 1.3 var(--label);
  color: var(--faint);
  letter-spacing: 0.03em;
}
td p:last-child {
  margin-bottom: 0;
}
.pros-cons {
  table-layout: fixed;
}
.pros-cons th:first-child {
  color: var(--verd-ink);
}
.pros-cons td:first-child {
  border-right: 1px solid var(--line);
}
.num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ic-cell {
  width: 44px;
  padding-right: 0;
}
tr:target,
li:target {
  background: color-mix(in srgb, var(--gold) 14%, transparent);
}
/* Beyond the reader's level: quieter color, never faded text (UX-P1-05); the Level column says why. */
tr.later > * {
  color: var(--muted);
  background: var(--ink-0);
}
tr.later .ic {
  filter: grayscale(0.85);
}
table.spells .ranks {
  font: 500 0.84rem / 1.45 var(--label);
  color: var(--muted);
  letter-spacing: 0.02em;
}
table.spells .ranks b {
  color: var(--text);
  font-weight: 600;
}
.spell-tab h2 .n {
  font: 600 0.85rem / 1 var(--label);
  color: var(--faint);
  vertical-align: middle;
}
.jump {
  font: 500 0.95rem / 1.6 var(--label);
  letter-spacing: 0.03em;
}
.removed li {
  margin: 0.5em 0;
}

/* controls */
/* Script-only parts stay hidden until head-init.js sets .js. They show with the display their own rule gives
   them, so a component needs no exception, and `hidden` (below) still hides them (L-14). */
:root:not(.js) [data-js] {
  display: none;
}
[hidden] {
  display: none !important;
}
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin: 14px 0 18px;
}
.seg-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.seg-lbl,
.lvl > span,
.filters label > span,
.range-form label > span,
.pick > span {
  font: 600 var(--label-5) / 1 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-5);
  color: var(--muted);
}
.seg {
  display: inline-flex;
  flex-wrap: wrap;
  border: 1px solid var(--line-ui);
  border-radius: 8px;
  overflow: hidden;
}
.seg button {
  font: 600 0.9rem / 1 var(--label);
  letter-spacing: 0.03em;
  color: var(--muted);
  background: var(--ink-1);
  border: 0;
  border-right: 1px solid var(--line);
  padding: 9px 12px;
  cursor: pointer;
}
.seg button:last-child {
  border-right: 0;
}
.seg button[aria-pressed="true"] {
  background: color-mix(in srgb, var(--c) 30%, var(--ink-2));
  color: var(--pressed);
}
.lvl {
  display: flex;
  align-items: center;
  gap: 10px;
}
.lvl input {
  accent-color: var(--gold);
  width: 180px;
  height: 24px;
} /* WCAG 2.5.8 */
.lvl output {
  font: 600 1.05rem / 1 var(--label);
  color: var(--gold-2);
  min-width: 2ch;
}
.route-status {
  font: 500 0.86rem / 1.4 var(--label);
  color: var(--faint);
  margin: 0;
}
.filters,
.range-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 18px;
  align-items: end;
  margin: 14px 0 0;
}
.filters label,
.range-form label,
.pick {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
input[type="search"],
select,
.filters input[type="number"],
.range-form input[type="number"] {
  font: 500 0.98rem / 1.2 var(--label);
  color: var(--text);
  background: var(--ink-1);
  border: 1px solid var(--line-ui);
  border-radius: 7px;
  padding: 8px 10px;
}
input[type="search"],
select {
  min-width: 170px;
}
.shown {
  font: 500 0.9rem / 1 var(--label);
  color: var(--muted);
  padding-bottom: 10px;
}
/* L-03 (WP-2): filter controls have a fixed width, not the width of their longest option, so the web font
   arriving cannot re-wrap the row and shift the page below it (CLS 0.146 on six recipe pages). */
.filters select,
.filters input[type="search"] {
  box-sizing: border-box;
  width: 15rem;
  max-width: 100%;
}
.filters input[type="number"],
.range-form input[type="number"] {
  width: 7em;
}
/* A leveling page's range total (site.js) and its band totals. */
.range-total {
  flex: 1 1 100%;
  font: 500 0.95rem / 1.5 var(--label);
  color: var(--text);
}
.band-total {
  margin: 10px 0 0;
}
tr.gap td {
  color: var(--muted);
  font-style: italic;
}
/* The applied filters (site.js): each one a button that removes it. */
.active-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 10px 0 0;
}
.active-filters:empty {
  display: none;
}
.chip-x {
  font: 500 0.88rem / 1.2 var(--label);
  color: var(--text);
  background: var(--ink-2);
  border: 1px solid var(--gold-dim);
  border-radius: 99px;
  padding: 5px 12px;
  min-height: 30px;
  cursor: pointer;
} /* WCAG 2.5.8 */
.chip-x::after {
  content: " ×";
  color: var(--gold-2);
}
.chip-x:hover {
  border-color: var(--gold);
}
.chk {
  font: 500 0.95rem / 1 var(--label);
  color: var(--muted);
  display: flex;
  gap: 8px;
  align-items: center;
}
.chk input {
  width: 24px;
  height: 24px;
  margin: 0;
  accent-color: var(--gold);
} /* WCAG 2.5.8 */
.btn {
  display: inline-block;
  font: 600 var(--label-11) / 1 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--gold-2);
  background: var(--ink-2);
  border: 1px solid var(--gold-dim);
  border-radius: 7px;
  padding: 10px 14px;
  text-decoration: none;
  cursor: pointer;
}
.btn:hover {
  border-color: var(--gold);
  color: var(--link-hover);
}
.btn-gold {
  background: linear-gradient(180deg, #e7c57d, #b9934c);
  color: #1b1408;
  border-color: #f1d99a;
}
.btn-gold:hover {
  color: #000;
}

/* role cards and class cards */
.roles,
.class-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 16px;
  margin-top: 16px;
}
.role,
.cc {
  position: relative;
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  border-top: 3px solid var(--t);
}
.cc {
  border-top-color: var(--c);
}
.role-top {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 8px;
}
.role-top .ic {
  border-color: var(--t);
}
.role h3 {
  margin: 0;
}
.role h3 a {
  color: var(--head);
  text-decoration: none;
}
.role .eyebrow {
  color: light-dark(var(--t-ink), var(--t));
}
.go {
  font: 600 var(--label-10) / 1.3 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  text-decoration: none;
}
.go::after {
  content: " →";
}
.cc-head {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  margin-bottom: 8px;
}
.cc-head .ic {
  border-color: var(--c);
}
.cc-head h2,
.cc-head h3 {
  margin: 0;
  color: light-dark(var(--c-ink), color-mix(in srgb, var(--c) 74%, #fff));
  font-size: 1.6rem;
}
/* The whole card is its head link's target, through ::after (as .news-go); the links and tooltip
   buttons inside the card sit above that layer, so they still go where they say. */
.cc-head::after,
.role h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
}
.cc :is(a, button):not(.cc-head),
.role :is(a, button):not(h3 a) {
  position: relative;
  z-index: 1;
}
.cc-head:focus-visible,
.role h3 a:focus-visible {
  outline: none;
}
.cc-head:focus-visible::after,
.role h3 a:focus-visible::after {
  outline: 2px solid var(--gold-2);
  outline-offset: 2px;
}
.cc:hover,
.role:hover {
  border-color: var(--line-2);
}
.cc p {
  font-size: 0.95rem;
  color: var(--muted);
}
.cc-specs {
  list-style: none;
  padding: 0;
  margin: 0 0 10px;
  display: grid;
  gap: 4px;
}
.cc-specs a {
  font-weight: 600;
  text-decoration: none;
}
.cc-specs span {
  font: 500 0.82rem / 1 var(--label);
  color: var(--faint);
  margin-left: 4px;
}
.cc-meta {
  font: 600 var(--label-7) / 1.5 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  margin: 0;
}
.cc-meta a {
  text-decoration: none;
}
.updates time {
  font: 500 0.85rem / 1 var(--label);
  color: var(--faint);
  margin-left: 6px;
}

/* leveling bands */
.bands {
  display: grid;
  gap: 14px;
  margin-top: 10px;
}
.band {
  display: grid;
  grid-template-columns: 112px 1fr;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-1);
  overflow: hidden;
}
.band-lv {
  padding: 16px 12px;
  background: var(--ink-2);
  border-right: 1px solid var(--line);
  text-align: center;
}
.band-lv span {
  display: block;
  font: 1.6rem / 1 var(--display);
  color: var(--gold-2);
}
.band-lv small {
  display: block;
  margin-top: 6px;
  font: 600 var(--label-3) / 1.3 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-3);
  color: var(--muted);
}
.band-body {
  padding: 14px 18px 8px;
  min-width: 0;
}
.band-body h3 {
  margin-bottom: 0.35em;
}
.band dl {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 6px 14px;
  margin: 10px 0 8px;
}
.band dt {
  font: 600 var(--label-4) / 1.9 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-4);
  color: var(--gold);
  grid-column: 1;
}
.band dd {
  margin: 0;
  grid-column: 2;
}
.band dd p {
  margin: 0 0 0.3em;
}
.who {
  font: 600 0.9rem / 1 var(--label);
  color: var(--muted);
  letter-spacing: 0.03em;
}
.learn {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}
.learn a,
.learn span {
  text-decoration: none;
  white-space: nowrap;
}
.lv-n {
  font: 500 0.8rem / 1 var(--label);
  color: var(--faint);
}
.ranks span {
  font: 500 0.92rem / 1.5 var(--label);
  color: var(--muted);
}
.band.cur {
  border-color: var(--c);
  box-shadow:
    0 0 0 1px var(--c),
    0 0 26px color-mix(in srgb, var(--c) 25%, transparent);
}
.band.cur .band-lv {
  background: color-mix(in srgb, var(--c) 28%, var(--ink-2));
}
.band.cur .band-lv small {
  color: var(--text);
}
.band.past {
  border-color: var(--line);
  background: var(--ink-0);
  color: var(--muted);
}
.band.past .band-lv {
  background: var(--ink-1);
}
.band.past .band-lv span,
.band.past dt {
  color: var(--muted);
}
.band.past .ic {
  filter: grayscale(0.85);
}
.js [data-race].off,
.js [data-faction].off {
  display: none !important;
}
.fac {
  font: 600 var(--label-3) / 1 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-4);
  color: var(--muted);
  border: 1px solid var(--line-2);
  border-radius: 4px;
  padding: 3px 6px;
  margin-left: 8px;
  vertical-align: middle;
}
.callout {
  border-left: 3px solid var(--gold);
  background: var(--ink-2);
  padding: 14px 18px;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.callout p:last-child {
  margin: 0;
}

/* spec pages */
.toc ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0;
  margin: 12px 0 0;
}
.toc a {
  display: block;
  font: 600 var(--label-8) / 1 var(--label-caps);
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  text-decoration: none;
  padding: 8px 11px;
  border: 1px solid var(--line);
  border-radius: 99px;
  color: var(--muted);
}
.toc a:hover {
  color: var(--gold-2);
  border-color: var(--gold-dim);
}
ol.stats {
  counter-reset: s;
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 10px;
}
ol.stats li {
  counter-increment: s;
  background: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 12px 6px 8px;
}
ol.stats li::before {
  content: counter(s);
  font: 600 0.8rem / 1 var(--label);
  color: var(--on-fill);
  background: var(--t);
  border-radius: 99px;
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  margin-right: 8px;
  vertical-align: 1px;
}
.prio {
  list-style: none;
  padding: 0;
  margin: 0 0 1em;
  display: grid;
  gap: 6px;
  counter-reset: p;
}
.prio li {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 12px;
  align-items: start;
  padding: 9px 12px;
  background: var(--ink-1);
  border: 1px solid var(--line);
  border-radius: 8px;
}
ol.prio li {
  counter-increment: p;
  position: relative;
  padding-left: 40px;
}
ol.prio li::before {
  content: counter(p);
  position: absolute;
  left: 12px;
  top: 13px;
  font: 600 0.9rem / 1 var(--label);
  color: light-dark(var(--t-ink), var(--t));
}
.prio b a {
  text-decoration: none;
}
.when {
  color: var(--text);
}
.macro {
  margin: 0 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-1);
  overflow: hidden;
}
.macro figcaption {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--ink-2);
}
.macro pre {
  margin: 0;
  padding: 12px 14px;
  font: 0.9rem / 1.5 var(--mono);
  color: var(--code);
  overflow-x: auto;
  white-space: pre;
}
.macro p {
  padding: 0 14px 10px;
  margin: 0;
  color: var(--muted);
  font-size: 0.94rem;
}
.macro-meta {
  display: flex;
  align-items: center;
  gap: 10px;
}
.macro-about {
  margin: -8px 0 18px;
  padding: 0 2px;
  color: var(--muted);
  font-size: 0.94rem;
}
.macro-about p {
  margin: 0 0 4px;
}

/* talents */
.trees {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 16px;
  margin-top: 12px;
}
.tree {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(
      260px 180px at 50% 0%,
      color-mix(in srgb, var(--t) 20%, transparent),
      transparent 70%
    ),
    var(--ink-1);
  padding: 12px;
}
.tree-h {
  font-size: 1.28rem;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0 4px 10px;
  color: light-dark(var(--t-ink), color-mix(in srgb, var(--t) 76%, #fff));
}
.tree-n {
  font: 600 1.1rem / 1 var(--label);
  color: var(--gold-2);
}
.tree-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(7, 60px);
  gap: 0;
  place-items: center;
  position: relative;
}
/* The prerequisite lines: an SVG under the grid, in the same 4 x 7 box (talents.py req_lines). */
.tree-body {
  position: relative;
}
.req-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.req-lines path {
  fill: none;
  stroke: var(--line);
  stroke-width: 3;
  stroke-linejoin: round;
}
.req-lines path.on {
  stroke: var(--gold);
}
.tal {
  position: relative;
  width: 48px;
  height: 48px;
}
/* An unlearned talent is grayed out, and its 0/5 rank badge says the same in text: keep the badge through
   any restyle, since it is what makes this pass WCAG 1.4.1 (color is not the only cue; UX-P3-07). */
.tal .ic {
  width: 48px;
  height: 48px;
  border-radius: 7px;
  filter: grayscale(1) brightness(0.55);
}
.tal.is-some .ic,
.tal.is-full .ic {
  filter: none;
}
.tal.is-some .ic {
  box-shadow: 0 0 0 2px var(--verd);
}
.tal.is-full .ic {
  box-shadow: 0 0 0 2px var(--gold);
}
.tal-pts {
  position: absolute;
  right: -6px;
  bottom: -6px;
  font: 600 0.72rem / 1 var(--label);
  background: var(--ink-0);
  color: var(--muted);
  border: 1px solid var(--line-2);
  border-radius: 5px;
  padding: 2px 4px;
}
.tal.is-some .tal-pts {
  color: var(--verd-ink);
  border-color: var(--verd-ink);
}
.tal.is-full .tal-pts {
  color: var(--gold-2);
  border-color: var(--gold);
}
.tal-card {
  display: none;
  position: absolute;
  z-index: 10;
  top: 56px;
  left: 50%;
  transform: translateX(-50%);
  width: min(300px, calc(100vw - 32px));
}
.tal:hover .tal-card,
.tal:focus-within .tal-card {
  display: block;
} /* a #t- link focuses it (js/talents.js) */
.tal[data-dismissed] .tal-card {
  display: none;
} /* Esc (js/talents.js), until focus or the pointer leaves */
.tal-btn {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
}
/* A tooltip as the game client draws one: dark navy, a thin silver frame, white header lines,
   the description in the client's yellow. */
/* The client's own dark card in both themes (D-112): color-scheme keeps light-dark() on its dark side. */
.wtt {
  /* The client's palette, named once (S-052 C7); every card that uses it is a .wtt. */
  --wtt-white: #fff;
  --wtt-gold: #ffd100; /* the description yellow */
  --wtt-gray: #9d9d9d;
  --wtt-frame: #a7a7b4;
  --wtt-shade: #1b1b2a;
  color-scheme: dark;
  background: rgb(8 8 24 / 0.96);
  border: 1px solid var(--wtt-frame);
  border-radius: 4px;
  padding: 7px 10px 8px;
  box-shadow:
    0 0 0 1px var(--wtt-shade),
    0 10px 30px rgb(0 0 0 / 0.6);
  font:
    400 0.86rem / 1.32 Arial,
    "Helvetica Neue",
    sans-serif;
  color: var(--wtt-white);
  text-align: left;
  white-space: normal;
}
.wtt p {
  margin: 0;
}
.wtt-row {
  display: flex;
  justify-content: space-between;
  gap: 14px;
}
.wtt-row span:last-child {
  text-align: right;
}
.wtt-h {
  margin-bottom: 1px;
}
.wtt-h b {
  font-size: 1rem;
  font-weight: 400;
  color: var(--wtt-white);
}
.wtt-h span {
  color: var(--wtt-gray);
}
.wtt-req {
  color: var(--wtt-white);
}
.wtt-desc {
  color: var(--wtt-gold);
  margin-top: 2px !important;
}
/* The client's red and green also color description cells on the page, so they darken on a light one. */
.wtt .tt-red,
.desc .tt-red {
  color: light-dark(#b0000c, #ff2020);
}
.wtt .tt-green,
.desc .tt-green {
  color: light-dark(#146a17, #20ff20);
}
.wtt .tt-white {
  color: var(--wtt-white);
}
.wtt .tt-gray {
  color: #808080;
}
.wtt .tt-blue {
  color: #71d5ff;
}
.wtt-item p {
  color: var(--wtt-white);
}
.wtt-item p.tt-green {
  color: #20ff20;
}
.wtt-item p.tt-gold {
  color: var(--wtt-gold);
}
.wtt-h b.tt-q0 {
  color: var(--wtt-gray);
}
.wtt-h b.tt-q2 {
  color: #1eff00;
}
.wtt-h b.tt-q3 {
  color: #4c9bff;
}
.wtt-h b.tt-q4 {
  color: #b764f7;
}
.wtt-h b.tt-q5 {
  color: #ff8000;
} /* the client's quality colors; rare and epic lightened to 4.5:1 */
.wtt-line {
  margin-top: 3px !important;
  max-width: 30ch;
}
.wtt-meta {
  color: var(--wtt-gray);
  font-size: 0.8rem;
  margin-top: 6px !important;
}
.wtt-ours {
  border-top: 1px solid #3a3a52;
  margin-top: 7px;
  padding-top: 6px;
  color: var(--text);
  font: 0.86rem / 1.42 var(--body);
}
.wtt-ours .ref b {
  color: var(--gold-2);
}
#wtt-pop {
  position: fixed;
  z-index: 60;
  width: max-content;
  max-width: min(320px, calc(100vw - 16px));
} /* hoverable (WCAG 1.4.13) */
#wtt-pop[hidden] {
  display: none;
}
/* Map coordinates: a /way card with a copy button (js/tooltip.js). */
button.way {
  cursor: copy;
  border-bottom: 1px dotted color-mix(in srgb, var(--gold-2) 40%, transparent);
}
.wtt-way {
  display: grid;
  gap: 6px;
  justify-items: start;
}
.wtt-way-name {
  font-weight: 700;
  color: var(--wtt-white);
}
.wtt-way code {
  font: 0.86rem / 1.3 var(--mono);
  color: var(--wtt-gold);
  user-select: all;
}
.way-copy {
  font: 600 0.8rem / 1 var(--label);
  padding: 5px 10px;
  border: 1px solid var(--wtt-frame);
  border-radius: 3px;
  background: var(--wtt-shade);
  color: var(--wtt-white);
  cursor: pointer;
}
.way-copy:hover,
.way-copy:focus-visible {
  background: #2a2a40;
}
/* Tooltip triggers that are not links are buttons (UX-P1-03, markup.tt_button); they look like the text they were. */
button.tt,
.tal-btn {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  border-radius: 0;
}
button.tt {
  display: inline;
  cursor: help;
}
.tt-name.tt {
  border-bottom: 1px dotted color-mix(in srgb, var(--gold-2) 40%, transparent);
}
td .desc {
  color: var(--text);
  margin: 0;
}
td .desc + .wtk {
  margin-top: 6px;
  color: var(--muted);
  font-size: 0.92em;
}
.wtk b {
  font: 600 0.82rem / 1 var(--label);
  letter-spacing: 0.04em;
  color: var(--gold);
}
.c0 {
  grid-column: 1;
}
.c1 {
  grid-column: 2;
}
.c2 {
  grid-column: 3;
}
.c3 {
  grid-column: 4;
}
.r0 {
  grid-row: 1;
}
.r1 {
  grid-row: 2;
}
.r2 {
  grid-row: 3;
}
.r3 {
  grid-row: 4;
}
.r4 {
  grid-row: 5;
}
.r5 {
  grid-row: 6;
}
.r6 {
  grid-row: 7;
}
.c2 .tal-card,
.c3 .tal-card {
  left: auto;
  right: -8px;
  transform: none;
}
.c0 .tal-card {
  left: -8px;
  transform: none;
}
.spent {
  font: 600 0.95rem / 1 var(--label);
  color: var(--muted);
  margin: 0;
}
.spent span {
  color: var(--gold-2);
}

/* Legacy (S-030): the talents tree drawing on a 3 x 4 grid, one color per tree. */
.lg-grid {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(4, 60px);
}
.lg-trees .tr0 {
  --t: var(--amber);
}
.lg-trees .tr1 {
  --t: var(--verd);
}
.lg-trees .tr2 {
  --t: var(--sky);
}
.perks dt {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  font: 600 1.05rem / 1.3 var(--label);
  scroll-margin-top: var(--anchor-gap);
}
.perks dt .note {
  font-weight: 400;
}
.perks dd {
  margin: 4px 0 0 32px;
}
.perks dd p {
  margin: 0 0 6px;
}
/* A rank's value sits under its number: both centered, the row's label left as every row head is. */
table.ranks td,
table.ranks thead th:not(:first-child) {
  text-align: center;
}
/* The planner (S-031): a perk whose gate is not met is dimmer still, and its card says what it needs; the
   card's own Add and Take back buttons are the phone's way in (no long-press). */
.tal.is-locked .ic {
  filter: grayscale(1) brightness(0.35);
}
.lg-act {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.lg-act fieldset {
  flex-basis: 100%;
  margin: 0;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.lg-act label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-right: 12px;
}
.lg-msg {
  min-height: 1.5em;
  margin: 0;
  color: var(--gold-2);
}
.lg-tick {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.js .static-note {
  display: none;
}
.builds {
  display: grid;
  gap: 12px;
}
.build {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-1);
  padding: 14px 16px;
}
.build:target {
  border-color: var(--gold);
}
.build h3 {
  font-size: 1.15rem;
}
.split {
  font: 600 0.9rem / 1 var(--label);
  color: var(--gold-2);
  margin-left: 4px;
}
.bt {
  margin: 0.2em 0;
  font-size: 0.94rem;
}

/* pager and footer */
.pager {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 40px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.pager a {
  font: 1.15rem / 1.2 var(--display);
  text-decoration: none;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.pager a small {
  display: block;
  font: 600 var(--label-2) / 1.4 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-5);
  color: var(--muted);
}
.pager .next {
  text-align: right;
  margin-left: auto;
}
/* The one 32 px icon button (L-17): the theme and search buttons in the masthead, the share row, the launch
   banner's close. 32 px clears WCAG 2.5.8's 24 px minimum. Each adds only what differs. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line-ui);
  border-radius: 8px;
  cursor: pointer;
  text-decoration: none;
}
.icon-btn:hover {
  color: var(--gold-2);
}
/* Share (S-013): small round marks on the breadcrumb line, at its right; under the crumbs on a narrow
   screen. 32 px targets, above WCAG 2.5.8's 24 px minimum. */
.share {
  margin-left: auto;
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
}
.share-lbl {
  font: 600 var(--label-2) / 1 var(--label-caps);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.share-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
.share-btn,
.share-net {
  border-color: var(--line);
  border-radius: 50%;
  background: var(--ink-1);
}
.share-btn:hover,
.share-net:hover {
  border-color: var(--gold);
  color: var(--gold-2);
}
.share-said {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  font: 500 0.8rem / 1.2 var(--label);
  color: var(--muted);
  white-space: nowrap;
}
/* bp: 420 */
@media (max-width: 420px) {
  .share-lbl {
    display: none;
  }
}
.foot {
  border-top: 1px solid var(--line);
  background: var(--ink-1);
  margin-top: 30px;
}
.foot-in {
  max-width: 1180px;
  margin: 0 auto;
  padding: 24px 16px 34px;
  font-size: 0.9rem;
  color: var(--muted);
}
.foot .legal {
  font-size: 0.8rem;
  margin: 0.5em 0 0;
}
.foot .build {
  font: 500 0.75rem / 1.3 var(--label);
  letter-spacing: 0.04em;
  margin: 0.5em 0 0;
}

/* bp: 640 */
@media (max-width: 640px) {
  body {
    font-size: 1rem;
  }
  .hero-in {
    flex-direction: column;
    align-items: flex-start;
    padding: 22px 18px;
    gap: 14px;
  }
  .band {
    grid-template-columns: 1fr;
  }
  .band-lv {
    border-right: 0;
    border-bottom: 1px solid var(--line);
    text-align: left;
    display: flex;
    gap: 12px;
    align-items: baseline;
    padding: 10px 14px;
  }
  .band-lv small {
    margin: 0;
  }
  .band dl {
    grid-template-columns: 1fr;
  }
  .band dt,
  .band dd {
    grid-column: 1;
  }
  .tal,
  .tal .ic {
    width: 40px;
    height: 40px;
  }
  .tree-grid {
    grid-template-rows: repeat(7, 52px);
  }
  .lvl input {
    width: 140px;
  }
  .mast-nav a {
    padding: 8px;
  }
  /* A talent card offset from a 48 px icon cannot fit beside it on a phone (UX-P1-07): it opens as
     a sheet along the bottom of the screen instead, the same for every column. */
  .tal-card,
  .c0 .tal-card,
  .c2 .tal-card,
  .c3 .tal-card {
    position: fixed;
    top: auto;
    bottom: 16px;
    left: 16px;
    right: 16px;
    width: auto;
    transform: none;
    max-height: 60vh;
    overflow-y: auto;
  }
}
/* Ads (S-021, plan §5.3–§5.7). A frame is the page surface with a 3:1 control edge and a label: never
   a card, callout or chip, so it is plainly not ours. Every unit has a fixed size per breakpoint, so its
   space is reserved before the ad arrives and nothing moves when it does. Its own stacking context keeps
   every ad iframe under the tooltip card and the theme popover; the masthead stays above the rail. */
.ad {
  position: relative;
  z-index: 0;
  margin: 28px 0;
  padding: 10px 12px 12px;
  border: 1px solid var(--line-ui);
  border-radius: var(--radius);
  background: var(--ink-0);
  text-align: center;
}
.ad-lbl {
  margin: 0 0 8px;
  font: 600 var(--label-3) / 1 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-5);
  color: var(--muted);
}
.ad-unit {
  display: block;
  margin: 0 auto;
  width: 300px;
  height: 250px;
}
/* The end unit stands apart from the last section, above the pager. */
.ad-end {
  margin-top: 40px;
}
/* The rail lives only in the gutter beside the centered 1180 px column: a 16 px gap, the 302 px frame and
   12 px to spare on each side make 1840 px, so a 1920 px desktop gets it and the column never narrows. */
.ad-rail {
  display: none;
}
/* The top unit, just after the lede, is the wide screen's first ad, above the fold on a desktop. Below 900 px
   it never shows, so the phone's first screen stays the title, tabs and first glance rows, and the first
   in-content unit (.ad-narrow) shows in its place. Never displayed, never requested (js/ads.js). */
.ad-top {
  display: none;
}
/* bp: 900 */
@media (min-width: 900px) {
  .ad-top {
    display: block;
  }
  .ad-narrow {
    display: none;
  }
  .ad-unit {
    width: 728px;
    height: 90px;
  }
}
/* Below 400 px a 300 px unit and the column's padding do not fit: the frame runs to the screen's edges
   (no side borders), so it never makes the page scroll sideways (WCAG 1.4.10). */
/* bp: 400 */
@media (max-width: 399.98px) {
  .ad {
    margin-inline: -16px;
    border-inline: 0;
    border-radius: 0;
    padding-inline: 0;
  }
}
/* bp: 400, 900 */
@media (min-width: 400px) and (max-width: 899.98px) {
  .ad-unit {
    width: 336px;
    height: 280px;
  }
}
/* bp: 1840 */
@media (min-width: 1840px) and (min-height: 760px) {
  .ad-rail {
    display: block;
    position: fixed;
    z-index: 1;
    top: calc(var(--mast-h) + 24px);
    left: calc(50% + 606px);
    width: 302px;
    margin: 0;
    padding-inline: 0;
  }
  .ad-rail .ad-unit {
    width: 300px;
    height: 600px;
  }
}
@media (prefers-reduced-motion: reduce) {
  * {
    scroll-behavior: auto !important;
    transition: none !important;
  }
}
/* Print (UX-P2-01): the light theme, on white; the
   page's shell is left off; closed sections print open; a link in prose prints where it goes (its
   path: the browser prints the page's own address, which gives the site). */
@media print {
  /* A tier list prints every entry, without the step controls (tierlist.js). */
  .tl-entry[hidden] {
    display: block !important;
  }
  .tl-nav,
  .tl-prompt,
  .tl-back {
    display: none !important;
  }
  :root,
  :root[data-theme] {
    color-scheme: light;
  }
  .mast,
  .tabs,
  .controls,
  .filters,
  .range-form,
  .pager,
  .toc,
  .launch,
  .skip,
  .foot,
  .share,
  .crumbs,
  .jump,
  details.legend,
  .open-all,
  .ad,
  :root.js [data-js],
  .map-layers-d,
  .pin-card {
    display: none !important;
  }
  /* The zone map at full width, unzoomed, its pins numbered to the key below it (S-022 22.4). */
  .zone-art:has(.map-layers) {
    display: block;
  }
  .zone-map,
  .pin-b {
    transform: none !important;
  }
  .pin .pin-n {
    display: inline;
    visibility: visible;
    fill: #000;
    stroke: #fff;
  }
  .print-only {
    display: block;
  }
  .map-print-key {
    columns: 2;
    font-size: 0.85rem;
  }
  body,
  .hero,
  .hero-in,
  .cc,
  .news-item,
  .band,
  .tablewrap {
    background: #fff !important;
    color: #000;
    box-shadow: none !important;
    text-shadow: none !important;
  }
  h1,
  h2,
  h3,
  h4,
  b,
  strong,
  th,
  a {
    color: #000 !important;
  }
  .tablewrap {
    overflow: visible;
  }
  thead th {
    position: static;
  }
  details::details-content {
    content-visibility: visible;
    display: contents;
  }
  details > summary {
    list-style: none;
  }
  .chip {
    background: none !important;
    color: #000 !important;
    border: 1px solid #666;
  }
  .crumbs a,
  .cc-head a,
  .cc-specs a,
  .go,
  .launch-src,
  a.ml,
  th a,
  td a,
  .jump a {
    display: inline;
    min-height: 0;
  }
  main :is(p, li, dd):not(td *, th *) > a[href^="/"]:not(.ref)::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #333;
  }
  h2,
  h3 {
    break-after: avoid;
  }
  tr,
  figure,
  .macro,
  .cc {
    break-inside: avoid;
  }
}

/* Launch countdown, atop every page (templates/layout.html, js/time.js). */
.launch {
  background: linear-gradient(90deg, var(--ink-1), var(--ink-3) 50%, var(--ink-1));
  border-bottom: 1px solid var(--gold-dim);
}
.launch-in {
  max-width: 1180px;
  margin: 0 auto;
  padding: 8px 16px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 20px;
  text-align: center;
}
.launch-head {
  margin: 0;
  font: 600 var(--label-12) / 1.3 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--gold-2);
}
.launch-head time {
  color: var(--text);
  text-transform: none;
  letter-spacing: 0;
}
.launch-clock {
  margin: 0;
  display: flex;
  gap: 6px;
}
.launch-unit {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  min-width: 46px;
  padding: 3px 6px;
  background: var(--ink-0);
  border: 1px solid var(--line-2);
  border-radius: 6px;
}
.launch-unit b {
  font: 700 1.15rem / 1.1 var(--label);
  color: var(--gold-2);
  font-variant-numeric: tabular-nums;
}
.launch-unit small {
  font: 600 var(--label-1) / 1.2 var(--label-caps);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  color: var(--muted);
}
.launch-src {
  font: 600 var(--label-6) / 1 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  padding: 8px 4px;
}
.launch-x {
  font: 400 1.4rem / 1 var(--label);
  border-color: transparent;
  border-radius: 6px;
}
.launch-x:hover {
  color: var(--text);
  border-color: var(--line-2);
}
.launch-off .launch {
  display: none;
}
.launch.is-live .launch-head {
  color: var(--gold);
}

/* Races (site/races.py). */
.race-icons {
  display: flex;
  gap: 4px;
  margin: 6px 0;
}
.race-card .cc-head h3 {
  margin: 0;
}
.fac-alliance {
  --c: #6f9fe0;
}
.fac-horde {
  --c: #d0574a;
}
.prof-crafting {
  --c: #c98b4f;
}
.prof-gathering {
  --c: #7cb36a;
}
.prof-secondary {
  --c: #8fa9c4;
}
.race-card {
  border-top: 3px solid var(--c);
}
.race-matrix td {
  text-align: center;
}
.race-matrix td.yes {
  color: var(--gold-2);
  font-weight: 700;
}
.race-matrix td.no {
  color: var(--faint);
}
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.racials th[scope="row"] {
  white-space: nowrap;
  vertical-align: top;
}
.racials td {
  vertical-align: top;
}
.racials .note {
  margin: 4px 0 0;
}
.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 14px;
  margin: 0 0 12px;
}
.facts dt {
  color: var(--muted);
  font: 600 var(--label-9) / 1.6 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
}
.facts dd {
  margin: 0;
}

/* Narrow phones: the brand and four nav entries need about 380 px, so the nav takes a row of its
   own under the brand (UX-P0-01), its links spread across it at a 32 px touch height. */
/* bp: 480 */
@media (max-width: 480px) {
  .mast-in {
    gap: 4px 8px;
    padding: 8px 12px;
    flex-wrap: wrap;
  }
  .brand span {
    font-size: 1rem;
    white-space: nowrap;
  }
  .mast-nav {
    gap: 0;
    flex: 1 0 100%;
    justify-content: space-between;
  }
  .mast-nav a {
    padding: 0 6px;
    min-height: 32px;
    display: flex;
    align-items: center;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
  }
}

/* News: Blizzard's posts in our own words, each linking to the original */
.news-list {
  display: grid;
  gap: 14px;
}
/* A card: a title of up to two lines and a summary of two, the whole of it a link to the topic page. */
.news-item {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 16px;
  align-items: center;
  background: var(--ink-1);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold-dim);
  border-radius: 8px;
  padding: 12px 16px;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.news-item.kind-blue {
  border-left-color: #4f8fd6;
}
.news-item.kind-log {
  border-left-color: var(--line-2);
}
.news-item:hover,
.news-item:focus-within {
  background: var(--ink-2);
  border-color: var(--line-2);
}
.news-body {
  min-width: 0;
  grid-column: -2;
}
/* The title wraps to two lines at most (UX-P2-09); the whole card is its target, through ::after. */
.news-item h3 {
  margin: 2px 0 4px;
  font-size: 1.05rem;
  line-height: 1.4;
}
.news-item h3 .news-go {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  min-height: 24px;
}
.news-go {
  text-decoration: none;
}
.news-go::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 8px;
}
.news-go:focus-visible {
  outline: none;
}
.news-go:focus-visible::after {
  outline: 2px solid var(--gold-2);
  outline-offset: 2px;
}
.news-meta {
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.news-sum {
  margin: 0;
  min-height: 3.2em;
  max-height: 3.2em;
  line-height: 1.6;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.kind-blue .chip {
  color: var(--blue-text);
  border-color: #4f8fd6;
}
.news-more {
  margin: 4px 0 24px;
}
.news-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 160px;
}
.news-thumb.thumb-avatar {
  width: 64px;
}
.news-thumb img,
.news-hero-thumb img {
  display: block;
  border: 1px solid var(--line);
}
.thumb-image img {
  width: 160px;
  height: 90px;
  border-radius: 6px;
  object-fit: cover;
}
.thumb-avatar img {
  width: 56px;
  height: 56px;
  border-radius: 50%;
}
.thumb-by {
  max-width: 100%;
  margin-top: 4px;
  color: var(--blue-text);
  font: 600 0.72rem / 1.2 var(--label);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The status log: one entry per notice, each an anchor its old address redirects to */
.status-log {
  list-style: none;
  margin: 0;
  padding: 0;
}
.status-log li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 16px;
  align-items: start;
  padding: 12px 0;
  border-top: 1px solid var(--line);
  scroll-margin-top: 80px;
}
.status-body {
  min-width: 0;
  grid-column: -2;
}
.status-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.status-src {
  flex: none;
  font-size: 0.85rem;
}
.status-log li:first-child {
  border-top: 0;
}
.status-log h2 {
  margin: 4px 0;
  font-size: 1.05rem;
}
.status-log p {
  margin: 0;
}
.status-log li:target {
  background: var(--ink-2);
}
/* The topic page */
.news-topic .hero-in {
  display: flex;
  gap: 24px;
  align-items: center;
  justify-content: space-between;
}
.news-hero-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: none;
}
.news-hero-thumb.thumb-image img {
  width: 320px;
  height: 180px;
}
.news-hero-thumb.thumb-avatar img {
  width: 96px;
  height: 96px;
}
/* Blizzard's video player: the frame's width, 16:9, so a phone never scrolls sideways */
.news-video {
  margin: 0 0 24px;
}
.video-frame {
  aspect-ratio: 16 / 9;
  max-width: 100%;
}
.video-frame iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.news-video figcaption {
  margin-top: 6px;
  font-size: 0.9rem;
}
.news-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 24px;
}
/* The full write-up (S-015): change tables and the source of each part */
.news-build h3,
.news-topic .sec h3 {
  margin: 18px 0 6px;
  font-size: 1rem;
}
.news-changes th[scope="row"] {
  white-space: nowrap;
}
.delta {
  font: 600 var(--label-2) / 1.4 var(--label-caps);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  white-space: nowrap;
}
.delta-new,
.delta-buff,
.delta-fix {
  color: var(--verd-ink);
}
.delta-nerf,
.delta-removed {
  color: var(--rose-ink);
}
.delta-change {
  color: var(--amber-ink);
}
.said {
  color: var(--muted);
  font-size: 0.9em;
}
.news-topic .src {
  color: var(--muted);
  font-size: 0.9rem;
}
/* Summary's heading row: Blizzard's post, linked once, at the right */
.sec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
}
.sec-head h2 {
  margin: 0;
}
.src-link {
  font-size: 0.95rem;
}
.news-issues small {
  color: var(--muted);
}
.news-step {
  display: block;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  text-decoration: none;
}
.news-step small {
  display: block;
  color: var(--muted);
  font: 600 var(--label-2) / 1.4 var(--label-caps);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
}
/* bp: 560 */
@media (max-width: 560px) {
  .news-thumb {
    width: 96px;
  }
  .news-thumb.thumb-avatar {
    width: 52px;
  }
  .thumb-image img {
    width: 96px;
    height: 54px;
  }
  .thumb-avatar img {
    width: 40px;
    height: 40px;
  }
  .news-topic .hero-in {
    flex-direction: column;
    align-items: flex-start;
  }
  .news-hero-thumb.thumb-image img {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }
}

/* WCAG 2.2 SC 2.5.8: every target is at least 24 px tall, except a link inside a sentence (UX-P2-10).
   These are the links that stand alone: crumbs, card heads and spec lists, table cells, class lists. Every
   crumb sits on that line too, the current page as well. */
.crumbs li,
.crumbs a,
.cc-head a,
.cc-specs a,
.go,
.launch-src,
a.ml,
th a,
td a,
.jump a,
.news-step {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}
summary {
  min-height: 24px;
}

/* The theme choice (templates/layout.html, js/head-init.js): a button in the masthead opens it as a
   popover; the footer shows it inline. */
.mast-in > nav {
  margin-left: auto;
}
.theme-pop {
  margin: 0;
  inset: auto;
  top: calc(var(--mast-h) + 4px);
  right: 16px;
  padding: 12px 14px;
  background: var(--ink-1);
  color: var(--text);
  border: 1px solid var(--line-ui);
  border-radius: var(--radius);
}
.theme-pop::backdrop {
  background: transparent;
}
.foot .theme-pick {
  margin: 1em 0 0;
}

/* Search (S-007): Pagefind's Component UI resets its elements with `all: initial`, so it is themed only
   through its --pf-* variables, set here from ours so both themes follow. Its own icons are data: URIs,
   which the CSP's img-src 'self' blocks: ours is served from /img/. */
.search-ui {
  --pf-text: var(--text);
  --pf-text-secondary: var(--muted);
  --pf-text-muted: var(--muted);
  --pf-background: var(--ink-1);
  --pf-border: var(--line-ui);
  --pf-border-focus: var(--gold-2);
  --pf-hover: var(--ink-2);
  --pf-skeleton: var(--ink-2);
  --pf-skeleton-shine: var(--ink-3);
  --pf-mark: var(--strong);
  --pf-outline-focus: var(--gold-2);
  --pf-scroll-shadow: transparent;
  --pf-font: var(--body);
  --pf-border-radius: var(--radius);
  --pf-input-height: 44px;
  --pf-input-font-size: 1.05rem;
  --pf-result-title-font-size: 1.1rem;
  --pf-result-excerpt-font-size: 0.95rem;
  --pf-summary-font-size: 0.95rem;
  --pf-icon-search: url("/img/search.svg");
  --pf-icon-arrow: none; /* filter dropdowns only, which this site does not use */
  max-width: 760px;
}
.search-ui pagefind-input {
  display: block;
  margin-bottom: 14px;
}
.search-nojs {
  padding: 14px 16px;
  background: var(--ink-1);
  border: 1px solid var(--line-ui);
  border-radius: var(--radius);
}
/* The masthead search (templates/layout.html): the box whenever the brand's row has room for it;
   narrower, only its button, which opens /search/. Its 32 px height keeps the masthead at --mast-h. */
.mast-search {
  display: flex;
  align-items: center;
}
.mast-search input[type="search"] {
  display: none;
  min-width: 0;
  width: 170px;
  height: 32px;
  padding: 0 10px;
  border-radius: 8px 0 0 8px;
  border-right: 0;
}
/* One ring round the box and its button, not round the box alone, which stopped at the button. */
.mast-search {
  border-radius: 10px;
}
.mast-search input[type="search"]:focus-visible {
  outline: none;
}
.mast-search:has(input:focus-visible) {
  outline: 2px solid var(--gold-2);
  outline-offset: 2px;
}
/* Below 1010 px the nav takes the second row, so the box stays on the first beside the brand: that row
   needs 494 px with it (443 px under 481, where the brand shrinks), and the cut-offs keep 4 px over that
   for font rendering. Short of it the row wraps the theme button rather than shrink the box, so it hides. */
/* bp: 447, 480, 498 */
@media (min-width: 447px) and (max-width: 480px), (min-width: 498px) {
  .mast-search input[type="search"] {
    display: block;
  }
  .mast-search button {
    border-radius: 0 8px 8px 0;
    background: var(--ink-1);
  }
}
.nf-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  margin-top: 1.2em;
}
.nf-search label {
  font: 500 1rem / 1.2 var(--body);
  color: var(--muted);
}
/* Below 1010 px the brand, the nav, the search and the theme button no longer fit in one row (it was
   700 px until Tier Lists made six links, S-024; the search button made the rows wrap unevenly from
   440 px and overflow at 481 to 505): two rows, always the same, the nav across the second. */
/* bp: 1010 */
@media (max-width: 1009px) {
  :root {
    --mast-h: 90px;
  }
  .mast-in {
    flex-wrap: wrap;
    gap: 4px 8px;
  }
  .mast-in > nav {
    order: 3;
    flex: 1 0 100%;
    margin-left: 0;
  }
  .mast-search {
    margin-left: auto;
  }
}
/* Six nav links fit the one row from 1010 px only with tighter links, up to 1080 px. */
/* bp: 1010, 1080 */
@media (min-width: 1010px) and (max-width: 1080px) {
  .mast-nav a {
    padding: 9px 7px;
    letter-spacing: 0.04em;
  }
}
/* Professions made the nav 361 px: the one row needs about 733 px with 16 px gaps, so just above 700
   the gaps halve and the links tighten again. */
/* bp: 640 */
@media (max-width: 640px) {
  :root {
    --mast-h: 88px;
  }
} /* the nav links drop to 8 px padding */
/* bp: 480 */
@media (max-width: 480px) {
  :root {
    --mast-h: 85px;
  }
} /* the tight masthead: 8 px padding, 32 px links */

/* Zone maps (S-022): the game client's own map image, with the default pins laid over it in its pixels. */
.zone-art {
  position: relative; /* the pin card (js/zonemap.js) is placed in it */
  margin: 0 0 1.2rem;
}
.zone-top {
  display: grid;
  gap: 0 34px;
}
/* bp: 900 */
@media (min-width: 900px) {
  .zone-top {
    grid-template-columns: 1fr 1fr; /* the overview's words on the left, the zone's map on the right, half each */
    align-items: start;
  }
  .zone-top .zone-art {
    margin-top: 1.2rem; /* level with the first heading's top */
  }
}
.zone-map {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* The map page's zoom (js/zonemap.js, Panzoom): the frame clips the map as it grows, and each pin's inner group
   is scaled back by --pin-k, so pins and their names keep their size. */
.map-zoom {
  display: flex;
  width: max-content;
  margin: 0 0 6px auto;
}
.map-zoom button {
  min-width: 2.75rem;
  min-height: 2.75rem; /* 44 px: a touch target (2.5.8 asks 24) */
}
.map-frame {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.map-frame .zone-map {
  border: 0;
  border-radius: 0;
}
.map-frame.zoomed .zone-map {
  cursor: grab;
}
.pin-b {
  transform: scale(var(--pin-k, 1));
}
/* A herb's or ore's area: where it spawns, shown while its kind is ticked in "Which" (zones.areas, layers_css).
   The light edge over a dark one reads on any art, as the pins' halo does. */
.node-area {
  display: none;
  pointer-events: none;
}
.area-fill {
  fill: var(--halo-out);
  fill-opacity: 0.3;
}
.area-under,
.area-edge {
  fill: none;
  vector-effect: non-scaling-stroke; /* the edge keeps its width as the map zooms, like the pins */
}
.area-under {
  stroke: var(--halo-in);
  stroke-width: 4;
}
.area-edge {
  stroke: var(--halo-out);
  stroke-width: 2;
}
.pin-halo {
  fill: var(--halo-in);
  stroke: var(--halo-out);
}
@media screen {
  .pin .pin-n,
  .print-only {
    display: none; /* print's pin numbers and key (zones.map_art); ads.drawn skips .print-only too */
  }
}
.pin text {
  font: 600 26px / 1 var(--label); /* map pixels: about 13 px on the overview's half-width map */
  dominant-baseline: central;
  fill: var(--map-label);
  stroke: var(--on-fill);
  stroke-width: 6;
  stroke-linejoin: round;
  paint-order: stroke; /* a dark outline under light letters, legible on any part of the painted map */
  visibility: hidden; /* the name shows only while the pointer is on its icon */
  pointer-events: none;
}
.pin:hover text,
.pin:focus text {
  visibility: visible;
}
.pin:focus-visible {
  outline: 3px solid var(--gold);
}
:root.js .pin {
  cursor: pointer;
}
/* With the script, a mouse on a pin gets the /way card (js/tooltip.js), which names it: no label as well. */
:root.js .pin:hover text {
  visibility: hidden;
}
:root.js .pin:focus text {
  visibility: visible;
}
/* A pin's card (js/zonemap.js): the /way card's look, placed under the pin inside the map. */
.pin-card {
  position: absolute;
  z-index: 5;
  width: max-content;
  max-width: min(300px, calc(100% - 16px));
}
.pin-card[hidden] {
  display: none;
}
.pin-card:focus-visible {
  outline: 2px solid var(--gold);
}
.pin-card .pc-name {
  font-weight: 700;
}
.pin-card .pc-meta,
.pin-card .pc-at {
  color: #c9c9d6;
}
.pin-card .pc-acts {
  display: flex;
  gap: 12px;
  align-items: center;
}
.pin-card a {
  color: var(--wtt-gold);
}
/* The map page's legend: a checkbox per layer, and the generated rules in classes.css hide a layer's pins while its
   box is clear (zones.layers_css), so it works with no script. Beside the map on a wide screen, under it otherwise. */
/* bp: 900 */
@media (min-width: 900px) {
  .zone-art:has(.map-layers) {
    display: grid;
    grid-template-columns: 1fr 17rem;
    gap: 0 1.2rem;
    align-items: start;
  }
  .zone-art:has(.map-layers) figcaption {
    grid-column: 1 / -1;
  }
}
.map-layers {
  margin: 0.6rem 0 0;
  padding: 0.3rem 0.8rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.map-layers legend {
  padding: 0 0.3em;
  font-weight: 600;
}
.map-layers .lg {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.1rem;
  margin: 0.2rem 0 0.4rem;
}
.map-layers .lg-h {
  flex-basis: 100%;
  margin: 0.2rem 0 0;
  font-family: var(--label-caps);
  color: var(--muted);
}
.map-layers label {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  min-height: 28px; /* a target at least 24 px tall (2.5.8) */
  cursor: pointer;
}
/* A layer's "Which" choice: a box per kind, folded under its layer's own box (zones.which, site.js) */
.map-layers .map-pick {
  flex-basis: 100%;
  margin: 0 0.4rem 0.2rem 1.6rem; /* under its own box's label, so it reads as that layer's */
}
.map-layers .map-pick > summary {
  min-height: 28px; /* the boxes' own target height (2.5.8) */
  display: flex;
  align-items: center;
  gap: 0.3em;
  cursor: pointer;
  color: var(--muted);
}
.map-pick:has(input:checked) .pick-all {
  display: none; /* the script names the kinds instead; with none it says "all" */
}
.map-pick .pick-some {
  color: var(--text);
}
.map-pick .pick-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.9rem;
  padding: 0.1rem 0 0.3rem 0.9rem;
  border-left: 2px solid var(--line);
}
.map-pick .pick-clear {
  min-height: 28px;
  font: inherit;
}
.map-layers .n {
  color: var(--muted);
  white-space: nowrap; /* "(17)" stays with its label */
}
.map-layers .presets {
  margin: 0.4rem 0 0.2rem;
}
.map-layers .seg-wrap {
  margin: 0.4rem 0;
}
.map-hidden {
  margin: 0.2rem 0;
  color: var(--muted);
}
.map-layers-d > summary {
  font-weight: 600;
  cursor: pointer;
  min-height: 28px;
}
/* bp: 640 */
@media (min-width: 641px) {
  :root.js .map-layers-d > summary {
    display: none; /* site.js keeps the panel open beside or under the map; only a phone folds it */
  }
}
.map-key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.2rem;
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}
.map-key img {
  margin-right: 0.4em;
  vertical-align: -0.25em;
}

/* Forced colors (L-12): the browser replaces every color with the reader's palette, so the fills and accent
   colors that mark a pressed button or the current page disappear. A border or outline stays. */
@media (forced-colors: active) {
  .seg button[aria-pressed="true"] {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  .mast-nav a[aria-current] {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  .tabs a {
    border-bottom-color: transparent;
  }
  .tabs a[aria-current] {
    border-bottom-color: Highlight;
    border-bottom-width: 4px;
  }
}

/* Tier lists (S-023). The graphic: six rows S→F, a colored label cell and a row of framed icons, each
   framed in its class color (--c, from classes.css). The tier ramp runs warm to cold: S gold, A amber,
   B verd, C sky, D violet, F slate. Without JavaScript every write-up below shows. */
.tierlist {
  display: grid;
  gap: 3px;
  margin: 1.25rem 0 2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--line);
  overflow: hidden;
}

.tier {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  background: var(--ink-1);
  min-height: 5.5rem;
}

.tier-label {
  display: grid;
  place-items: center;
  margin: 0;
  font: 700 2rem / 1 var(--display);
  color: var(--on-fill);
  background: var(--t);
}

.tier-s {
  --t: var(--gold-fill);
}
.tier-a {
  --t: var(--amber);
}
.tier-b {
  --t: var(--verd);
}
.tier-c {
  --t: var(--sky);
}
.tier-d {
  --t: var(--violet);
}
.tier-f {
  --t: var(--slate-fill);
}

.tier-items {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0.5rem;
  list-style: none;
}

/* Every tile the same size: wide enough for the longest name on one line ("Marksmanship", 93 px at 0.8rem;
   "Beast Mastery" 85), and names never wrap, so no tile is taller than the rest. At 5.5rem a one-word name
   ran past the border and pulled the icon off center. test_tierlist checks fit, centering and size. */
.tier-item {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
  width: 7rem;
  padding: 0.35rem 0.25rem;
  border: 2px solid var(--c, var(--line-2));
  border-radius: var(--radius);
  background: var(--ink-0);
  color: var(--text);
  text-align: center;
  text-decoration: none;
}

.tier-item:hover,
.tier-item:focus-visible,
.tier-item[aria-current] {
  background: var(--ink-2);
}

.tier-name {
  font-size: 0.8rem;
  line-height: 1.2;
  white-space: nowrap;
}

.tier-name span {
  display: block;
  color: var(--muted);
}

.tier-none {
  align-self: center;
  margin: 0;
  padding: 0 1rem;
  color: var(--faint);
}

.tl-meta,
.tl-headline {
  color: var(--muted);
}

/* A note with a colored bar at its left (S-052 C4): the archived tier list and the PvP forecast. */
.tl-archived,
.pvp-forecast {
  padding: 0.75rem 1rem;
  border-left: 4px solid var(--amber);
  background: var(--ink-1);
}

.tier-chip {
  color: var(--on-fill);
  background: var(--t);
}

/* Definition rows (S-052 C5): a 9rem label column and the text beside it, one column on a narrow screen. */
:is(.tl-tiers, .pvp-verdict, .pvp-fight) > div {
  display: grid;
  grid-template-columns: 9rem 1fr;
  gap: 0.25rem 1rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--line);
}

:is(.tl-tiers, .pvp-verdict, .pvp-fight) dd {
  margin: 0;
}

.tl-tiers > div {
  padding: 0.4rem 0;
}

.tl-entry {
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  border-left: 4px solid var(--c, var(--line-2));
  background: var(--ink-1);
  scroll-margin-top: var(--anchor-gap);
}

.tl-entry h3 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.tl-mini {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}

.tl-mini .tier-item {
  width: auto;
  padding: 0.15rem;
}

/* The index filter (S-038, site.js): a facet is a row of pills, each a real checkbox, ticked ones gold. */
.tl-filters {
  align-items: center;
  margin-bottom: 18px;
}
.tl-filters .shown {
  padding-bottom: 0;
}
.facet {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  border: 0;
  margin: 0;
  padding: 0;
}
.facet legend {
  float: left;
  margin-right: 4px;
  font: 600 var(--label-5) / 1 var(--label-caps);
  text-transform: uppercase;
  letter-spacing: var(--track-5);
  color: var(--muted);
}
.filters .pill {
  flex-direction: row;
  align-items: center;
  gap: 6px;
  min-height: 32px; /* WCAG 2.5.8 */
  padding: 4px 12px;
  border: 1px solid var(--line-ui);
  border-radius: 99px;
  background: var(--ink-1);
  cursor: pointer;
}
.filters .pill > span {
  font: 600 0.9rem / 1 var(--label);
  letter-spacing: 0.03em;
  text-transform: none;
  color: var(--text);
}
.filters .pill > .n {
  color: var(--muted);
}
.pill input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.pill:has(input:checked) {
  background: color-mix(in srgb, var(--gold) 22%, var(--ink-2));
  border-color: var(--gold);
}
.pill:has(input:checked) > span:first-of-type::before {
  content: "✓ "; /* ticked shows in the shape too, not only the color (WCAG 1.4.1) */
  color: var(--gold-2);
}
.pill:has(input:focus-visible) {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* bp: 480 */
@media (max-width: 480px) {
  .tier {
    grid-template-columns: 3rem 1fr;
  }
  .tier-item {
    width: 6rem;
    padding-inline: 0.15rem;
  }
  .tier-name {
    font-size: 0.7rem;
  }
}

/* ---- Tier lists: the build picker (WP-1, OD-6) ----------------------------------------------------
   A <details> of links, top right of the list's header, once a list has two builds. .hero-in clips its
   overflow, so the open list grows the header in flow instead of floating over the page. */
.tierlist-page .hero-in {
  flex-wrap: wrap;
}
.tl-builds {
  position: relative; /* above .hero-in::after */
  z-index: 1;
  align-self: flex-start;
  margin-left: auto;
  max-width: 100%;
}
.tl-builds > summary {
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ink-1);
  cursor: pointer;
}
.tl-builds > ol {
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}
.tl-builds li {
  padding: 0.35rem 0;
  border-top: 1px solid var(--line);
}
.tl-builds a[aria-current] {
  font-weight: 700;
}
.tl-builds-moves {
  display: block;
  color: var(--muted);
  font-size: 0.85em;
}
/* ---- end of the build picker ---------------------------------------------------------------------- */

/* The tier list panel (S-024, js/tierlist.js). Its hooks are data-tierlist, not data-js: [data-js] marks a
   control that only works with a script, and is hidden without one; the chart and write-ups are content. */
.tier-item[aria-current] {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

.tl-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.75rem 0;
}

/* A .btn as a step control (S-052 C2): a 44 px target, in the case it is written in. */
.btn-step {
  line-height: 1.2;
  letter-spacing: normal;
  text-transform: none;
  min-height: 44px;
}

.tl-next {
  margin-left: auto;
}

.tl-entry h3:focus {
  outline: none;
}

.tl-entry h3:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 4px;
}

/* Tier Lists made six nav links (S-024). The brand never wraps: a masthead taller than --mast-h hides
   every anchored heading under it, and a wrapped brand was how the one row used to absorb a long nav.
   Instead the masthead takes two rows below 1010 px and the phone nav row tightens. The browser suite
   measures every 5 px from 320 to 1280 (test_masthead_offsets), so a seventh link shows where it breaks. */
.brand {
  white-space: nowrap;
}
/* With text enlarged (WCAG 1.4.4, 200%) nothing fits one row: the nav drops to a row of its own, and
   wraps within it, rather than running off the side. At normal size the sweep holds every width to
   one row, so this never fires there unnoticed. */
.mast-in,
.mast-nav {
  flex-wrap: wrap;
}
/* The nav's own row on a phone: six links need 467 px at 481 px (8 px padding) and 309 px at 320 px
   (3 px), against rows of about 457 and 296. */
/* bp: 480, 520 */
@media (min-width: 481px) and (max-width: 520px) {
  .mast-nav {
    gap: 0;
  }
  .mast-nav a {
    padding-inline: 5px;
  }
}
/* bp: 400 */
@media (max-width: 400px) {
  .mast-nav a {
    padding: 0 2px;
    letter-spacing: 0;
  }
}
/* Legacy made a seventh link once a tier list is published (S-030); only then do these apply, so six
   links keep the layout above. Seven need about 40 px more than six: the one row takes it from tighter
   links up to 1150 px, the nav's own row from its gaps and spacing, and a phone's (330 px of text against
   296 at 320 px) cannot, so there the nav takes two rows of four columns and the masthead grows with it. */
/* bp: 1010, 1150 */
@media (min-width: 1010px) and (max-width: 1150px) {
  .mast-nav:has(> li:nth-child(7)) a {
    padding-inline: 4px;
    letter-spacing: 0.02em;
  }
}
/* bp: 1010 */
@media (max-width: 1009px) {
  .mast-nav:has(> li:nth-child(7)) {
    gap: 0;
  }
}
/* bp: 480, 640 */
@media (min-width: 481px) and (max-width: 640px) {
  .mast-nav:has(> li:nth-child(7)) a {
    padding-inline: 4px;
    letter-spacing: 0.02em;
  }
}
/* bp: 480 */
@media (max-width: 480px) and (min-height: 501px) {
  /* not on a short screen, whose masthead scrolls away (L-39, below) */
  :root:has(.mast-nav > li:nth-child(7)) {
    --mast-h: 117px;
  }
}
/* bp: 480 */
@media (max-width: 480px) {
  .mast-nav:has(> li:nth-child(7)) {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
  }
  .mast-nav:has(> li:nth-child(7)) a {
    justify-content: center;
  }
}

/* L-39 (WP-4): on a short screen (a phone on its side) the masthead scrolls away instead of taking a
   quarter of the height. Nothing then sits under it, so the offsets that read --mast-h go to zero. */
@media (max-height: 500px) {
  :root {
    --mast-h: 0px;
  }
  .mast {
    position: static;
  }
}

/* A spec's Races tab (S-055): the spec's section of a race-per-spec list, every race it can be, best first. */
.tl-stakes {
  border: 1px solid var(--line-ui);
}
.tl-stakes-big {
  color: var(--rose-ink);
}
.tl-stakes-some {
  color: var(--amber-ink);
}
.tl-stakes-little {
  color: var(--muted);
}
.tl-spec {
  margin: 2rem 0 0;
  padding-top: 1rem;
  border-top: 3px solid var(--c, var(--line));
}
.tl-best {
  list-style: none;
  padding: 0;
}
.tl-races {
  display: grid;
  gap: 0.5rem;
  margin: 1rem 0;
  padding: 0;
  list-style: none;
}
.tl-race {
  padding: 0.5rem 0.75rem;
  border-left: 4px solid var(--c, var(--line));
  background: var(--ink-1);
}
.tl-race h4 {
  margin: 0;
}
.tl-race .tl-headline {
  margin: 0.25rem 0;
}

/* A spec's PvP tab (S-044): the forecast note (with .tl-archived), the verdict per list, the profile table. */

.pvp-verdict dd p {
  margin: 0.25rem 0 0;
}

/* Phase C (S-047): the fight plan and battleground lines as labeled rows, the matchup verdicts by color. */
.mu-favored {
  color: var(--verd-ink);
}

.mu-even {
  color: var(--muted);
}

.mu-unfavored {
  color: var(--rose-ink);
}

.mu-c-low {
  color: var(--amber-ink);
}

/* Five columns do not fit a phone: below 600 px each matchup is a card, its cells labeled (plan §3.7). */
/* bp: 600 */
@media (max-width: 37.5rem) {
  .pvp-fight > div {
    grid-template-columns: 1fr;
  }

  .pvp-mu thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .pvp-mu :is(tr, th, td) {
    display: block;
  }

  .pvp-mu tr {
    padding: 0.5rem 0;
    border-top: 1px solid var(--line);
  }

  .pvp-mu td[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 600;
  }
}

/* The pips are a picture of the number beside them (aria-hidden), so a narrow screen keeps only the number. */
/* bp: 640 */
@media (max-width: 40rem) {
  :is(.tl-tiers, .pvp-verdict) > div {
    grid-template-columns: 1fr;
  }

  .pvp-profile .pips {
    display: none;
  }

  .pvp-profile :is(th, td) {
    padding-inline: 0.4rem;
    white-space: normal;
  }
}

/* The class's other specs drop below 400 px, so the profile fits a phone with no sideways scroll (plan §3.7). */
/* bp: 400 */
@media (max-width: 25rem) {
  .pvp-profile {
    font-size: 0.875rem;
  }

  .pvp-n1 :is(th, td):nth-child(n + 4),
  .pvp-n2 :is(th, td):nth-child(n + 5) {
    display: none;
  }
}

/* A spec's Races tab (S-055): one heading and a PvE / PvP drop-down; site.js hides the other list. With no
   script both lists show, each under its own heading, which the drop-down makes redundant once it works. */
.tl-mode-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.tl-mode-bar h2 {
  margin-right: auto;
}
.tl-mode-bar select {
  min-width: 0;
}
.js [data-races-mode].off {
  display: none !important;
}
.js .tl-mode-h {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
