/* Copyright 2018-2026 Preston A. Elder <prez@neuromancy.net>. All rights reserved. */
/* Rotation Master site.
   Colors, type, shape and decoration all come from the design tokens in
   themes.css (imported here, so pages need only this one stylesheet); the
   embedded viewer uses the same token names (--stone, --surface, --text,
   --muted, --gold, --azure, --line), so it follows the page's theme.
   Theme = <html data-edition-theme>, light/dark = <html data-theme> or the
   system preference. Optional self-hosted fonts: see themes/fonts.css. */
@import url("themes.css");

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

/* Form fields: one set of measurements for every single-line control (text, search, number, color, select, the
   search box with its Change/Find buttons, and the buttons beside them), so side-by-side fields are the same height
   and start at the same top. They are fixed-height boxes: padding + the line + the border add up to
   --field-height, whatever the control's own default is. Textareas share padding, border, radius and font size and
   keep their own height. */
:root {
  --field-height: 40px;
  --field-pad-y: 8px;
  --field-pad-x: 10px;
  --field-border: 1px;
  --field-font-size: 16px;
  --field-line-height: 22px;
  --field-radius: var(--radius);
}

body {
  --site-content-width: 1200px;
  --site-gutter: 16px;
  /* Stacking order, lowest to highest: sticky page furniture (sidebars), the header, what opens from the header
     (menus), modal dialogs, the skip link. Wowhead's tooltips are the script's own. */
  --z-sticky: 10;
  --z-header: 100;
  --z-popover: 110;
  --z-modal: 200;
  --z-skip: 300;
  margin: 0;
  color: var(--text);
  font: 16px/1.6 var(--font);
  background-color: var(--stone);
  background-image: var(--theme-texture);
  background-size: var(--theme-texture-size);
  background-repeat: repeat;
}

/* Page width: the default is the one capped column above. "Full width" (the header's width button; site/theme-init.js sets
   <html data-width="full"> before first paint and remembers it in this browser) lets the frame, the header and the footer
   fill the window less the gutters, which grow a little on a big screen. It changes nothing below the cap (a window narrower
   than 1233px is already full), and prose keeps its own measure (.prose, .lead, .legal) inside the wide frame. */
html[data-width="full"] body {
  --site-content-width: 100%;
}

@media (min-width: 1233px) {
  html[data-width="full"] body {
    --site-gutter: clamp(16px, 2.5vw, 48px);
  }
}

html[data-width="full"] main p {
  max-width: 100ch;
}

a {
  color: var(--azure);
  text-underline-offset: 2px;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

::selection {
  background: var(--gold);
  color: var(--on-gold);
}

input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--azure);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 8px;
  z-index: var(--z-skip);
  padding: 8px 12px;
  background: var(--surface);
  color: var(--azure);
}

.skip-link:focus {
  left: 8px;
}

main {
  display: block;
  min-width: 0;
  overflow-wrap: break-word;
  max-width: var(--site-content-width);
  margin: 0 auto;
  padding: 24px var(--site-gutter) 64px;
}

main:focus {
  outline: none;
}

h1,
h2,
h3,
h4 {
  color: var(--gold);
  line-height: 1.25;
}

h1 {
  font: normal clamp(28px, 5vw, 40px)/1.15 var(--font-display);
  margin: 8px 0 16px;
  overflow-wrap: break-word;
}

h2,
h3 {
  font-family: var(--serif);
  font-weight: var(--heading-weight);
  letter-spacing: var(--heading-tracking);
}

h2 {
  font-size: 22px;
  margin: 32px 0 12px;
  text-transform: var(--heading-case);
}

h3 {
  font-size: 18px;
  margin: 24px 0 8px;
}

h4 {
  font-size: 16px;
  margin: 16px 0 6px;
}

p {
  margin: 8px 0 14px;
}

/* A code chip is one identifier: it never breaks (not even at a hyphen); one longer than its line
   scrolls inside itself rather than pushing the page sideways. */
code {
  font: 0.92em var(--mono);
  background: var(--code-bg);
  color: var(--text);
  padding: 1px 5px;
  border-radius: 4px;
  overflow-wrap: normal;
  word-break: normal;
  white-space: nowrap;
  display: inline-block;
  max-width: 100%;
  overflow-x: auto;
  vertical-align: bottom;
}

.nowrap {
  white-space: nowrap;
}

pre {
  font: 13px/1.55 var(--mono);
  background: var(--code-bg);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  overflow-x: auto;
  white-space: pre;
}

pre code {
  background: none;
  padding: 0;
  font-size: inherit;
  overflow-wrap: normal;
  white-space: inherit;
  display: inline;
  max-width: none;
  overflow-x: visible;
  vertical-align: baseline;
}

/* Divider: a rule with the theme's ornament (an SVG mask) in a gap at the center. */
hr {
  position: relative;
  overflow: visible;
  height: 12px;
  margin: 28px 0;
  border: 0;
  background: linear-gradient(
      90deg,
      var(--line) calc(50% - 56px),
      transparent calc(50% - 56px) calc(50% + 56px),
      var(--line) calc(50% + 56px)
    )
    center / 100% 1px no-repeat;
}

.icon {
  width: 18px;
  height: 18px;
  vertical-align: -3px;
  flex: none;
}

.hint,
.fine,
.byline,
.result-count,
.crumbs {
  color: var(--muted);
  font-size: 14px;
}

.empty {
  color: var(--muted);
  font-style: italic;
}

.problem {
  color: var(--danger);
}

.ok {
  color: var(--ok);
}

.user-id {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
}

/* Header: the theme's rule runs along the bottom edge. */
.site-header {
  /* Above all page content (a sticky sidebar, the hero, a canvas): its menus open into it, and nothing between
     the header and the page may clip them (no overflow, contain or transform on the header or its row). */
  position: relative;
  z-index: var(--z-header);
  background-color: var(--surface);
  background-color: color-mix(in srgb, var(--surface) 90%, transparent);
  box-shadow: var(--shadow);
  padding-bottom: 3px;
  background-image: var(--theme-rule);
  background-size: 100% 3px;
  background-position: 0 100%;
  background-repeat: no-repeat;
}

/* One row at every width: the main links fold into the More menu one at a time as the row fills (site/nav-fit.js; all of
   them into the hamburger on a phone), the brand's name hides on phones, the account name shortens. --hdr-gap is the gap
   between the row's boxes, --act-gap the one between the controls. */
.header-inner {
  --hdr-gap: 20px;
  --act-gap: 8px;
  max-width: var(--site-content-width);
  margin: 0 auto;
  padding: 10px var(--site-gutter);
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 8px var(--hdr-gap);
  min-width: 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  text-decoration: none;
  font: 20px/1 var(--font-display);
  flex: none;
  white-space: nowrap;
}

.brand picture {
  display: contents;
}

.brand .logo {
  width: 40px;
  height: 40px;
  flex: none;
}

.main-nav {
  display: flex;
  flex-wrap: nowrap;
  gap: 2px 4px;
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
}

.main-nav a[hidden],
.nav-menu li[hidden] {
  display: none;
}

.main-nav a:focus-visible {
  outline-offset: -2px;
}

.main-nav a {
  white-space: nowrap;
}

.main-nav a {
  color: var(--text);
  text-decoration: none;
  padding: 8px 10px;
  border-radius: var(--radius);
  transition:
    background-color var(--motion),
    color var(--motion);
}

.main-nav a:hover {
  background: var(--surface-2);
}

.main-nav a[aria-current="page"] {
  color: var(--gold);
  box-shadow: inset 0 -2px 0 var(--gold);
  border-radius: 0;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--act-gap);
  flex-wrap: nowrap;
  margin-left: auto;
  flex: 0 1 auto;
  min-width: 0;
}

/* The icon buttons never shrink or wrap; if the row is ever too short, the account name gives way first. (Phones, below
   641px, have their own rules further down: the account name takes what is left.) */
@media (min-width: 641px) {
  .header-actions > * {
    flex: none;
  }
  .header-actions > .account-menu {
    flex: 0 1 auto;
    min-width: 0;
  }
  .header-actions .account-button {
    max-width: 100%;
  }
}

.account {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  flex-wrap: nowrap;
  white-space: nowrap;
}

/* Header menus (the main links that do not fit, the account): disclosures
   whose list drops below the button; site.mjs adds keys and click-outside. The main links' menu sits right after them
   in the row; hidden until the row has folded a link (data-nav-fit, below). */
.nav-menu,
.account-menu {
  position: relative;
}

.nav-menu {
  display: none;
  flex: none;
}

.nav-more-text,
.nav-menu .caret {
  display: none;
}

.nav-menu > summary,
.account-menu > summary {
  list-style: none;
  cursor: pointer;
}

.nav-menu > summary::-webkit-details-marker,
.account-menu > summary::-webkit-details-marker {
  display: none;
}

.account-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 8px 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--text);
  max-width: 220px;
}

.account-button:hover {
  background: var(--surface-2);
}

.account-name {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.account-menu[open] .caret {
  transform: rotate(180deg);
}

.menu-list {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: var(--z-popover);
  min-width: 200px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
}

.nav-menu .menu-list {
  left: 0;
  right: auto;
}

.menu-list a,
.menu-list button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 15px;
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}

.menu-list a:hover,
.menu-list button:hover {
  background: var(--surface-2);
}

.menu-list a:focus-visible,
.menu-list button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.menu-list a[aria-current="page"] {
  color: var(--gold);
  font-weight: 700;
}

.menu-separator {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}

.link-button {
  background: none;
  border: 0;
  color: var(--azure);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  padding: 6px 4px;
  text-decoration: underline;
  min-height: 0;
  margin: 0;
}

/* Buttons (also restyles the viewer's buttons) */
.button,
button.button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  margin: 0;
  border: 1px solid var(--azure);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--azure);
  font: inherit;
  font-size: 15px;
  line-height: 1.3;
  text-decoration: none;
  cursor: pointer;
  min-height: var(--field-height);
  vertical-align: middle;
  transition:
    background-color var(--motion),
    border-color var(--motion),
    color var(--motion),
    box-shadow var(--motion);
}

.button:hover {
  background: var(--surface-2);
}

.button.primary {
  background: var(--azure);
  color: var(--on-accent);
}

.button.primary:hover {
  filter: brightness(1.08);
}

.button.discord {
  background: var(--discord);
  border-color: var(--discord);
  color: var(--on-discord);
}

.button.danger {
  border-color: var(--danger);
  color: var(--danger);
}

.button.danger.primary {
  background: var(--danger);
  color: var(--on-danger);
}

.button:disabled {
  opacity: 0.55;
  cursor: default;
}
.button[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}
/* Without JavaScript the theme and width buttons and Sign out do nothing: they are not offered. */
@media (scripting: none) {
  [data-action="theme"],
  [data-action="width"],
  [data-action="sign-out"],
  .menu-separator:has([data-action="sign-out"]) {
    display: none;
  }
}
.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: background-color var(--motion);
}

.icon-button:hover {
  background: var(--surface-2);
}

/* The width button only does something where the default column is capped: a window of 1233px or more. It shows the arrows
   that apply (widen, or back in). */
.icon-button.width-toggle {
  display: none;
}

@media (min-width: 1233px) {
  .icon-button.width-toggle {
    display: inline-flex;
  }
}

html[data-width="full"] .width-toggle .to-full,
html:not([data-width="full"]) .width-toggle .to-default {
  display: none;
}

/* The language menu: a disclosure the size of the theme button (no extra row);
   the list drops below it, each language in its own name and script. */
.lang-menu {
  position: relative;
}

.lang-menu > summary {
  list-style: none;
  width: auto;
  min-width: 40px;
  padding: 0 8px;
  gap: 4px;
}

.lang-menu > summary::-webkit-details-marker {
  display: none;
}

.lang-menu > summary .icon {
  flex: none;
}

.lang-short {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.lang-list {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: var(--z-popover);
  min-width: 200px;
  max-height: min(70vh, 480px);
  overflow: auto;
  margin: 0;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
}

.lang-heading {
  margin: 2px 8px 6px;
  font-size: 12px;
  color: var(--muted);
}

.lang-list ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.lang-list button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.lang-list button:hover {
  background: var(--surface-2);
}

.lang-list button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.lang-list button[aria-current="true"] {
  font-weight: 700;
  color: var(--gold);
}

.lang-list button[aria-current="true"]::after {
  content: " ✓";
}

.lang-auto {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}

.translation-note {
  font-size: 14px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Footer */
.site-footer {
  border-top: 1px solid var(--line);
  background-color: var(--surface);
  background-color: color-mix(in srgb, var(--surface) 90%, transparent);
}

.footer-inner {
  max-width: var(--site-content-width);
  margin: 0 auto;
  padding: 20px var(--site-gutter) 28px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
}

.footer-contact,
.site-footer .fine {
  margin: 8px 0 0;
}

.footer-sep {
  margin: 0 6px;
  color: var(--muted);
}

.dev-note {
  color: var(--danger);
}

/* Home. The optional hero art sits behind the right column only, fading in
   from the left, so it never runs under the text; phones never load it. */
.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: 32px;
  align-items: center;
  padding: 16px 0 8px;
}

.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0 0 0 55%;
  pointer-events: none;
  background-color: transparent; /* decorative layer: no text sits on it */
  background-image: var(--theme-hero-image);
  background-position: right center;
  background-size: cover;
  background-repeat: no-repeat;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 30%);
  mask-image: linear-gradient(90deg, transparent, #000 30%);
}

.hero h1 {
  font-size: clamp(30px, 5vw, 46px);
}

/* The hero heading is sized from the box it sits in, not from the screen: the longest word of any language (German
   "hervorgehoben", 8.5 em) must fit on its line, whatever the column, the mark beside it or the language. */
@supports (width: 1cqi) {
  .hero-text {
    container-type: inline-size;
  }
  .hero h1 {
    font-size: clamp(24px, 10.5cqi, 46px);
  }
}

/* The addon's logo beside the headline: wide screens only (phones load no
   raster art; the header mark is already there). A missing file leaves an
   empty, transparent box. */
.hero-mark {
  display: none;
}

@media (min-width: 721px) {
  .hero-text {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    column-gap: 24px;
    align-items: center;
  }
  .hero-text > * {
    grid-column: 1 / -1;
  }
  .hero-text > h1 {
    grid-column: 2;
    margin: 0;
  }
  @supports (width: 1cqi) {
    .hero h1 {
      font-size: clamp(22px, calc((100cqi - 184px) / 9.6), 46px);
    }
  }
  .hero-mark {
    display: block;
    grid-column: 1;
    width: 160px;
    height: 160px;
    margin: 8px 0 16px;
    background-color: transparent; /* the logo has its own transparent edge */
    background-image: image-set(
      url("img/logo/logo-160.avif") type("image/avif") 1x,
      url("img/logo/logo-320.avif") type("image/avif") 2x,
      url("img/logo/logo-160.webp") type("image/webp") 1x,
      url("img/logo/logo-320.webp") type("image/webp") 2x,
      url("img/logo/logo-160.png") type("image/png") 1x
    );
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
  }
}

.lead {
  font-size: 18px;
  max-width: 62ch;
}

.hero-figure {
  margin: 0;
}

.hero-figure pre {
  font-size: 13px;
  background: var(--surface);
  box-shadow: var(--shadow-raised);
}

.hl {
  color: var(--on-gold);
  background: var(--gold);
  padding: 0 3px;
  border-radius: 3px;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: 16px;
  margin: 32px 0;
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: var(--border-accent) solid var(--gold);
  border-radius: var(--radius);
  padding: 16px 18px;
  box-shadow: var(--shadow);
}

.card h2 {
  margin-top: 0;
  font-size: 20px;
}

.card h2 a {
  color: var(--gold);
  text-decoration: none;
}

/* The home page's four boxes: 2x2, one column on phones. The box opens its heading's link (stretched over the box);
   the links inside it sit above that target and stay their own. */
.home-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

/* The icon and the heading share the first row (the icon at the left, the heading beside it, both centered on
   the row); the sentence and the links take the full width below. A long heading wraps in its own column,
   never the icon. */
.home-card {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto 1fr;
  align-items: center;
  column-gap: 12px;
  row-gap: 4px;
  min-width: 0;
  transition:
    border-color var(--motion),
    box-shadow var(--motion);
}

.home-card:hover,
.home-card:focus-within {
  border-color: var(--gold);
  box-shadow: var(--shadow-raised);
}

.home-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--gold);
  background: var(--surface-2);
}

.home-card-icon .icon {
  width: 26px;
  height: 26px;
}

.home-card h2 {
  margin: 0;
  min-width: 0;
  font-size: 22px;
  overflow-wrap: break-word;
}

.home-card p {
  grid-column: 1 / -1;
  margin: 4px 0 0;
}

.card-main::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.card-main:focus-visible::after {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.card-links {
  align-self: end;
  margin-top: 0 !important;
  padding-top: 10px;
  font-size: 15px;
}

.card-links a {
  position: relative;
  z-index: 1;
}

@media (max-width: 720px) {
  .home-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.addon-sources {
  margin: 32px 0;
}

.addon-sources h2 {
  margin-top: 0;
}

/* The four download links stay together on the left; Join the Discord is set apart on the right (under them on a phone). */
.addon-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
  margin-top: 12px;
}

.addon-row .source-links {
  margin: 0;
}

.addon-discord {
  margin-left: auto;
}

@media (max-width: 720px) {
  .addon-discord {
    margin-left: 0;
  }
}

.source-links {
  list-style: none;
  padding: 0;
  margin: 12px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 12px;
}

.source-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  box-shadow: var(--shadow);
}

.source-link .icon {
  width: 24px;
  height: 24px;
  flex: none;
  color: var(--gold);
}

.source-link:hover {
  border-color: var(--gold);
}

/* Share listings */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
}

.page-head h1 {
  margin-bottom: 8px;
}

.share-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: 14px;
}

.share-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  min-width: 0;
  box-shadow: var(--shadow);
  transition:
    box-shadow var(--motion),
    border-color var(--motion);
}

.share-card:hover {
  box-shadow: var(--shadow-raised);
  border-color: var(--line-strong);
}

.share-card h3 {
  margin: 0 0 6px;
  font-size: 18px;
  overflow-wrap: anywhere;
}

.share-card h3 a {
  color: var(--text);
  text-decoration: none;
}

.share-card h3 a:hover {
  color: var(--azure);
}

.share-card .excerpt {
  color: var(--muted);
  overflow-wrap: anywhere;
}

.share-card .byline {
  margin-bottom: 0;
}

/* One pill list everywhere pills appear: a single flex row-wrap box whose row gap equals its column gap, so
   a pill drops to the next line only when it truly does not fit. Every pill is one line of the same height
   and never breaks inside; one longer than the box is cut with an ellipsis rather than overflowing it. A card
   keeps all its pills in one list: a second list always starts a new line. */
.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  margin: 8px 0;
  min-width: 0;
  padding: 0;
  list-style: none;
}

.tag {
  display: inline-block;
  box-sizing: border-box;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
  font-size: 12px;
  line-height: 18px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
}

.tag-kind {
  border-color: var(--gold);
  color: var(--gold);
}

.filters {
  display: grid;
  grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)) auto;
  gap: 10px;
  align-items: end;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px;
  margin: 8px 0 12px;
}

.filters label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 14px;
  color: var(--muted);
}

/* The specialization filter waits for a class: disabled (skipped by Tab, not
   submitted) and visibly so in every theme, with its hint. */
.filters select:disabled {
  opacity: 0.6;
  color: var(--muted);
  background-color: var(--surface-2);
  border-style: dashed;
  cursor: not-allowed;
}

/* Its hint is read with it (aria-describedby); on screen the grayed select's
   own "Choose a class first" says the same, so the row stays aligned. */
.filters .spec-hint {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Administrators' account page */
.admin-form {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 8px 12px;
  margin: 8px 0 16px;
}

.admin-form label:not(.check) {
  flex-basis: 100%;
  color: var(--muted);
  font-size: 14px;
}

.admin-form fieldset {
  flex-basis: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin: 0;
  padding: 8px 12px;
}

.status-line:empty {
  display: none;
}

input:where(
  :not(
    [type="checkbox"],
    [type="radio"],
    [type="range"],
    [type="hidden"],
    [type="file"],
    [type="image"],
    [type="button"],
    [type="submit"],
    [type="reset"]
  )
),
select,
textarea {
  box-sizing: border-box;
  max-width: 100%;
  font: inherit;
  font-size: var(--field-font-size);
  line-height: var(--field-line-height);
  color: var(--text);
  background: var(--surface);
  border: var(--field-border) solid var(--line-strong);
  border-radius: var(--field-radius);
  padding: var(--field-pad-y) var(--field-pad-x);
}

input:where(
  :not(
    [type="checkbox"],
    [type="radio"],
    [type="range"],
    [type="hidden"],
    [type="file"],
    [type="image"],
    [type="button"],
    [type="submit"],
    [type="reset"]
  )
),
select {
  height: var(--field-height);
  min-height: var(--field-height);
  vertical-align: middle;
}

/* The native spinner and the search chrome would make a number or search box a different size from its neighbors: the
   arrow keys and the wheel still step a number. */
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type="search"] {
  -webkit-appearance: none;
  appearance: none;
}

input[type="search"]::-webkit-search-decoration {
  display: none;
}

input[type="color"] {
  padding: 3px 4px;
  cursor: pointer;
}

textarea {
  width: 100%;
  min-height: var(--field-height);
  resize: vertical;
  font: 14px/1.5 var(--mono);
}

textarea#share-description,
textarea#report-details {
  font-family: var(--font);
  font-size: var(--field-font-size);
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--focus);
}

.pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin: 24px 0 8px;
  flex-wrap: wrap;
}

/* Forms */
/* Forms and sections fill the one content width (--site-content-width, set on main); only the controls and the reading text inside keep a measure. */
.share-form,
.signin-form,
.report-form {
  max-width: none;
}

.share-form label,
.signin-form label,
.report-form label {
  display: block;
  margin: 16px 0 6px;
  font-weight: 600;
}

.share-form input#share-title {
  width: 100%;
}

.signin-form input {
  width: 100%;
  max-width: 480px;
}

.share-form textarea {
  width: 100%;
}

fieldset {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 8px 16px 16px;
  margin: 20px 0;
  min-width: 0;
}

fieldset:disabled {
  opacity: 0.6;
}

legend {
  color: var(--gold);
  padding: 0 6px;
  font-weight: 600;
}

fieldset.editions {
  padding: 8px 12px;
}

label.check {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  font-weight: normal !important;
  margin: 4px 16px 4px 0 !important;
}

label.check input {
  min-height: 0;
}

.detected {
  margin: 12px 0;
}

.preview-box {
  margin: 10px 0;
}

.preview-box summary {
  cursor: pointer;
  color: var(--azure);
}

.preview-box .prose {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 4px 14px;
  margin-top: 8px;
}

/* Callouts */
.callout {
  border-left: var(--border-accent) solid var(--azure);
  background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 4px 16px;
  margin: 16px 0;
}

.callout-tip {
  border-left-color: var(--ok);
}

.callout-warning,
.callout-important {
  border-left-color: var(--danger);
}

blockquote {
  margin: 16px 0;
  padding: 2px 16px;
  border-left: var(--border-accent) solid var(--line);
  color: var(--muted);
}

/* Prose (help pages and descriptions) */
.prose {
  max-width: 78ch;
  overflow-wrap: break-word;
}

.prose ul,
.prose ol {
  padding-left: 1.4em;
}

.prose li {
  margin: 4px 0;
}

.prose .table-wrap {
  overflow-x: auto;
  margin: 12px 0;
}

.prose table {
  border-collapse: collapse;
  width: 100%;
  font-size: 15px;
}

.prose th,
.prose td {
  border: 1px solid var(--line);
  padding: 6px 10px;
  text-align: left;
  vertical-align: top;
}

.prose th {
  background: var(--surface-2);
}

.prose .align-right {
  text-align: right;
}

.prose .align-center {
  text-align: center;
}

.diagram {
  margin: 16px 0;
}

.diagram pre {
  background: var(--surface);
  line-height: 1.45;
}

/* Help */
.help-layout {
  display: grid;
  grid-template-columns: 230px minmax(0, 1fr) 200px;
  gap: 32px;
  align-items: start;
}

.help-nav,
.help-outline {
  position: sticky;
  z-index: var(--z-sticky);
  top: 12px;
  max-height: calc(100vh - 24px);
  overflow: auto;
  font-size: 14px;
}

.help-nav summary {
  display: none;
}

.help-nav h2,
.help-outline h2 {
  font: 600 13px/1.25 var(--font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 18px 0 6px;
}

.help-nav ul,
.help-outline ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.help-nav a,
.help-outline a {
  display: block;
  padding: 4px 8px;
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
}

.help-nav a:hover,
.help-outline a:hover {
  background: var(--surface-2);
}

.help-nav a[aria-current="page"] {
  background: var(--surface-2);
  color: var(--gold);
  font-weight: 600;
}

.help-article h1 {
  margin-top: 0;
}

.help-article h2 {
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
}

.help-footer {
  margin-top: 24px;
  color: var(--muted);
}

/* Share page: title, pills and author on the left; downloads and rating in a
   right-hand rail at desktop widths, under the header on phones. The edition
   art is the page background (themes.css), not a band here. */
.share-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "head" "rail" "main";
  column-gap: 28px;
}

.share-head {
  grid-area: head;
  min-width: 0;
}

.share-rail {
  grid-area: rail;
  min-width: 0;
}

.share-main {
  grid-area: main;
  min-width: 0;
}

@media (min-width: 960px) {
  .share-layout {
    grid-template-columns: minmax(0, 1fr) 240px;
    grid-template-areas: "head rail" "main rail";
  }
  .builtin-view.share-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "head" "main";
  }
  .share-rail {
    align-self: start;
    position: sticky;
    z-index: var(--z-sticky);
    top: 16px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-top: 12px;
    box-shadow: var(--shadow);
  }
  .share-rail .stats {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  .share-rail .rating {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }
  .share-rail .rating .button {
    justify-content: center;
  }
}

.title-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 16px;
}

.title-row h1 {
  flex: 1 1 auto;
  min-width: 0;
}

.rotation-id {
  margin-left: auto;
  font-size: 14px;
  color: var(--text);
  background: none;
  border: 0;
  padding: 0;
  white-space: nowrap;
}

a.tag {
  text-decoration: none;
}

a.tag:hover,
a.tag:focus-visible {
  border-color: var(--azure);
  color: var(--azure);
}

.share-version {
  color: var(--muted);
  font-size: 14px;
  margin: 4px 0;
}

.format-line {
  color: var(--muted);
  font-size: 14px;
}

.builtin-card h3 .rotation-id {
  font-size: 13px;
  font-weight: normal;
  margin-left: 6px;
  color: var(--muted);
}

.builtin-disabled {
  opacity: 0.85;
}

.builtins-link {
  margin: 0 0 12px;
}

.share-head h1 {
  margin-bottom: 4px;
  overflow-wrap: anywhere;
}

.share-description {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 4px 18px;
  margin: 16px 0;
}

/* An export string (inside .share-export a little air above the hint): lines of 76 characters (codec/wrap.mjs) in the system monospace stack, never re-wrapped by the
   browser, no ligatures; a long line scrolls inside the box, never the page. */
textarea.export-box {
  font: 13px/1.45 var(--mono);
  font-variant-ligatures: none;
  white-space: pre;
  overflow-wrap: normal;
  word-break: normal;
  overflow-x: auto;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
}

.share-export textarea.export-box {
  margin-top: 4px;
}

.facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 4px 16px;
  margin: 8px 0 16px;
}

.facts dt {
  color: var(--muted);
}

.facts dd {
  margin: 0;
  overflow-wrap: break-word;
}

.kind-line {
  font-size: 17px;
}

.source {
  border-top: 1px solid var(--line);
  margin-top: 16px;
}

.code-block summary {
  cursor: pointer;
  color: var(--muted);
  font: 13px var(--mono);
  margin: 8px 0 4px;
}

.code-block pre {
  max-height: 480px;
}

.share-manage {
  margin-top: 32px;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}

.report summary {
  cursor: pointer;
  color: var(--muted);
}

.loading {
  color: var(--muted);
}

/* Theme ornaments are SVG masks, so the theme color applies. Without mask
   support they are simply not drawn. */
@supports (mask-image: none) or (-webkit-mask-image: none) {
  hr::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    width: 96px;
    height: 12px;
    margin-left: -48px;
    background-color: var(--gold);
    -webkit-mask: var(--theme-divider) center / contain no-repeat;
    mask: var(--theme-divider) center / contain no-repeat;
  }
  .share-head .crumbs::before {
    content: "";
    display: inline-block;
    width: 1.3em;
    height: 1.3em;
    margin-right: 6px;
    vertical-align: -0.3em;
    background-color: var(--gold);
    -webkit-mask: var(--theme-emblem) center / contain no-repeat;
    mask: var(--theme-emblem) center / contain no-repeat;
  }
}

/* Rotation views and share pages: the site owns layout. */
.share-visual button {
  min-height: 40px;
  border-radius: var(--radius);
}

.result {
  color: var(--text);
}

/* The main links, the More menu and the Menu button: site/nav-fit.js measures and sets data-nav-fit on <html>.
     full  every link is in the row                          (the menu is hidden)
     some  the links that fit are in the row, the rest in the menu, whose button reads "More" (the entries of the links
           in the row are hidden by the script)
     menu  too few fit: every link is in the menu, whose button is the hamburger (what a phone gets)
   Without the script (no script, or before it has run) every link folds into the hamburger below 1560px, earlier than
   any language needs; wider, every link is in the row. */
html[data-nav-fit="some"] .nav-menu,
html[data-nav-fit="probe"] .nav-menu,
html[data-nav-fit="menu"] .nav-menu {
  display: block;
}

html[data-nav-fit="menu"] .main-nav,
html[data-nav-fit="probe"] .main-nav {
  display: none;
}

/* "More": the button reads like one of the row's links, beside the last one, with a caret. */
html[data-nav-fit="some"] .nav-menu > summary,
html[data-nav-fit="probe"] .nav-menu > summary {
  width: auto;
  height: auto;
  min-height: 40px;
  padding: 0 8px 0 10px;
  gap: 4px;
  border-color: transparent;
  font-size: 16px;
}

html[data-nav-fit="some"] .nav-more-text,
html[data-nav-fit="probe"] .nav-more-text {
  display: inline;
}

html[data-nav-fit="some"] .nav-menu .caret,
html[data-nav-fit="probe"] .nav-menu .caret {
  display: inline-block;
}

html[data-nav-fit="some"] .nav-menu > summary > .icon:first-child,
html[data-nav-fit="probe"] .nav-menu > summary > .icon:first-child {
  display: none;
}

html[data-nav-fit="some"] .nav-menu[open] .caret {
  transform: rotate(180deg);
}

/* The current page is in the menu: the button wears the links' current-page mark. */
.nav-menu[data-has-current] > summary {
  color: var(--gold);
}

html[data-nav-fit="some"] .nav-menu[data-has-current] > summary {
  box-shadow: inset 0 -2px 0 var(--gold);
  border-radius: 0;
}

/* In the hamburger state the button sits with the controls, as it always has: right of the brand, left of Discord. */
html[data-nav-fit="menu"] .nav-menu {
  margin-left: auto;
  margin-right: calc(var(--act-gap) - var(--hdr-gap));
}

html[data-nav-fit="menu"] .header-actions {
  margin-left: 0;
  flex: 0 1 auto;
}

@media (max-width: 1559px) {
  html:not([data-nav-fit]) .main-nav {
    display: none;
  }
  html:not([data-nav-fit]) .nav-menu {
    display: block;
    margin-left: auto;
    margin-right: calc(var(--act-gap) - var(--hdr-gap));
  }
  html:not([data-nav-fit]) .header-actions {
    margin-left: 0;
    flex: 0 1 auto;
  }
}

/* (the bell needs the phone header from 640px, not 520px) */
@media (max-width: 640px) {
  .brand span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .account-button .badge {
    display: none;
  }
  /* The account name takes what is left of the row and shortens with an ellipsis. */
  .header-actions {
    flex: 1 1 auto;
    justify-content: flex-end;
  }
  .account-menu {
    min-width: 0;
    flex: 0 1 auto;
  }
  .account-button {
    max-width: 100%;
    min-width: 0;
    padding: 0 4px 0 8px;
  }
  .lang-menu > summary {
    padding: 0 6px;
  }
}

@media (max-width: 1000px) {
  .help-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }
  .help-outline {
    display: none;
  }
  .help-nav {
    position: static;
    max-height: none;
  }
  .help-nav summary {
    display: block;
    cursor: pointer;
    color: var(--azure);
    padding: 8px 0;
  }
  .filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .filters label:first-child {
    grid-column: 1 / -1;
  }
}

/* The hero's two columns need room for the heading beside the mark: below 900px it is one column. */
@media (max-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
  }
  .hero::before {
    display: none;
  }
}

@media (max-width: 720px) {
  .header-inner {
    --hdr-gap: 8px;
    --act-gap: 6px;
    padding-left: 12px;
    padding-right: 12px;
  }
  .account-button {
    max-width: 120px;
  }
  .filters {
    grid-template-columns: minmax(0, 1fr);
  }
  .facts {
    grid-template-columns: minmax(0, 1fr);
  }
  .facts dd {
    margin-bottom: 6px;
  }
  main {
    padding-top: 16px;
  }
}

/* Import warnings */
.risk-panel {
  border: 2px solid var(--danger);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 6px 18px 10px;
  margin: 16px 0;
}

.risk-panel h2 {
  margin: 8px 0;
  font-size: 19px;
  color: var(--danger);
  text-transform: none;
  letter-spacing: normal;
}

.risk-panel.risk-none {
  border: 1px solid var(--ok);
}

.risk-panel.risk-none p {
  color: var(--ok);
  margin: 8px 0;
}

.risk-list {
  margin: 0;
  padding-left: 1.2em;
}

.risk-list li {
  margin: 8px 0;
}

.risk-danger strong {
  color: var(--danger);
}

.risk-caution strong {
  color: var(--warn);
}

.risk-info strong {
  color: var(--azure);
}

.risk-where {
  display: block;
  color: var(--muted);
  font-size: 14px;
  overflow-wrap: anywhere;
}

.tag-risk-danger {
  border-color: var(--danger);
  color: var(--danger);
}

.tag-risk-caution {
  border-color: var(--warn);
  color: var(--warn);
}

.tag-risk-info {
  color: var(--muted);
}

/* Fully decoded rotation tree */
.full-decode {
  margin-top: 20px;
}

.rotation-tree h4,
.rotation-tree h5 {
  color: var(--gold);
  margin: 18px 0 6px;
}

.steps {
  list-style: none;
  padding: 0;
  margin: 0;
}

.tree-step {
  border-left: 3px solid var(--azure);
  background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 6px 12px;
  margin: 8px 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

.tree-step.disabled {
  border-left-color: var(--line);
}

.tree-step.branch {
  border-left-color: var(--gold);
}

.cooldown-steps .tree-step {
  border-left-color: var(--ok);
}

.tree-step-head {
  margin: 2px 0 4px;
}

.step-index {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.cond-label {
  margin: 6px 0 2px;
  color: var(--muted);
  font-size: 14px;
}

.cond-tree {
  list-style: none;
  margin: 0;
  padding-left: 14px;
  border-left: 1px dashed var(--line);
}

.cond-tree > li {
  margin: 3px 0;
}

.rotation-tree > .cond-tree,
.tree-step > .cond-tree {
  border-left: 0;
  padding-left: 0;
}

.cond-op {
  color: var(--gold);
  font-weight: 600;
}

.cond-name {
  font-weight: 600;
}

.flag {
  color: var(--danger);
}

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

.arms {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 6px;
}

.arm {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 4px 8px;
  min-width: 0;
}

.arm-false {
  border-top: 3px solid var(--danger);
}

.arm-true {
  border-top: 3px solid var(--ok);
}

.arm-label {
  margin: 4px 0;
  font-weight: 600;
  font-size: 14px;
}

dl.kv {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 2px 12px;
  margin: 4px 0;
  font-size: 14px;
}

dl.kv dt {
  color: var(--muted);
}

dl.kv dd {
  margin: 0;
  overflow-wrap: break-word;
}

dl.kv.inline {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 2px 0 2px 2px;
}

dl.kv.inline dt::after {
  content: ":";
}

dl.kv.inline dt,
dl.kv.inline dd {
  display: inline;
}

dl.kv.inline dd {
  margin: 0 14px 0 4px;
}

dl.kv.inline > dd > dl.kv {
  display: grid;
}

.envelope-fields,
.profile-part {
  margin: 8px 0;
}

.envelope-fields summary,
.profile-part summary {
  cursor: pointer;
  color: var(--azure);
}

@media (max-width: 720px) {
  .arms {
    grid-template-columns: minmax(0, 1fr);
  }
  dl.kv:not(.inline) {
    grid-template-columns: minmax(0, 1fr);
  }
  dl.kv:not(.inline) dd {
    margin-bottom: 4px;
  }
}

/* ---- Community UI ------------------------------------------------------ */

/* Badges. .badge is a small neutral pill; .badge-mod and .badge-admin mark
   roles (with or without .badge). In the decoded tree's step heads .badge
   keeps its original inline-text look. */
.badge,
.badge-mod,
.badge-admin {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  line-height: 1.4;
  padding: 1px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--muted);
  white-space: nowrap;
  vertical-align: 1px;
}

.badge.warn {
  color: var(--warn);
  border-color: var(--warn);
  font-weight: 600;
}

.badge-mod {
  color: var(--mod);
  border-color: var(--mod);
  font-weight: 600;
}

.badge-admin {
  color: var(--admin);
  border-color: var(--admin);
  font-weight: 600;
}

.tree-step-head > .badge {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  white-space: normal;
  vertical-align: baseline;
}

/* Ratings: <div class="rating"><button class="vote-up" aria-pressed="false">…</button>
   <span class="score">12</span><button class="vote-down" aria-pressed="false">…</button></div>.
   Pressed shows as fill, a heavier border and bold text, not color alone. */
.rating {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.rating .score,
.rating output {
  min-width: 2ch;
  text-align: center;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.vote-up,
.vote-down {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 40px;
  min-height: 40px;
  padding: 4px 10px;
  margin: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  transition:
    background-color var(--motion),
    border-color var(--motion),
    color var(--motion);
}

.vote-up:hover {
  border-color: var(--ok);
  color: var(--ok);
}

.vote-down:hover {
  border-color: var(--danger);
  color: var(--danger);
}

.vote-up[aria-pressed="true"] {
  background: var(--ok-surface);
  border: 2px solid var(--ok);
  color: var(--ok);
  font-weight: 700;
}

.vote-down[aria-pressed="true"] {
  background: var(--danger-surface);
  border: 2px solid var(--danger);
  color: var(--danger);
  font-weight: 700;
}

.vote-up:disabled,
.vote-down:disabled {
  opacity: 0.55;
  cursor: default;
}

.vote-up .icon,
.vote-down .icon {
  width: 16px;
  height: 16px;
}

/* Small inline stats (downloads, comments, score) with an optional .icon. */
.stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  margin: 6px 0;
}

.stat {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--muted);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.stat .icon {
  width: 16px;
  height: 16px;
  vertical-align: -2px;
}

.stat strong,
.stat b {
  color: var(--text);
  font-weight: 600;
}

/* Comments */
.comments {
  margin: 32px 0 0;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}

ul.comments,
ol.comments,
.comments > ul,
.comments > ol {
  list-style: none;
  padding-left: 0;
}

.comments > ul,
.comments > ol {
  margin: 0;
}

.comment {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 10px 0;
  min-width: 0;
  overflow-wrap: anywhere;
  box-shadow: var(--shadow);
}

.comment > :last-child {
  margin-bottom: 4px;
}

.comment-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin: 0 0 4px;
  color: var(--muted);
  font-size: 14px;
}

.comment-meta strong,
.comment-meta .author-name {
  color: var(--text);
}

.comment-meta .flag-button {
  margin-left: auto;
}

.comment-held {
  background: var(--warn-surface);
  border: 1px dashed var(--warn);
  box-shadow: none;
}

.comment-form {
  max-width: none;
  margin: 16px 0;
}

.comment-form label {
  display: block;
  margin: 12px 0 6px;
  font-weight: 600;
}

.comment-form textarea {
  min-height: 96px;
  font-family: var(--font);
  font-size: var(--field-font-size);
}

/* Flag/report control: quiet until hovered or pressed. */
.flag-button {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  padding: 4px 8px;
  margin: 0;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition:
    color var(--motion),
    border-color var(--motion);
}

.flag-button:hover,
.flag-button[aria-pressed="true"] {
  color: var(--danger);
  border-color: var(--danger);
}

.flag-button:disabled {
  opacity: 0.55;
  cursor: default;
}

/* "Content hidden for review" */
.notice-hidden {
  position: relative;
  border: 2px dashed var(--warn);
  border-radius: var(--radius);
  background: var(--warn-surface);
  color: var(--text);
  padding: 12px 16px 12px 52px;
  margin: 16px 0;
}

.notice-hidden > :first-child {
  margin-top: 0;
}

.notice-hidden > :last-child {
  margin-bottom: 0;
}

.notice-hidden :is(h2, h3, strong:first-child) {
  color: var(--warn);
  text-transform: none;
  letter-spacing: normal;
}

.notice-hidden a {
  color: var(--text);
}

/* The big Lua warning */
.lua-warning {
  position: relative;
  border: 2px solid var(--danger);
  border-left-width: calc(var(--border-accent) * 2);
  border-radius: var(--radius);
  background: var(--danger-surface);
  color: var(--text);
  padding: 14px 18px 14px 64px;
  margin: 20px 0;
  box-shadow: var(--shadow);
}

.lua-warning > :first-child {
  margin-top: 0;
}

.lua-warning > :last-child {
  margin-bottom: 0;
}

.lua-warning :is(h2, h3, .lua-warning-title) {
  margin: 2px 0 8px;
  color: var(--danger);
  font-size: 21px;
  text-transform: none;
  letter-spacing: normal;
}

.lua-warning a {
  color: var(--text);
}

.lua-warning code {
  background: var(--code-bg);
}

/* Icons for the controls above (masks, so they take the text color). */
@supports (mask-image: none) or (-webkit-mask-image: none) {
  .flag-button::before,
  .notice-hidden::before,
  .lua-warning::before,
  .status-ok::before,
  .status-error::before {
    content: "";
    flex: none;
    background-color: currentColor;
    -webkit-mask: var(--icon) center / contain no-repeat;
    mask: var(--icon) center / contain no-repeat;
  }
  .flag-button::before {
    width: 14px;
    height: 14px;
    --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 2h2v20H5zM8 3h11l-2.5 4.5L19 12H8z'/%3E%3C/svg%3E");
  }
  .notice-hidden::before {
    position: absolute;
    left: 16px;
    top: 13px;
    width: 24px;
    height: 24px;
    background-color: var(--warn);
    --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M3.3 2l18.7 18.7-1.3 1.3-3.5-3.5A11 11 0 0 1 12 20C6.5 20 2.6 16 1 12c.8-2 2.2-4 4-5.4L2 3.3zM7 8a9 9 0 0 0-3.8 4c1.5 3 4.6 5.8 8.8 5.8 1.3 0 2.5-.3 3.6-.8l-2-2A3.5 3.5 0 0 1 9 10.4zM12 4c5.5 0 9.4 4 11 8-.6 1.5-1.6 3-2.8 4.2l-1.5-1.5a9 9 0 0 0 1.9-2.7C19.3 9 16.2 6.2 12 6.2c-.8 0-1.6.1-2.3.3L8 4.8C9.3 4.3 10.6 4 12 4z'/%3E%3C/svg%3E");
  }
  .lua-warning::before {
    position: absolute;
    left: 18px;
    top: 16px;
    width: 30px;
    height: 30px;
    background-color: var(--danger);
    --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.5l11.5 20H.5zM10.8 8.5h2.4l-.4 7h-1.6zM12 17a1.4 1.4 0 1 1 0 2.8 1.4 1.4 0 0 1 0-2.8z'/%3E%3C/svg%3E");
  }
  .status-ok::before,
  .status-error::before {
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-right: 6px;
    vertical-align: -0.15em;
  }
  .status-ok::before {
    --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.6 1.6L9 19.4 21 7.4l-1.6-1.6z'/%3E%3C/svg%3E");
  }
  .status-error::before {
    --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1a11 11 0 1 1 0 22 11 11 0 0 1 0-22zm-1.2 5v8h2.4V6zM12 15.6a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z'/%3E%3C/svg%3E");
  }
}

/* Author byline: display name, Discord name, BattleTag, optional character link. */
.author-card {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  max-width: 100%;
  min-width: 0;
  padding: 8px 12px;
  margin: 4px 0 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow-wrap: anywhere;
}

.author-card > * {
  margin: 0;
}

.author-card .author-name,
.author-card strong {
  color: var(--text);
  font-weight: 700;
}

.author-card .handle,
.author-card .discord-name,
.author-card .battletag {
  color: var(--muted);
  font-size: 14px;
}

.author-card .character {
  font-size: 14px;
}

.character-detail {
  color: var(--muted);
  font-size: 14px;
}

.character-list,
.profile-characters {
  list-style: none;
  margin: 0;
  padding: 0;
}

.character-list li,
.profile-characters li {
  margin: 4px 0;
}

.character-add {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

/* The source line beside Battle.net data (Blizzard's API terms): small, muted, plain. */
.source-note {
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
}

.author-card img {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  align-self: center;
}

/* Admin and moderation. Wrap a wide .table in .table-wrap; cells also break
   anywhere so even an unwrapped table never pushes the page sideways. */
.table-wrap {
  max-width: 100%;
  overflow-x: auto;
  margin: 12px 0;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  background: var(--surface);
}

.table caption {
  caption-side: top;
  text-align: left;
  color: var(--muted);
  padding: 6px 0;
}

.table th,
.table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
  overflow-wrap: break-word;
}

/* Words and identifiers never break inside: a table too wide for the screen scrolls in its wrapper. */
.table-wrap {
  overflow-x: auto;
}

.table thead th {
  background: var(--surface-2);
  color: var(--text);
  font-weight: 600;
  border-bottom: 2px solid var(--line-strong);
}

.table tbody tr:hover {
  background: var(--surface-2);
}

.table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.table .actions {
  gap: 6px;
}

.queue {
  list-style: none;
  padding: 0;
  margin: 0;
}

.queue-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: var(--border-accent) solid var(--warn);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin: 12px 0;
  min-width: 0;
  overflow-wrap: anywhere;
  box-shadow: var(--shadow);
}

.queue-item.resolved {
  border-left-color: var(--ok);
}

.queue-item :is(h2, h3) {
  margin: 0 0 6px;
  font-size: 17px;
  text-transform: none;
  letter-spacing: normal;
}

.queue-item .actions {
  margin-top: 10px;
}

/* Long legal prose (terms, privacy) */
.legal {
  overflow-wrap: break-word;
}

.legal.prose {
  max-width: none;
}

.legal > * {
  max-width: 72ch;
}

.legal p,
.legal li {
  line-height: 1.7;
}

.legal h2 {
  font-size: 20px;
  margin-top: 36px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
  text-transform: none;
  letter-spacing: normal;
}

.legal h3 {
  font-size: 17px;
}

.legal ol,
.legal ul {
  padding-left: 1.4em;
}

.legal li {
  margin: 6px 0;
}

/* Account settings */
.account-section {
  max-width: none;
  margin: 20px 0;
  padding: 4px 20px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  min-width: 0;
}

.account-section > :is(h2, h3) {
  margin-top: 16px;
  font-size: 20px;
}

.account-section label {
  display: block;
  margin: 14px 0 6px;
  font-weight: 600;
}

.account-section input:not([type="checkbox"]):not([type="radio"]),
.account-section select {
  width: 100%;
  max-width: 480px;
}

.account-id {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.account-id code {
  font-size: 1.15em;
  padding: 4px 8px;
  overflow-wrap: anywhere;
  white-space: normal;
  display: inline;
}

.danger-zone {
  max-width: none;
  margin: 32px 0;
  padding: 4px 20px 16px;
  background: var(--danger-surface);
  border: 2px solid var(--danger);
  border-radius: var(--radius-lg);
  min-width: 0;
}

.danger-zone > :is(h2, h3) {
  margin-top: 16px;
  color: var(--danger);
  text-transform: none;
  letter-spacing: normal;
}

/* Status messages: color plus an icon. Block elements also get a panel. */
.status-ok {
  color: var(--ok);
  font-weight: 600;
}

.status-error {
  color: var(--danger);
  font-weight: 600;
}

:is(p, div, li).status-ok,
:is(p, div, li).status-error {
  padding: 8px 12px;
  border: 1px solid currentColor;
  border-radius: var(--radius);
}

:is(p, div, li).status-ok {
  background: var(--ok-surface);
}

:is(p, div, li).status-error {
  background: var(--danger-surface);
}

@media (max-width: 480px) {
  .lua-warning {
    padding: 54px 14px 14px;
  }
  .lua-warning::before {
    left: 14px;
    top: 14px;
  }
  .notice-hidden {
    padding: 46px 14px 12px;
  }
  .notice-hidden::before {
    left: 14px;
    top: 12px;
  }
  .account-section,
  .danger-zone {
    padding-left: 14px;
    padding-right: 14px;
  }
}

/* Windows high contrast: system colors replace the theme; keep the mask
   icons and ornaments visible by painting them in the text color. */
@media (forced-colors: active) {
  hr::after,
  .share-head .crumbs::before,
  .flag-button::before,
  .notice-hidden::before,
  .lua-warning::before,
  .status-ok::before,
  .status-error::before {
    forced-color-adjust: none;
    background-color: CanvasText;
  }
}

/* Reduced motion: no decorative animation or transition anywhere
   (themes.css also zeroes --motion). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* The tint alone meets AA; blur is optional, never a contrast dependency. */
@supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))) {
  .site-header,
  .site-footer {
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
  }
}

/* The rotation as Rotation Master draws it (site/rotation-view.mjs): cards placed by the addon's canvas geometry,
   connectors and arm labels in the addon's meanings (green = true/enabled, red = false/Unless, amber = a problem or
   All/Any, gray = off). Every color is a theme token, so the canvas follows light and dark and every edition theme:
   the canvas is the code-block surface, a card is a surface of its own, the meanings are --ok, --danger, --warn and
   the muted ink, all of them AA text colors on both (tests/web_rotation_colors.mjs measures every theme and mode). */
.rotation-view {
  margin: 16px 0;
}

.share-visual .rotation-view button,
.rotation-view button {
  min-height: 0;
  border-radius: 0;
}

.share-visual .rotation-view .rv-mode,
.share-visual .rotation-view .rv-zoom-button {
  min-height: 32px;
}

.share-visual .rotation-view .rv-tab {
  border-radius: var(--radius) var(--radius) 0 0;
}

.share-visual .rotation-view .rv-arm {
  border-radius: 3px;
}

.rv-switch {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 8px 14px;
  margin-bottom: 10px;
}

.rv-switch-heading {
  margin: 0 0 4px;
  font-size: 15px;
}

.rv-switch-text {
  margin: 0;
  overflow-wrap: anywhere;
}

.rv-switch-text .game-link {
  color: inherit;
}

.rv-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 8px;
}

.rv-tabs {
  display: flex;
  gap: 2px;
}

.rv-tab {
  border: 1px solid var(--line-strong);
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--surface-2);
  color: var(--text);
  padding: 6px 14px;
  font: inherit;
  cursor: pointer;
}

.rv-tab:hover {
  background: var(--surface);
}

/* The selected tab is the canvas's own color with the gold edge on top: it reads as joined to the panel below it. */
.rv-tab[aria-selected="true"] {
  background: var(--code-bg);
  color: var(--text);
  border-color: var(--line-strong);
  box-shadow: inset 0 3px 0 var(--gold);
  font-weight: 700;
}

.rv-modes {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-bottom: 4px;
}

.rv-segmented,
.rv-zoom {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  overflow: hidden;
}

.rv-mode,
.rv-zoom-button {
  border: 0;
  background: var(--surface);
  color: var(--text);
  padding: 4px 10px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  min-height: 32px;
}

.rv-mode:hover,
.rv-zoom-button:hover {
  background: var(--surface-2);
}

.rv-mode + .rv-mode,
.rv-zoom-button + .rv-zoom-button {
  border-left: 1px solid var(--line-strong);
}

.rv-mode[aria-pressed="true"] {
  background: var(--azure);
  color: var(--on-accent);
}

.rv-canvas {
  position: relative;
  overflow: auto;
  max-height: 78vh;
  min-height: 120px;
  background: var(--code-bg);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: 0 var(--radius) var(--radius) var(--radius);
  padding: 12px;
}

.rv-canvas:focus-visible {
  outline: 2px solid var(--azure);
  outline-offset: 2px;
}

.rv-sizer {
  position: relative;
}

.rv-surface {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
}

.rv-lines {
  position: absolute;
  left: 0;
  top: 0;
  overflow: visible;
  pointer-events: none;
}

.rv-line {
  fill: none;
  stroke-width: 2;
  stroke-linejoin: round;
}

.rv-line.inactive {
  opacity: 0.35;
}

.rv-line.tone-green {
  stroke: var(--ok);
}

.rv-line.tone-red {
  stroke: var(--danger);
}

.rv-line.tone-amber {
  stroke: var(--warn);
}

.rv-line.tone-gray,
.rv-line.tone-neutral,
.rv-line.tone-white {
  stroke: var(--line-strong);
}

.rv-group {
  position: absolute;
  border: 1px solid;
  border-radius: 8px;
}

.rv-group.tone-green {
  border-color: var(--ok);
  background: color-mix(in srgb, var(--ok) 5%, transparent);
}

.rv-group.tone-red {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 5%, transparent);
}

.rv-group.tone-gray,
.rv-group.tone-neutral,
.rv-group.tone-white,
.rv-group.tone-amber {
  border-color: var(--line-strong);
}

.rv-arm {
  position: absolute;
  width: 100px;
  height: 18px;
  padding: 0 4px;
  border: 0;
  border-radius: 3px;
  background: var(--surface);
  font: 12px/18px var(--font, inherit);
  text-align: left;
  cursor: pointer;
}

.rv-arm.arm-true {
  color: var(--ok);
}

.rv-arm.arm-false {
  color: var(--danger);
}

.rv-arm.inactive {
  opacity: 0.55;
}

.rv-card {
  position: absolute;
  box-sizing: border-box;
  border: 1px solid;
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  line-height: 1.35;
  padding: 3px 8px 4px 24px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rv-card.tone-green {
  border-color: var(--ok);
}

.rv-card.tone-red {
  border-color: var(--danger);
}

.rv-card.tone-white,
.rv-card.tone-gray,
.rv-card.tone-neutral {
  border-color: var(--line-strong);
}

.rv-card.tone-amber {
  border-color: var(--warn);
}

.rv-card.inactive {
  opacity: 0.7;
}

.rv-card-head {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 22px;
}

.rv-title {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-weight: 700;
  text-align: left;
  padding: 0;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rv-card.compact .rv-title {
  font-weight: 600;
}

.rv-pill {
  flex: none;
  font-size: 11px;
  line-height: 16px;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  color: var(--muted);
}

.rv-pill.on {
  border-color: var(--ok);
  color: var(--ok);
}

.rv-action {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 20px;
}

.rv-icon {
  width: 18px;
  height: 18px;
  flex: none;
  border-radius: 3px;
  background: var(--surface-2);
}

.rv-cooldown {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  min-width: 0;
}

.rv-cooldown-text {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rv-card.cooldown .rv-cooldown > .rv-icon {
  width: 36px;
  height: 36px;
  margin-top: 2px;
}

.rv-action-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rv-cond {
  color: var(--muted);
  overflow-wrap: anywhere;
}

.rv-measure {
  position: absolute;
  left: -10000px;
  top: 0;
  visibility: hidden;
}

.rv-measure .rv-card {
  position: static;
  height: auto;
  overflow: visible;
}

.rv-empty {
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  color: var(--muted);
}

.game-link {
  color: var(--azure);
  text-decoration: none;
}

.game-link:hover,
.game-link:focus-visible {
  text-decoration: underline;
}

.game-link.loading {
  text-decoration: underline dotted;
} /* no opacity: a link that never resolves (the tooltip script blocked) must stay AA */
/* The game's own color codes (|cAARRGGBB) in a condition's words (site/wow-text.mjs sets --wow): the game draws them on
   dark panels, so on a light surface the color keeps its hue and is darkened to a readable lightness, and on a dark
   one lightened, the same way. Browsers without relative colors show the code's color as it is. */
.wow-c.wow-c {
  color: var(--wow);
} /* doubled: a colored link beats the rules that make links inherit */
@supports (color: light-dark(red, blue)) and (color: oklch(from red min(l, 0.5) c h)) {
  .wow-c.wow-c {
    color: light-dark(oklch(from var(--wow) min(l, 0.46) c h), oklch(from var(--wow) max(l, 0.76) c h));
  }
}

/* Wowhead's tooltip script (site/wowhead-power.mjs) iconizes links itself; a
   card already shows its icon and the game's condition text has none, so its
   inline icons stay hidden in the rotation view (the cards read them). */
.rotation-view .game-link [class^="icon"],
.rotation-view .game-link[data-wh-icon-added] {
  background-image: none !important;
  padding-left: 0 !important;
}

.rotation-view .game-link [class^="icon"] {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .rv-surface {
    transition: none;
  }
}

/* Achievements (site/achievements.mjs). The tier sets one color, used for the
   badge ring, the glyph and the tier label: gold, silver (muted) and bronze
   (warn), all AA text colors in every theme. Locked ones are drawn in lines. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.achievement-gold {
  --tier: var(--gold);
}

.achievement-silver {
  --tier: var(--muted);
}

.achievement-bronze {
  --tier: var(--warn);
}

.achievement-list {
  list-style: none;
  padding: 0;
  margin: 12px 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: 10px;
}

.achievement {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 12px;
  min-width: 0;
}

.achievement-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 3px solid var(--tier);
  color: var(--tier);
  background: var(--surface-2);
}

.achievement-badge .icon {
  width: 24px;
  height: 24px;
  vertical-align: 0;
}

.achievement.is-locked .achievement-badge {
  border-style: dashed;
  border-color: var(--line-strong);
  color: var(--muted);
  background: none;
}

.achievement-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow-wrap: break-word;
}

.achievement-name {
  color: var(--text);
}

.achievement-tier {
  font-size: 12px;
  font-weight: 600;
  color: var(--tier);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.achievement.is-locked .achievement-tier {
  color: var(--muted);
}

.achievement-desc {
  font-size: 14px;
  color: var(--text);
}

.achievement-meta {
  font-size: 13px;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.achievement-meta progress {
  width: 96px;
  height: 8px;
  accent-color: var(--azure);
}

.achievement-strip {
  margin: 0 0 16px;
}

.achievement-strip ul {
  list-style: none;
  padding: 0;
  margin: 0 0 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.achievement-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  padding: 2px 10px 2px 2px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
}

.achievement-chip .achievement-badge {
  width: 26px;
  height: 26px;
  border-width: 2px;
}

.achievement-chip .achievement-badge .icon {
  width: 15px;
  height: 15px;
}

.content-hash code {
  font-size: 12px;
  overflow-wrap: anywhere;
  white-space: normal;
  display: inline;
}

.queue-duplicate {
  border-left-color: var(--azure);
}

/* Notifications: the header bell (the size of the other icon buttons, so the
   header stays one row; the unread count is a badge over its corner) and the
   /notifications list. */
.bell {
  position: relative;
  flex: none;
}

.bell[aria-current="page"] {
  color: var(--gold);
  border-color: var(--gold);
}

.bell-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--danger);
  color: var(--on-danger);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  box-sizing: border-box;
  pointer-events: none;
}

/* The bell adds a button to the row: the account name gives up some width to keep it one row. */
@media (min-width: 721px) and (max-width: 900px) {
  .account-button {
    max-width: 150px;
  }
}

@media (max-width: 520px) {
  .bell {
    width: 34px;
  }
  .header-inner {
    --act-gap: 4px;
  }
}

.notification-list {
  list-style: none;
  margin: 12px 0;
  padding: 0;
}

.notification {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 8px 0;
  min-width: 0;
  overflow-wrap: break-word;
  box-shadow: var(--shadow);
}

.notification.is-new {
  border-left: 4px solid var(--azure);
}

.notification p {
  margin: 0;
}

.notification-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  margin-top: 4px;
  color: var(--muted);
  font-size: 14px;
}

.notification-new {
  color: var(--azure);
  border-color: var(--azure);
  font-weight: 600;
}

.notification:target {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* The bell's drop-down (site/bell.mjs): a popover under the bell, on the header's layer (above sticky sidebars and the
   editor, the same as the header's menus; only one of them is open at a time). On a phone it spans the page under the
   header instead, so it can never run off the screen. Without script the bell is a link and none of this exists. */
.exports-section {
  margin: 20px 0;
}

.bell-menu {
  position: relative;
  flex: none;
  display: inline-flex;
}

button.bell {
  font: inherit;
}

.bell-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: var(--z-popover);
  box-sizing: border-box;
  width: min(380px, calc(100vw - 16px));
  max-height: min(70vh, 520px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
  font-size: 15px;
}

.bell-panel[hidden] {
  display: none;
}

.bell-head,
.bell-status,
.bell-more,
.bell-foot {
  flex: none;
}

.bell-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 8px 6px 14px;
  border-bottom: 1px solid var(--line);
}

.bell-head h2 {
  margin: 0;
  font-size: 16px;
}

.bell-head .link-button {
  min-height: var(--field-height);
  padding: 0 8px;
}

.bell-head .link-button:disabled {
  color: var(--muted);
  text-decoration: none;
  cursor: default;
}

.bell-status {
  margin: 0;
  padding: 10px 14px;
  color: var(--muted);
}

.bell-status:empty {
  display: none;
}

.bell-list {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.bell-list li + li {
  border-top: 1px solid var(--line);
}

.bell-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  color: var(--text);
  text-decoration: none;
  border-inline-start: 4px solid var(--azure);
}

.bell-item:hover {
  background: var(--surface-2);
}

.bell-item:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.bell-item.is-read {
  border-inline-start-color: transparent;
  color: var(--muted);
}

.bell-icon {
  flex: none;
  margin-top: 1px;
  color: var(--azure);
}

.bell-item.is-read .bell-icon {
  color: var(--muted);
}

.bell-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}

.bell-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
  overflow-wrap: anywhere;
  line-height: 1.35;
}

.bell-time {
  color: var(--muted);
  font-size: 13px;
}

.bell-more {
  margin: 0;
  padding: 8px 14px;
  border-top: 1px solid var(--line);
}

.bell-foot {
  margin: 0;
  border-top: 1px solid var(--line);
}

.bell-foot a {
  display: block;
  padding: 11px 14px;
  text-align: center;
  font-weight: 600;
}

.bell-foot a:hover {
  background: var(--surface-2);
}

.bell-foot a:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

@media (max-width: 720px) {
  .bell-menu {
    position: static;
  }
  .bell-panel {
    left: 8px;
    right: 8px;
    top: calc(100% + 4px);
    width: auto;
    max-width: none;
    max-height: calc(100vh - 90px);
  }
}

/* Public profiles and replies. */
.profile-since {
  color: var(--muted);
  margin: 0 0 12px;
}

.profile-accounts {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
}

.profile section > h2 {
  margin-top: 28px;
}

.profile-comment-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.profile-comment {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 10px 0;
  min-width: 0;
  overflow-wrap: break-word;
  box-shadow: var(--shadow);
}

.profile-comment p {
  margin: 0 0 4px;
}

.reply-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  margin: 12px 0 0;
  padding: 6px 10px;
  border-left: 4px solid var(--azure);
  background: var(--surface-2);
}

.reply-banner[hidden] {
  display: none;
}

.comment .reply-to {
  font-size: 13px;
}

[hidden] {
  display: none !important;
}

/* Compare (/compare, /viewer): two slots, each a share, a Built In or a pasted export, then both rotations side by side
   with the differences marked and listed. Same content width as every page; the columns shrink, the page does not. */
.compare {
  min-width: 0;
}

.compare-slots,
.cmp-views {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  align-items: start;
}

.compare-slot {
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 4px 16px 16px;
  box-shadow: var(--shadow);
}

.slot-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
}

.slot-head h2 {
  margin: 12px 0 4px;
  font-size: 20px;
}

.slot-edit {
  min-height: 34px;
  padding: 3px 12px;
  font-size: 14px;
}

.slot-chosen {
  margin: 4px 0 10px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.slot-source {
  border: 0;
  padding: 0;
  margin: 0 0 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}

.slot-source-choice {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-weight: 600;
}

.picker-filters {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0 0 8px;
}

.picker-filters label:first-child,
.picker-filters button {
  grid-column: 1 / -1;
}

.picker-filters button {
  justify-self: start;
}

.picker-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 320px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.picker-list:empty {
  display: none;
}

.picker-list li + li {
  border-top: 1px solid var(--line);
}

.picker-choice {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  padding: 8px 10px;
  cursor: pointer;
}

.picker-choice:hover {
  background: var(--surface-2);
}

.picker-choice input {
  align-self: center;
  min-height: 0;
}

.pick-title {
  font-weight: 600;
}

.pick-meta {
  font-size: 13px;
}

.picker-pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.slot-panel textarea {
  width: 100%;
}

.compare-actions {
  margin: 16px 0;
}

.compare-result {
  min-width: 0;
  margin-top: 8px;
}

.cmp-view {
  min-width: 0;
}

.cmp-view h3 {
  margin: 16px 0 8px;
  font-size: 17px;
  overflow-wrap: anywhere;
}

.cmp-summary {
  margin: 8px 0 12px;
}

.cmp-counts {
  font-weight: 600;
}

.cmp-changes {
  margin-top: 28px;
}

.cmp-change-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 10px;
}

.cmp-change {
  border: 1px solid var(--line);
  border-left: 4px solid var(--diff-color, var(--line));
  border-radius: var(--radius);
  background: var(--surface);
  padding: 8px 14px;
  min-width: 0;
}

.cmp-change-head {
  margin: 0;
  overflow-wrap: anywhere;
}

.cmp-details {
  margin: 4px 0 2px;
  padding-left: 1.3em;
}

.cmp-details li {
  margin: 2px 0;
  overflow-wrap: anywhere;
}

.cmp-tag {
  display: inline-block;
  padding: 0 8px;
  border-radius: 999px;
  border: 1px solid var(--diff-color, var(--line));
  font-size: 13px;
  font-weight: 700;
}

.diff-added {
  --diff-color: var(--ok);
}

.diff-removed {
  --diff-color: var(--danger);
}

.diff-changed {
  --diff-color: var(--warn);
}

.diff-moved {
  --diff-color: var(--azure);
}

.cmp-tag.diff-added {
  color: var(--diff-color);
}

.cmp-tag.diff-removed {
  color: var(--diff-color);
}

.cmp-tag.diff-changed {
  color: var(--diff-color);
}

.cmp-tag.diff-moved {
  color: var(--diff-color);
}

/* Marks on the rotation views: a stripe, an outline and a label on each card that differs. */
.rv-card.diff {
  box-shadow: inset 4px 0 0 var(--diff-color);
  border-color: var(--diff-color);
}

.rv-card.diff-removed {
  opacity: 0.85;
}

.rv-diff-badge {
  flex: none;
  padding: 0 7px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--diff-color);
  color: var(--diff-color);
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
}

.rv-switch.diff {
  border-left: 4px solid var(--diff-color);
}

.rv-tab-badge {
  margin-left: 2px;
  padding: 0 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--warn) 25%, transparent);
  font-size: 11px;
  font-weight: 700;
}

@media (max-width: 900px) {
  .compare-slots,
  .cmp-views {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 720px) {
  .picker-filters {
    grid-template-columns: minmax(0, 1fr);
  }
}

.app-screenshot { margin: 24px auto; max-width: 860px; }
.app-screenshot a { display: block; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; line-height: 0; }
.app-screenshot a:focus-visible { outline: 3px solid var(--azure); outline-offset: 3px; }
.app-screenshot img { display: block; width: 100%; height: auto; }
.app-screenshot figcaption { color: var(--muted); font-size: 0.875rem; line-height: 1.5; margin-top: 8px; }
.app-screenshot figcaption span { white-space: nowrap; }

/* An in-page view of the full-size screenshot; no upscaling beyond its intrinsic dimensions. */
.screenshot-dialog { padding: 0; border: 0; max-width: calc(100vw - 32px); max-height: calc(100dvh - 32px); overflow: visible; background: transparent; }
.screenshot-dialog::backdrop { background: rgba(0, 0, 0, .85); }
.screenshot-dialog img { display: block; width: auto; height: auto; max-width: calc(100vw - 32px); max-height: calc(100dvh - 32px); cursor: zoom-out; }
.screenshot-dialog-close { position: absolute; top: 8px; right: 8px; z-index: 1; width: 40px; height: 40px; border: 1px solid #fff; border-radius: 50%; background: #111; color: #fff; font-size: 28px; line-height: 1; cursor: pointer; }
