
:root {
  --bg: #09090b; --surface: #121214; --elevated: #1c1c20;
  --fg: #f4f0ea; --muted: #9a958c; --subtle: #6b6760;
  --accent: #e11d2e; --border: #2a2926;
  --honor: #8a9bb0; --ruthless: #e11d2e; --ambiguous: #c4a574; --evil: #6f8f5a; --undeclared: #6b6760;
  --display: "Bebas Neue", "Arial Narrow", Impact, sans-serif;
  --sans: "Barlow", "Segoe UI", system-ui, sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
.kicker { font-size: 0.68rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); margin: 0; }
.wrap { max-width: 80rem; margin: 0 auto; padding: 2rem 1rem 4rem; }
@media (min-width: 640px) { .wrap { padding-left: 1.5rem; padding-right: 1.5rem; } }
.page-title { font-family: var(--display); font-size: clamp(2.8rem, 2rem + 4vw, 4.5rem); letter-spacing: 0.08em; margin: 0.2rem 0 0; font-weight: 400; }
.essay { font-size: clamp(1.05rem, 0.95rem + 0.4vw, 1.2rem); line-height: 1.65; }
.zine-title { font-family: var(--display); font-size: clamp(2.4rem, 1.2rem + 4vw, 5rem); line-height: 0.92; letter-spacing: 0.03em; font-weight: 400; margin: 0.4rem 0 0; }
.hero-mark { font-family: var(--display); font-size: clamp(3.6rem, 1rem + 8vw, 8rem); line-height: 0.82; letter-spacing: 0.08em; margin: 0; font-weight: 400; white-space: nowrap; }
.btn { display: inline-flex; height: 3rem; align-items: center; justify-content: center; border-radius: 8px; background: var(--accent); color: var(--fg); padding: 0 1.5rem; font-size: 0.85rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; border: 0; }
.btn:active { transform: scale(0.96); }
.link-k { font-size: 0.85rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; text-underline-offset: 4px; }
.link-k:hover { text-decoration: underline; }
.badge { display: inline-flex; border: 1px solid; padding: 0.15rem 0.5rem; font-size: 0.62rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.honorable { color: var(--honor); border-color: color-mix(in srgb, var(--honor) 40%, transparent); }
.ambiguous { color: var(--ambiguous); border-color: color-mix(in srgb, var(--ambiguous) 40%, transparent); }
.ruthless { color: var(--ruthless); border-color: color-mix(in srgb, var(--ruthless) 50%, transparent); }
/* Morality has four values. The supplied design defined three, so `evil`
   gets its own token here -- a sickly green that reads as its own thing
   rather than a darker shade of ruthless. */
.evil { color: var(--evil); border-color: color-mix(in srgb, var(--evil) 45%, transparent); }
.undeclared { color: var(--undeclared); border-color: var(--border); }

.site-head { position: sticky; top: 0; z-index: 30; border-bottom: 1px solid var(--border); background: color-mix(in srgb, var(--bg) 90%, transparent); }
.head-row { max-width: 80rem; margin: 0 auto; height: 3.5rem; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0 1rem; }
@media (min-width: 640px) { .head-row { padding: 0 1.5rem; } }
.wordmark { font-family: var(--display); font-size: 1.5rem; letter-spacing: 0.22em; }
.nav-desk { display: none; align-items: center; gap: 0.15rem; }
/* .nav-m was the old horizontal scroller, replaced by the hamburger panel
   below. The rule is gone rather than left dead. */
@media (min-width: 768px) { .nav-desk { display: flex; } .only-m { display: none !important; } }
.nav-link { flex: 0 0 auto; padding: 0.5rem 0.75rem; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.nav-link.is-on, .nav-link:hover { color: var(--fg); }
.apply-link { flex: 0 0 auto; border: 1px solid color-mix(in srgb, var(--accent) 60%, transparent); border-radius: 8px; padding: 0.45rem 0.75rem; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; }
.apply-link.is-on { background: var(--accent); border-color: var(--accent); }
.site-foot { border-top: 1px solid var(--border); }
.foot-row { max-width: 80rem; margin: 0 auto; padding: 2rem 1rem; display: flex; flex-direction: column; gap: 1rem; }
@media (min-width: 640px) { .foot-row { flex-direction: row; align-items: flex-end; justify-content: space-between; padding: 2rem 1.5rem; } }
.foot-lede { max-width: 22rem; color: var(--muted); font-size: 0.9rem; }
.foot-meta { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--subtle); }

.hero { position: relative; min-height: calc(100dvh - 3.5rem); overflow: hidden; }
.hero img.fill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero .veil { position: absolute; inset: 0; background: linear-gradient(to top, var(--bg), color-mix(in srgb, var(--bg) 55%, transparent), color-mix(in srgb, var(--bg) 20%, transparent)); }
.hero .copy { position: relative; z-index: 1; max-width: 80rem; margin: 0 auto; min-height: calc(100dvh - 3.5rem); display: flex; flex-direction: column; justify-content: flex-end; padding: 0 1rem 3rem; }
.band { border-block: 1px solid var(--border); background: var(--surface); }
.grid-2 { display: grid; gap: 2.5rem; }
@media (min-width: 1024px) { .grid-2 { grid-template-columns: 1fr 1fr; } }
.promo-split { display: grid; gap: 2rem; }
@media (min-width: 1024px) { .promo-split { grid-template-columns: 0.8fr 1.2fr; align-items: center; } }
.frame { position: relative; aspect-ratio: 3/4; overflow: hidden; border-radius: 10px; background: var(--elevated); }
.frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.quote-band { position: relative; min-height: 28rem; overflow: hidden; }
.quote-band img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.quote-band .veil { position: absolute; inset: 0; background: color-mix(in srgb, var(--bg) 70%, transparent); }
.quote-band .copy { position: relative; z-index: 1; max-width: 80rem; margin: 0 auto; min-height: 28rem; display: flex; flex-direction: column; justify-content: flex-end; padding: 3rem 1rem; }
blockquote { font-family: var(--display); font-size: clamp(2rem, 1rem + 4vw, 3.75rem); letter-spacing: 0.05em; margin: 1rem 0 0; }
.roster-strip { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0.75rem; }
@media (min-width: 640px) { .roster-strip { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 1024px) { .roster-strip { grid-template-columns: repeat(7, minmax(0,1fr)); } }
.roster-strip a { position: relative; display: block; aspect-ratio: 2/3; overflow: hidden; border-radius: 8px; background: var(--elevated); }
.roster-strip img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; transition: transform 500ms; }
.roster-strip a:hover img { transform: scale(1.05); }
.roster-strip .cap { position: absolute; inset: auto 0 0 0; padding: 0.5rem; background: linear-gradient(to top, var(--bg), transparent); }
.clock { display: flex; gap: 0.75rem; }
.clock li { list-style: none; min-width: 3rem; text-align: center; }
.clock b { display: block; font-family: var(--display); font-size: 1.9rem; letter-spacing: 0.08em; font-weight: 400; }

.promo-card { display: grid; overflow: hidden; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
@media (min-width: 640px) { .promo-card { grid-template-columns: 8rem 1fr; } }
.promo-card .pic { position: relative; aspect-ratio: 3/4; }
@media (min-width: 640px) { .promo-card .pic { aspect-ratio: auto; } }
.promo-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.promo-card .body { padding: 1.25rem; display: flex; flex-direction: column; justify-content: center; }
.zine p { font-size: 1.12rem; line-height: 1.65; margin: 1.25rem 0; }
.zine .said { font-style: italic; font-weight: 500; }
.zine .beat { font-family: var(--display); font-size: 2.25rem; letter-spacing: 0.12em; color: var(--accent); margin: 2rem 0; }
.byline { display: flex; align-items: center; gap: 0.75rem; margin-top: 1.5rem; }
.byline img { width: 3rem; height: 3rem; border-radius: 8px; object-fit: cover; object-position: top; }

.calling { position: relative; min-height: calc(100dvh - 3.5rem); overflow: hidden; }
.calling img.fill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.calling .veil { position: absolute; inset: 0; background: color-mix(in srgb, var(--bg) 80%, transparent); }
.calling .copy { position: relative; z-index: 1; max-width: 80rem; margin: 0 auto; min-height: calc(100dvh - 3.5rem); display: flex; flex-direction: column; justify-content: flex-end; gap: 2rem; padding: 3rem 1rem; }
.calling h1 { font-family: var(--display); font-size: clamp(3.5rem, 2rem + 8vw, 6rem); letter-spacing: 0.04em; margin: 0.4rem 0 0; font-weight: 400; }
.code { font-family: var(--display); font-size: clamp(2rem, 1rem + 3vw, 3rem); letter-spacing: 0.2em; color: var(--accent); margin: 0; }

.file { border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); border-radius: 10px; background: var(--surface); padding: 1.5rem; }
.field { display: block; margin-bottom: 1.25rem; }
.field input, .field textarea { width: 100%; margin-top: 0.5rem; border: 1px solid var(--border); background: var(--surface); border-radius: 8px; padding: 0.7rem 0.75rem; outline: none; }
.field input { height: 2.75rem; }
.field input:focus, .field textarea:focus { box-shadow: 0 0 0 1px rgba(244,240,234,0.16); }
.notice { border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); border-radius: 10px; background: var(--surface); padding: 2rem; margin-top: 3rem; }

/* =========================================================
   Nav dropdowns
   The supplied design had a flat five-item nav. ICON needs Roster and
   Callings to branch, so these are additive -- .nav-link is untouched
   and a dropdown trigger simply reuses it.
   ========================================================= */
.nav-item { position: relative; flex: 0 0 auto; }
.nav-item > .nav-link { display: inline-flex; align-items: center; gap: 0.3rem; background: none; border: 0; }
.nav-item > .nav-link::after {
  content: "";
  width: 0; height: 0;
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 4px solid currentColor;
  opacity: 0.7;
}
.nav-menu {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 12rem;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.35rem;
  display: none;
  z-index: 40;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.55);
}
/* Hover for pointers, :focus-within so it also opens from the keyboard. */
.nav-item:hover .nav-menu,
.nav-item:focus-within .nav-menu { display: block; }
.nav-menu a {
  display: block;
  padding: 0.5rem 0.7rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  border-radius: 5px;
  white-space: nowrap;
}
.nav-menu a:hover, .nav-menu a.is-on { color: var(--fg); background: var(--surface); }

/* ---- Mobile: hamburger panel ----
   The previous approach flattened the dropdowns into a horizontal scroller.
   That worked in principle but the dropdowns themselves opened on :hover,
   which a touch screen has no equivalent for -- so on a phone they simply
   never opened. A panel avoids the problem entirely: every destination is a
   plain link, no hover involved. */
.nav-toggle {
  display: none;
  width: 2.75rem; height: 2.75rem;
  border: 0; background: none; padding: 0.6rem;
  flex-direction: column; justify-content: space-between;
}
.nav-toggle span {
  display: block; height: 2px; width: 100%;
  background: var(--fg); border-radius: 2px;
  transition: transform 200ms ease, opacity 150ms ease;
}
/* Bars fold into an X while the panel is open. */
.nav-toggle.is-open span:nth-child(1) { transform: translateY(0.51rem) rotate(45deg); }
.nav-toggle.is-open span:nth-child(2) { opacity: 0; }
.nav-toggle.is-open span:nth-child(3) { transform: translateY(-0.51rem) rotate(-45deg); }

.nav-mobile {
  position: fixed;
  top: 3.5rem; left: 0; right: 0; bottom: 0;
  z-index: 60;
  background: var(--bg);
  border-top: 1px solid var(--border);
  padding: 1rem 1.25rem 3rem;
  overflow-y: auto;
}
.nav-mobile[hidden] { display: none; }
.m-heading {
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--subtle);
  margin: 1.4rem 0 0.35rem;
}
.m-link {
  display: block;
  padding: 0.7rem 0;
  font-size: 0.95rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
.m-link.is-on, .m-link:active { color: var(--fg); }
.m-sub { padding-left: 0.9rem; font-weight: 500; letter-spacing: 0.1em; }
.m-account { margin-top: 2rem; border-top: 1px solid var(--border); padding-top: 0.5rem; }
.m-apply { color: var(--accent); }

/* Page behind the panel is locked while it's open. */
body.nav-locked { overflow: hidden; }

@media (max-width: 767px) {
  .nav-toggle { display: flex; }
  /* The account strip lives in the panel on mobile, so the header row keeps
     just the wordmark and the toggle. */
  .head-account { display: none; }

  /* Toggle to the LEFT of the logo.
     Done with flex order rather than by moving the markup: the wordmark
     stays first in the DOM, so it's still the first thing a screen reader
     reads and the first link in the document. */
  .nav-toggle { order: -1; margin-left: -0.6rem; }
  /* space-between would fling the two to opposite edges once the account
     strip is hidden. flex-start keeps them together. */
  .head-row { justify-content: flex-start; gap: 0.5rem; }
}
@media (min-width: 768px) {
  .nav-mobile { display: none !important; }
}

/* Account strip: login / dashboard / admin, which the design had no slot
   for. Sits at the right-hand end of the header row. */
.head-account { display: flex; align-items: center; gap: 0.5rem; flex: 0 0 auto; }
.head-account .nav-link { padding: 0.5rem 0.6rem; }

/* =========================================================
   COMPONENT LAYER
   =========================================================
   Every component the rest of the site already uses, restyled with the new
   design's tokens.

   WHY THIS RATHER THAN REWRITING TWENTY PAGES: the markup on those pages is
   entangled with working logic -- spoiler filters, wallet maths, pagination,
   the promo editor. Rewriting all of it to new class names would risk a lot
   of tested behaviour to change how things look. Restyling the classes gets
   the same visual result and touches no logic at all.

   Pages can still be rebuilt individually later; nothing here prevents it.
   ========================================================= */

/* ---- Typography ---- */
h1 { font-family: var(--display); font-size: clamp(2.4rem, 1.6rem + 3vw, 3.8rem); letter-spacing: 0.06em; font-weight: 400; margin: 0 0 1rem; }
h2 { font-family: var(--display); font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.4rem); letter-spacing: 0.05em; font-weight: 400; margin: 2rem 0 0.9rem; }
h3 { font-family: var(--display); font-size: 1.35rem; letter-spacing: 0.05em; font-weight: 400; margin: 1.4rem 0 0.6rem; }
h4 { font-size: 0.95rem; font-weight: 600; letter-spacing: 0.06em; margin: 1rem 0 0.5rem; }
p { line-height: 1.6; }
a:not(.btn):not(.nav-link):not(.apply-link):not(.wordmark) { color: var(--accent); }
/* Underline on hover is for links in PROSE.
   The exclusions are every link that wraps a whole block -- a Calling row, a
   Dominion tile, a roster card. Underlining those puts a line under every
   word inside them, which reads as damage rather than as a link; they show
   they're interactive through their border and background instead.
   
   These live in the :not() chain rather than as a separate override because
   each :not() raises this selector's specificity -- a plain `.show-card
   { text-decoration: none }` scores lower and loses, however far down the
   file it sits. */
/* Hover underline, but ONLY on links that are inline text.
   A block-level link wrapping a whole card underlines every line inside it,
   which is what made news items look struck through. The colour change is
   enough of a hover cue on those. */
a:not(.btn):not(.nav-link):not(.apply-link):not(.wordmark):not(.show-card):not(.tape):not(.dominion):not(.split-panel):not(.frame):not(.m-link):not(.ghost):not(.link-k):not(.sec-more):hover { text-decoration: underline; }
/* !important is deliberate and the only sane option here. The rule above is
   a chain of thirteen :not() selectors, which outweighs anything reasonable
   -- matching it would mean repeating all thirteen on every override. */
a:has(> p):hover,
a:has(> div):hover,
a:has(> h1):hover, a:has(> h2):hover, a:has(> h3):hover,
a:has(> img):hover,
a:has(> dl):hover,
a:has(> span.chatter-initial):hover { text-decoration: none !important; }

/* Legacy variable names, mapped onto the new palette so any inline style
   written against the old design still resolves. */
:root {
  --ink: var(--bg);
  --paper: var(--fg);
  --paper-dim: var(--border);
  --concrete: var(--muted);
  --steel: var(--elevated);
  --marquee-red: var(--accent);
  --glow: color-mix(in srgb, var(--accent) 35%, transparent);
  --mono: var(--sans);
}

/* ---- Buttons ---- */
.btn { text-decoration: none; }
.btn.outline, .btn.ghost {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
}
.btn.outline:hover, .btn.ghost:hover { border-color: var(--accent); color: var(--fg); }
.btn.gold { background: var(--accent); }
.btn.wide, .btn.block { width: 100%; }

/* ---- Cards and panels ---- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.25rem 1.4rem;
  margin-bottom: 1.1rem;
}
.notice-box, .error-box {
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.9rem;
  border: 1px solid var(--border);
  background: var(--surface);
}
.notice-box { border-color: color-mix(in srgb, var(--honor) 45%, transparent); }
.error-box { border-color: color-mix(in srgb, var(--accent) 60%, transparent); color: var(--fg); }
.eyebrow, .kicker {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--muted);
}
.hint { font-size: 0.78rem; color: var(--muted); }

/* ---- Forms ---- */
label {
  display: block;
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
  margin-bottom: 0.35rem;
}
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=time], input[type=search], input:not([type]),
select, textarea {
  width: 100%;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
  color: var(--fg);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); }
textarea { min-height: 8rem; resize: vertical; }
.stack > div, .stack-y > div { margin-bottom: 1rem; }
form.stack, form.stack-y { max-width: 46rem; }

/* ---- Tables ---- */
table.standings, table.admin-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.5rem 0 1.5rem;
  font-size: 0.92rem;
}
table.standings th, table.admin-table th {
  text-align: left;
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
  border-bottom: 1px solid var(--border);
  padding: 0.6rem 0.7rem;
  white-space: nowrap;
}
table.standings td, table.admin-table td {
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  padding: 0.65rem 0.7rem;
  vertical-align: top;
}
table.standings tr:hover td { background: var(--surface); }
.sortable { cursor: pointer; }
.sort-arrow { opacity: 0.35; font-size: 0.7em; }

/* ---- Grids ---- */
.grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.cols-2 { display: grid; gap: 1.1rem; }
.cols-3 { display: grid; gap: 1.1rem; }
@media (min-width: 700px) { .cols-2 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .cols-3 { grid-template-columns: repeat(3, 1fr); } }
.row { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center; }

/* ---- Fighter profile "tape" ---- */
.tape {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.tape-photo {
  position: relative;
  width: 100%;
  aspect-ratio: 3/4;
  background: var(--elevated) center/cover no-repeat;
  /* The name plate is absolutely positioned inside this, so the box needs to
     be the positioning context. Without it the plate rendered as ordinary
     flow content at the TOP of the photo. */
}
/* Fade at the foot, so a name sitting over any artwork stays readable --
   the same treatment the roster wall uses. ::after rather than an element,
   because the markup is shared by several pages. */
.tape-photo::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg) 4%, color-mix(in srgb, var(--bg) 55%, transparent) 34%, transparent 62%);
  pointer-events: none;
}
.wrestler-layout .tape .tape-photo { background-size: contain; background-position: center; }
.tape-stats { padding: 1rem 1.15rem; }
.tape-stats > div { display: flex; justify-content: space-between; gap: 1rem; padding: 0.45rem 0; border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); }
.tape-stats > div:last-child { border-bottom: 0; }
.tape-stats .label { font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin: 0; }
.tape-stats .value { text-align: right; font-weight: 500; }
/* Anchored to the foot of the artwork, above the fade. */
.name-plate {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  padding: 1rem 1.15rem 1.15rem;
}
/* Name split, matching the roster wall: a small wide-tracked grey line above
   the large one. Letter-spacing is what makes the two read as a pair rather
   than as two headings. */
.ring-first {
  font-family: var(--display);
  font-size: clamp(1rem, 0.8rem + 0.8vw, 1.4rem);
  letter-spacing: 0.28em;
  color: var(--muted);
  line-height: 1;
  margin-bottom: 0.15rem;
}
.ring-name { font-family: var(--display); font-size: clamp(2.2rem, 1.4rem + 3vw, 3.4rem); letter-spacing: 0.05em; line-height: 1; }
/* Morality tag, pinned to the top-left of the artwork the way the roster
   cards do it. Absolute inside .tape-photo, so it sits clear of the name
   plate at the foot. */
.align-tag {
  display: inline-block; margin-top: 0.5rem;
  font-size: 0.62rem; font-weight: 600; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--muted);
  border: 1px solid var(--border); border-radius: 4px; padding: 0.15rem 0.5rem;
}
/* Pinned top-left ONLY as a direct child of the photo, matching the roster
   cards. Scoped to `>` deliberately: the same class also appears nested
   inside .name-plate on other pages, and a looser selector would position
   those against the name plate instead of the artwork. */
.tape-photo > .align-tag {
  position: absolute; top: 0.75rem; left: 0.75rem; z-index: 1;
  margin-top: 0;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
}
.wrestler-layout { display: grid; gap: 2rem; }
@media (min-width: 900px) { .wrestler-layout { grid-template-columns: 20rem 1fr; align-items: start; } }

/* ---- Combatants on a card ---- */
.combatant-card { text-align: center; }
.combatant-photo { width: 100%; aspect-ratio: 3/4; object-fit: cover; border-radius: 8px; background: var(--elevated); }
.combatant-name { font-family: var(--display); font-size: 1.3rem; letter-spacing: 0.04em; margin-top: 0.5rem; }

/* ---- Pact / Syndicate cards ---- */
.team-card, .stable-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.team-card .team-photo-single {
  width: 100%; aspect-ratio: 4/5;
  background-color: var(--elevated);
  background-position: center; background-size: contain; background-repeat: no-repeat;
}
.team-card .team-info, .stable-card .stable-info { padding: 1rem 1.15rem; }
.team-card .team-name, .stable-card .stable-name { font-family: var(--display); font-size: 1.5rem; letter-spacing: 0.04em; }

/* ---- Collapsible history blocks ---- */
.history-block { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 1rem; background: var(--surface); }
.history-block > summary { cursor: pointer; padding: 0.85rem 1.15rem; list-style: none; }
.history-block > summary::-webkit-details-marker { display: none; }
.history-block > summary::before {
  content: "\25B8"; color: var(--accent); margin-right: 0.5rem;
  display: inline-block; transition: transform 0.15s ease;
}
.history-block[open] > summary::before { transform: rotate(90deg); }
/* Matches .dash-section > summary above, so every collapsible section on the
   dashboard reads at the same weight. */
.history-block > summary h2, .history-block > summary h3 {
  margin: 0; display: inline;
  font-family: var(--display);
  font-size: 1.5rem;
  letter-spacing: 0.05em;
  font-weight: 400;
}
.history-scroll { max-height: 26rem; overflow-y: auto; padding: 0 1.15rem; }
.history-pager { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1.15rem 1rem; }
.history-pager button[disabled] { opacity: 0.4; cursor: default; }

/* ---- Dashboard sections ---- */
.dash-section { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 1.1rem; background: var(--surface); }
/* This rule existed only in the old stylesheet, so these headings were
   rendering at default body size while .history-block's (Mentions, The
   Envelope, Fight Writing Guide) came through at h2. Same treatment for both
   now -- display font, same size, same chevron. */
.dash-section > summary {
  cursor: pointer;
  list-style: none;
  padding: 0.85rem 1.15rem;
  font-family: var(--display);
  font-size: 1.5rem;
  letter-spacing: 0.05em;
  display: flex;
  /* Left-aligned, matching .history-block. space-between pushed the sub-label
     to the far right and left a gulf between it and the heading. */
  justify-content: flex-start;
  align-items: baseline;
  gap: 0.6rem;
}
.dash-section > summary::-webkit-details-marker { display: none; }
.dash-section > summary::before {
  content: "\25B8";
  color: var(--accent);
  font-size: 0.8em;
  display: inline-block;
  transition: transform 0.15s ease;
}
.dash-section[open] > summary::before { transform: rotate(90deg); }
.dash-section-body { padding: 1rem 1.15rem; }
.dash-subheading { font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin: 1.2rem 0 0.5rem; }

/* ---- Misc carried over ---- */
.promo-mention { color: var(--accent); font-weight: 600; }
.promo-wordcount { font-family: var(--sans); font-size: 0.75rem; color: var(--muted); text-align: right; padding: 0.25rem 0 0; }
.promo-wordcount.is-near { color: var(--ambiguous); }
.promo-wordcount.is-over { color: var(--accent); font-weight: 600; }
.mention-menu { position: absolute; z-index: 2000; min-width: 12rem; max-height: 15rem; overflow-y: auto; background: var(--elevated); border: 1px solid var(--accent); border-radius: 8px; }
.mention-option { padding: 0.45rem 0.75rem; cursor: pointer; font-size: 0.85rem; white-space: nowrap; }
.mention-option:hover, .mention-option.is-active { background: var(--accent); color: #fff; }
.impersonation-bar { position: sticky; top: 0; z-index: 4000; background: var(--accent); color: #fff; font-size: 0.78rem; padding: 0.5rem 1rem; display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; text-align: center; }
/* Styled as a solid chip, not a bare link.
   A plain <a> here inherits the accent colour, which is the SAME red as this
   bar's background -- so on any page where this rule hasn't loaded, the way
   out is invisible. An explicit background means it shows regardless. */
.impersonation-bar a {
  color: #fff !important;
  text-decoration: none;
  font-weight: 700;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 4px;
  padding: 0.15rem 0.6rem;
  white-space: nowrap;
}
.impersonation-bar a:hover { background: #000; }
.slider { width: 100%; }
.quill-editor { background: var(--elevated); border-radius: 8px; min-height: 12rem; }
.ql-toolbar, .ql-container { border-color: var(--border) !important; }
.ql-editor { min-height: 10rem; color: var(--fg); }
.ql-snow .ql-stroke { stroke: var(--muted); }
.ql-snow .ql-fill { fill: var(--muted); }
.ql-picker-label, .ql-picker-item { color: var(--muted) !important; }

/* ---- Second pass: remaining components ----
   Everything above covers the heavily-used classes. These are the rest that
   carry real visual weight -- section headings, split panels, the moveset
   picker, admin form groups. Anything not listed inherits sensible defaults
   and needs no rule. */

/* Section headings with a "more" link on the right */
.sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin: 2rem 0 1rem; flex-wrap: wrap; }
.sec-title { font-family: var(--display); font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.4rem); letter-spacing: 0.05em; font-weight: 400; margin: 0; }
.sec-more { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.sec-more:hover { color: var(--fg); }
.chev { color: var(--accent); }

/* Homepage split panels */
.split-col { min-width: 0; }
.split-panel { position: relative; display: block; border-radius: 10px; overflow: hidden; background: var(--elevated); aspect-ratio: 16/10; }
.split-panel img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.panel-veil { position: absolute; inset: 0; background: linear-gradient(to top, var(--bg), transparent 70%); }
.panel-copy { position: absolute; left: 0; right: 0; bottom: 0; padding: 1.25rem; }
.panel-kicker { font-size: 0.66rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); }
.panel-line { font-family: var(--display); font-size: 1.6rem; letter-spacing: 0.04em; }

/* Buttons: variants used on older pages */
.icon-btn { gap: 0.5rem; }
.btn.primary { background: var(--accent); }
.btn.danger { background: transparent; border: 1px solid color-mix(in srgb, var(--accent) 70%, transparent); color: var(--accent); }
.navbtn { border: 1px solid var(--border); border-radius: 8px; background: var(--surface); padding: 0.45rem 0.8rem; font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.navbtn:hover, .navbtn.is-on { color: var(--fg); border-color: var(--accent); }
.mode-btn { border: 1px solid var(--border); border-radius: 8px; background: var(--surface); padding: 0.4rem 0.8rem; font-size: 0.72rem; color: var(--muted); }
.mode-btn.is-on { color: var(--fg); border-color: var(--accent); }

/* Media thumbs and misc blocks */
.media { border-radius: 8px; overflow: hidden; background: var(--elevated); }
.media img { width: 100%; height: 100%; object-fit: cover; }
.rail { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: 0.5rem; }
.mini { font-size: 0.78rem; color: var(--muted); }
.line { color: var(--muted); }
.error { color: var(--accent); }
.empty { color: var(--muted); font-style: italic; }
.spacer { flex: 1; }

/* Combatant blocks on a Calling */
.combatant-info { margin-top: 0.4rem; }
.combatant-card-col { display: flex; flex-direction: column; gap: 0.35rem; }
.combatant-card.stacked { display: flex; flex-direction: column; align-items: center; }

/* Promo quote bubble */
.speech-bubble { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1rem 1.15rem; }
.quote-text { font-size: 1.05rem; line-height: 1.55; }

/* Moveset picker */
.move-grid { display: grid; gap: 0.4rem 1rem; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); }
.move-checkbox { display: flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; text-transform: none; font-weight: 400; letter-spacing: 0; color: var(--fg); margin: 0; }
.move-checkbox input { width: auto; }
.remove-move-row { display: flex; gap: 0.5rem; align-items: center; }

/* Admin form groupings, shown or hidden by role/type */
.roster-type-fields, .champ-fields, .reign-fields, .bribe-field { margin-bottom: 1rem; }
.admin-collapse { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 1rem; background: var(--surface); }
.admin-collapse > summary { cursor: pointer; padding: 0.8rem 1.1rem; list-style: none; }
.admin-collapse > summary::-webkit-details-marker { display: none; }
.admin-collapse > summary::before { content: "\25B8"; color: var(--accent); margin-right: 0.5rem; display: inline-block; transition: transform 0.15s ease; }
.admin-collapse[open] > summary::before { transform: rotate(90deg); }

/* Admin card rows */
.card-bout { border: 1px solid var(--border); border-radius: 10px; background: var(--surface); padding: 1rem 1.15rem; margin-bottom: 1rem; }
.card-bout .order { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.stat-line { display: flex; justify-content: space-between; gap: 1rem; padding: 0.35rem 0; }
.stat-label { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.stack-wide { max-width: none; }
.dash-section-sub { font-size: 0.78rem; color: var(--muted); }
.theme-play-btn { border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--muted); padding: 0.2rem 0.6rem; font-size: 0.72rem; }
.theme-play-btn:hover { color: var(--fg); border-color: var(--accent); }
.team-members a { color: var(--accent); }

/* ---- Splash note overlay (logged-out visitors, once per session) ---- */
.splash-overlay[hidden] { display: none; }
.splash-overlay {
  position: fixed; inset: 0; z-index: 5000;
  background: rgba(0, 0, 0, 0.94);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem; overflow-y: auto;
}
.splash-inner { position: relative; max-width: 52rem; width: 100%; margin: auto; }
/* drop-shadow on the alpha, not box-shadow -- the note is a torn scrap on
   transparency and a box shadow would trace its invisible bounding box. */
.splash-inner img { width: 100%; height: auto; filter: drop-shadow(0 18px 40px rgba(0,0,0,0.8)); }
.splash-close {
  position: absolute; top: -0.9rem; right: -0.9rem;
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  border: 1px solid var(--accent); background: #0b0b0b; color: #fff;
  font-size: 1.6rem; line-height: 1; z-index: 1;
}
.splash-close:hover { background: var(--accent); }

/* =========================================================
   Dominion wall
   Same treatment as the Dossiers roster view: a portrait-ratio tile with the
   artwork behind, a fade into the page, and everything that matters sitting
   at the FOOT of the image rather than floating over the middle of it.
   ========================================================= */
.dominion-wall {
  list-style: none; margin: 2rem 0 0; padding: 0;
  display: grid; gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.dominion {
  position: relative; display: block;
  aspect-ratio: 2/3; overflow: hidden;
  border-radius: 10px; background: var(--elevated);
  box-shadow: 0 0 0 1px rgba(244, 240, 234, 0.08);
}
.dominion img:not(.belt) {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: top;
  transition: transform 500ms ease-out;
}
.dominion:hover img:not(.belt) { transform: scale(1.04); }
/* The fade is what makes text at the foot readable over any artwork. */
.dominion .fade {
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg) 4%, color-mix(in srgb, var(--bg) 55%, transparent) 38%, transparent 68%);
}
.dominion-meta {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1rem 1rem 1.1rem;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 0.35rem;
}
/* The belt image, sitting directly above the holder's name. */
.dominion-meta .belt {
  width: 100%; max-height: 4.5rem;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.7));
  margin-bottom: 0.15rem;
}
.dominion-meta .holder {
  font-family: var(--display); font-size: 1.6rem;
  letter-spacing: 0.04em; line-height: 1; color: var(--fg);
}
.dominion-meta .dominion-name {
  font-size: 0.64rem; font-weight: 600; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--muted);
}
.dominion-link { margin: 0.6rem 0 0; text-align: center; }
.dominion-link a {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}
.dominion-link a:hover { color: var(--fg); }


/* ---- Site logo ----
   Replaces the wordmark text wherever an image is set in Image Library.
   Both selectors keep their text styling for the fallback case, so removing
   the logo puts the wordmark straight back. */
.wordmark.has-logo { display: inline-flex; align-items: center; line-height: 0; }
.wordmark.has-logo img {
  /* Capped by HEIGHT, not width: the header row is a fixed 3.5rem and a
     wide logo would otherwise push the nav out of it. */
  height: 2.4rem; width: auto; max-width: 12rem; object-fit: contain;
}
.hero-mark.is-logo { line-height: 0; white-space: normal; }
.hero-mark.is-logo img {
  width: min(30rem, 70vw); height: auto; max-height: 40vh;
  object-fit: contain;
  filter: drop-shadow(0 10px 34px rgba(0, 0, 0, 0.75));
}
/* The footer wordmark is text-only and unaffected. */

/* =========================================================
   Shared roster wall (includes/roster_wall.php)
   The Dossiers card treatment, used by Pacts, Syndicates, Staff, Managers,
   Retired and the Hall of Fame.
   ========================================================= */
.wall-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin: 1.5rem 0 0.5rem;
}
.wall-toolbar label { display: flex; align-items: center; gap: 0.6rem; margin: 0; }
.wall-search {
  width: 16rem; max-width: 60vw;
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: 8px; padding: 0.5rem 0.7rem; color: var(--fg);
  text-transform: none; letter-spacing: 0;
}
.wall-rail {
  list-style: none; margin: 1rem 0 2rem; padding: 0;
  display: grid; gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
/* perspective on the LI, not the card: the 3D space has to belong to the
   parent or the rotation reads flat. */
.wall-rail > li { perspective: 1100px; }

.wall-card3d {
  position: relative; width: 100%; height: 26rem;
  transform-style: preserve-3d;
  transition: transform 500ms cubic-bezier(0.22, 1, 0.36, 1);
}
.wall-card3d.is-flipped { transform: rotateY(180deg); }
.wall-face {
  position: absolute; inset: 0;
  overflow: hidden; border-radius: 10px;
  border: 1px solid var(--border);
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.wall-front { background: var(--elevated); }
.wall-front button {
  position: relative; display: block; width: 100%; height: 100%;
  border: 0; padding: 0; background: none; text-align: left;
}
.wall-front img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: top;
  transition: transform 500ms ease-out;
}
.wall-front button:hover img { transform: scale(1.04); }
.wall-fade {
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg) 4%, color-mix(in srgb, var(--bg) 55%, transparent) 34%, transparent 64%);
}
.wall-front .badge {
  position: absolute; top: 0.75rem; left: 0.75rem; z-index: 2;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
}
.wall-meta { position: absolute; inset: auto 0 0 0; padding: 0.9rem 1rem 1rem; }
.wall-main {
  display: block; font-family: var(--display);
  font-size: 1.9rem; line-height: 0.9; letter-spacing: 0.04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wall-lead {
  display: block; font-family: var(--display);
  font-size: 1rem; letter-spacing: 0.2em; color: var(--muted);
  margin-top: 0.2rem;
}

.wall-back {
  transform: rotateY(180deg);
  background: var(--surface);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  display: flex; flex-direction: column; padding: 1.15rem;
}
.wall-back-name { font-family: var(--display); font-size: 1.5rem; letter-spacing: 0.04em; margin: 0; }
.wall-back .line { font-size: 0.88rem; color: var(--muted); margin: 0.5rem 0 0; }
.wall-stats {
  margin-top: auto; display: grid; grid-template-columns: 1fr 1fr;
  gap: 0.5rem 0.75rem; border-top: 1px solid var(--border);
  padding-top: 0.85rem; font-size: 0.85rem;
}
.wall-stats dd { margin: 0.15rem 0 0; font-weight: 500; }
.wall-actions { display: flex; gap: 0.5rem; margin-top: 1rem; }
.wall-actions button, .wall-actions a {
  flex: 1; height: 2.6rem; border-radius: 8px;
  border: 1px solid var(--border); background: var(--elevated);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--fg); text-decoration: none; font-size: 0.85rem;
}
.wall-actions a:hover, .wall-actions button:hover { border-color: var(--accent); }

/* ---- The creed (info.php) ----
   Four words, the initials picked out so ICON reads across them. Wraps to
   two lines on narrow screens rather than shrinking below legibility. */
.creed {
  display: flex; flex-wrap: wrap;
  gap: 0.4rem 1.6rem;
  margin: 1.75rem 0 2.5rem;
  padding: 1.25rem 0;
  border-block: 1px solid var(--border);
  font-family: var(--display);
  font-size: clamp(1.4rem, 1rem + 1.8vw, 2.2rem);
  letter-spacing: 0.06em;
  color: var(--muted);
  line-height: 1;
}
.creed b { color: var(--accent); font-weight: 400; }

/* ---- Promo list rows ----
   These lived only in the old style.css, which the new design doesn't load --
   so the thumbnail rendered at its natural size, which for a 1600px
   placeholder meant it swallowed the page. */
.card.promo-row {
  display: flex;
  gap: 1.15rem;
  align-items: center;
  padding: 1.15rem 1.25rem;
}
.promo-row-thumb {
  width: 4.5rem;
  height: 6rem;
  object-fit: cover;
  object-position: center top;
  border-radius: 6px;
  flex-shrink: 0;   /* or a long title squeezes the image thinner */
  display: block;
  background: var(--elevated);
}
.promo-row-body { min-width: 0; }   /* lets long titles wrap instead of overflowing */
.card.promo-row h3 { font-size: 1.15rem; margin: 0.25rem 0 0.4rem; }

@media (max-width: 600px) {
  .card.promo-row { gap: 0.85rem; padding: 0.9rem 1rem; }
  .promo-row-thumb { width: 3.25rem; height: 4.35rem; }
  .card.promo-row h3 { font-size: 1rem; }
}

/* ---- Remaining components from the old stylesheet ----
   Everything below was styled only in style.css, which the new design no
   longer loads. Anything that sizes an IMAGE matters most: without a rule the
   file renders at its natural pixel size, which is how the promo thumbnail
   ended up filling the screen. */

/* Promo page portrait */
.promo-portrait {
  float: left;
  max-width: 40%;
  height: auto;
  margin: 0 1.4rem 1rem 0;
  border-radius: 8px;
  display: block;
}
.promo-body::after { content: ""; display: block; clear: both; }
@media (max-width: 700px) {
  .promo-portrait { float: none; width: 100%; max-width: 20rem; margin: 0 auto 1rem; }
}

/* Calling cards on the Callings list */
.show-card {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; flex-wrap: wrap;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  background: var(--surface);
  border-radius: 8px;
  padding: 1rem 1.15rem;
  margin-bottom: 0.85rem;
  text-decoration: none;
}
.show-card:hover { border-color: var(--accent); }
.show-card .date { font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.show-card .show-name { font-family: var(--display); font-size: 1.5rem; letter-spacing: 0.04em; margin: 0.15rem 0 0; }
.show-card .status {
  font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.2rem 0.6rem; border-radius: 4px;
  background: var(--elevated); color: var(--muted);
}
.show-card .status.completed { background: var(--accent); color: #fff; }
.show-card .show-type { font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.show-card .show-type.premium { background: var(--accent); color: #fff; padding: 0.1rem 0.45rem; border-radius: 4px; }
.show-mode-bar { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }

/* Reactions */
.reaction-row { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 1rem 0; }
.reaction-btn {
  display: inline-flex; align-items: center; gap: 0.35rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 0.3rem 0.8rem;
  font-size: 0.8rem; color: var(--fg);
}
.reaction-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.reaction-btn:hover { border-color: var(--accent); }

/* Video embeds */
.video-wrap { position: relative; width: 100%; margin-bottom: 1.5rem; border-radius: 8px; overflow: hidden; }
.video-wrap iframe, .video-wrap video { width: 100%; display: block; border: 0; }
.video-click-overlay { position: absolute; inset: 0; cursor: pointer; }
.video-play-icon {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 3.5rem; height: 3.5rem; border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  border: 1px solid var(--accent);
  display: flex; align-items: center; justify-content: center;
  color: var(--fg); font-size: 1.2rem;
}
.now-playing-bar { font-size: 0.78rem; color: var(--muted); margin-bottom: 0.75rem; }

/* Combatant photos on a Calling. Height-capped rather than stretched, since
   character art varies wildly in aspect. */
.combatant-card img.combatant-photo {
  height: auto; max-height: 12.5rem;
  width: auto; max-width: 10.5rem;
  object-fit: contain; background: var(--elevated);
  align-self: center; flex-shrink: 0; display: block; margin: 0 auto;
}
.combatant-card div.combatant-photo { width: 6.25rem; background: var(--elevated); }
.combatant-card.stacked div.combatant-photo { width: 100%; height: 13.75rem; max-width: none; object-fit: cover; }
.combatant-card.mini div.combatant-photo { width: 100%; height: 5.75rem; max-width: none; object-fit: cover; }
.vs { font-family: var(--display); font-size: 1.4rem; color: var(--accent); letter-spacing: 0.08em; }

/* Moveset picker */
.moveset-picker-full { display: grid; gap: 1rem; }
.move-category-block { border: 1px solid var(--border); border-radius: 8px; padding: 0.85rem 1rem; background: var(--surface); }
.move-category-label { font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.5rem; }
.move-category-picked { color: var(--accent); }

/* Predictions */
.prediction-results-bar { height: 0.5rem; border-radius: 999px; background: var(--elevated); overflow: hidden; margin: 0.35rem 0; }
.prediction-results-bar > span { display: block; height: 100%; background: var(--accent); }

/* Title lineage, momentum meters, badges and comments */
.lineage-timeline { display: grid; gap: 0.5rem; }
.lineage-row { display: flex; align-items: center; gap: 0.85rem; }
.lineage-photo { width: 2.75rem; height: 2.75rem; border-radius: 50%; object-fit: cover; object-position: center top; background: var(--elevated); flex-shrink: 0; }
.lineage-bar-track, .momentum-bar-track { flex: 1; height: 0.5rem; border-radius: 999px; background: var(--elevated); overflow: hidden; }
.lineage-bar-fill, .momentum-bar-fill { display: block; height: 100%; background: var(--accent); }
.momentum-meter { display: flex; align-items: center; gap: 0.75rem; margin: 0.5rem 0; }

.badge-row { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.5rem 0; }
.badge-pill {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase;
  border: 1px solid var(--border); border-radius: 999px;
  padding: 0.2rem 0.6rem; color: var(--muted);
}
.badge-icon { font-size: 0.85em; }

.comment-item { border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); padding: 0.85rem 0; }
.comment-item:last-child { border-bottom: 0; }

.mode-toggle { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.compact { font-size: 0.85rem; }

/* ---- Belt shine ----
   A highlight that sweeps across a Dominion's belt image. Carried over from
   the old stylesheet; the wrapper markup was lost when the page was rebuilt.

   The delay means the belts don't all flash in unison -- combined with the
   per-card offset below, they catch the light at different moments, which
   reads as light moving across a room rather than a synchronised effect. */
@keyframes belt-shine {
  0%        { transform: translateX(-120%) skewX(-20deg); }
  60%, 100% { transform: translateX(220%) skewX(-20deg); }
}
.belt-shine-wrap {
  position: relative;
  display: block;
  overflow: hidden;
  width: 100%;
}
.belt-shine-wrap::after {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 30%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.55), transparent);
  animation: belt-shine 3.2s ease-in-out infinite;
  animation-delay: 1s;
  pointer-events: none;
}
/* Stagger, so a wall of belts doesn't pulse as one. */
.dominion-wall > li:nth-child(2n) .belt-shine-wrap::after { animation-delay: 1.9s; }
.dominion-wall > li:nth-child(3n) .belt-shine-wrap::after { animation-delay: 2.6s; }

/* Respects a reduced-motion preference -- a repeating sweep is exactly the
   kind of thing that setting exists for. */
@media (prefers-reduced-motion: reduce) {
  .belt-shine-wrap::after { animation: none; }
}

/* ---- Vacant Dominions ----
   The tile always has a backdrop of its own, so a missing or slow image
   never leaves a flat empty box. */
.dominion {
  background:
    radial-gradient(120% 80% at 50% 15%, color-mix(in srgb, var(--fg) 7%, transparent), transparent 60%),
    var(--elevated);
}
/* An unheld belt is pushed back and desaturated -- present, but plainly not
   somebody's. The belt image itself stays at full strength on top. */
.dominion.is-vacant img:not(.belt) { opacity: 0.45; filter: grayscale(0.4); }
.dominion.is-vacant .holder { color: var(--muted); }

/* ---- Fight Writing Guide ---- */
.guide-layout { display: grid; gap: 2rem; align-items: start; margin-top: 1.5rem; }
@media (min-width: 900px) { .guide-layout { grid-template-columns: 20rem 1fr; } }
.guide-photo {
  width: 100%; border-radius: 10px; display: block;
  background: var(--elevated);
  border: 1px solid var(--border);
}
.guide-move {
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 0.9rem 1.1rem;
  margin-bottom: 0.75rem;
}
/* The finisher is the one that ends it, so it gets the accent edge. */
.guide-move.is-finisher { border-left-color: var(--accent); }
.guide-move-name { font-family: var(--display); font-size: 1.4rem; letter-spacing: 0.04em; margin: 0; }
.guide-move-detail { margin: 0.4rem 0 0; color: var(--muted); line-height: 1.55; }

.guide-moves { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); }
.guide-cat {
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); padding: 0.85rem 1rem;
}
.guide-cat ul { list-style: none; margin: 0.4rem 0 0; padding: 0; }
.guide-cat li { padding: 0.2rem 0; font-size: 0.9rem; }
.guide-notes { border-top: 1px solid var(--border); padding-top: 1rem; }
.guide-notes p { line-height: 1.65; }

/* ---- Booking Office ---- */
.admin-group { margin: 2.25rem 0; }
.admin-group-head { margin-bottom: 1rem; }
.admin-group-head h2 { margin: 0; }
.admin-group-head p { margin: 0.2rem 0 0; color: var(--muted); font-size: 0.9rem; }

.admin-tiles {
  display: grid; gap: 0.85rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.admin-tile {
  display: flex; flex-direction: column; gap: 0.3rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 0.9rem 1.05rem;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.admin-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.admin-tile-title {
  font-family: var(--display); font-size: 1.25rem; letter-spacing: 0.04em;
  color: var(--fg); display: flex; align-items: center; gap: 0.5rem;
}
.admin-tile-blurb { font-size: 0.82rem; color: var(--muted); line-height: 1.45; }
/* Only rendered when something is actually waiting, so it always means
   "this needs you" rather than being decoration. */
.admin-badge {
  font-family: var(--sans); font-size: 0.7rem; font-weight: 700;
  background: var(--accent); color: #fff;
  border-radius: 999px; padding: 0.05rem 0.45rem; line-height: 1.5;
}

/* ---- Submissions inbox ---- */
.sub-body { border-left: 2px solid var(--border); padding-left: 1rem; margin: 0.5rem 0 0; }
.sub-body p { line-height: 1.6; }
/* A plain-text copy of the same thing. The rendered version is for reading;
   this is for pasting into the news or card editor without carrying markup
   across. Click selects it all. */
.sub-plain {
  width: 100%; font-family: var(--sans); font-size: 0.85rem;
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: 6px; padding: 0.6rem 0.7rem; color: var(--muted);
}

/* ---- Rich text bodies ----
   Every rendered rich-text block: news, promos, bios, the Fight Writing
   Guide, submissions.

   Quill makes a new PARAGRAPH on Enter, not a line break, which is correct
   markup but leaves gaps that read as too airy for short lines. Tightening
   the gap keeps the semantics right while looking closer to what was typed.
   Shift+Enter still gives a true <br> where a tighter break is wanted. */
.rich-body p {
  margin: 0 0 0.3rem;
  line-height: 1.6;
}
.rich-body p:last-child { margin-bottom: 0; }

/* An empty paragraph is what a SECOND Enter produces -- Quill writes
   "<p><br></p>" between the two lines. Left alone it takes a full line of
   height and the gap comes out around 40px, which is more than a paragraph
   break needs.
   
   Sized so the total works out near 25px:
     0.3rem margin + 15px empty line + 0.3rem margin ~= 25px
   
   :empty covers a paragraph with nothing in it at all; the :has() rule
   covers Quill's version, which contains a lone <br>. */
.rich-body p:empty,
.rich-body p:has(> br:only-child) {
  height: 15px;
  line-height: 15px;
  margin: 0 0 0.3rem;
}
/* Headings and lists keep room to breathe -- the tightening is only meant
   for consecutive paragraphs. */
.rich-body h1, .rich-body h2, .rich-body h3 { margin: 1.4rem 0 0.5rem; }
.rich-body h1:first-child, .rich-body h2:first-child, .rich-body h3:first-child { margin-top: 0; }
.rich-body ul, .rich-body ol { margin: 0 0 0.75rem; padding-left: 1.4rem; }
.rich-body li { margin: 0.15rem 0; }
.rich-body blockquote {
  margin: 0.75rem 0; padding-left: 1rem;
  border-left: 2px solid var(--accent); color: var(--muted);
}

/* ---- Arc note from the Booking Office ----
   Marked out from the handlers' own writing, since it's instruction rather
   than story. */
.arc-note {
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-left-width: 3px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
}
.arc-note p { margin: 0.25rem 0 0; line-height: 1.55; }
.arc-note .kicker { color: var(--accent); }

/* ---- Flippable combatant cards on the show page ----
   The roster wall's card, sized for a match line-up.

   TWO THINGS HAD TO BE OVERRIDDEN, and both made the card render as an
   empty box:

   1. .wall-card3d sets height:26rem for the roster grid. A min-height here
      doesn't beat a height, so the cards were 26rem tall with their content
      sitting in the top corner of a much larger box.

   2. perspective lives on .wall-rail > li, which these cards have no
      equivalent of. Without a perspective ancestor the 3D transform has no
      depth, and backface-visibility:hidden can take the front face with it.
      The wrapper below supplies it. */
.combatant-card-col { perspective: 1100px; }

.combatant-card3d { width: 190px; height: 250px; }
.combatant-card3d.mini { width: 140px; height: 200px; }

/* The faces are absolutely positioned, so the front needs to lay its photo
   and name out within a fixed height rather than growing to fit. */
.combatant-card3d .wall-front {
  display: flex; flex-direction: column;
}
.combatant-card3d .wall-front button {
  display: block; width: 100%; flex: 1 1 auto; min-height: 0;
  padding: 0; border: 0; background: none; cursor: pointer;
}
.combatant-card3d img.combatant-photo,
.combatant-card3d div.combatant-photo {
  width: 100%; height: 100%; max-width: none;
  aspect-ratio: auto; object-fit: cover; display: block;
  border-radius: 0; background: var(--elevated);
}
.combatant-card3d .combatant-info {
  flex: 0 0 auto; margin: 0; padding: 0.4rem 0.5rem; text-align: center;
}
.combatant-card3d .combatant-name { font-size: 0.85rem; }
.combatant-card3d.mini .combatant-name { font-size: 0.75rem; }

/* The back is denser than a roster card -- less room to work with. */
.combatant-card3d .wall-back { padding: 0.7rem 0.8rem; overflow-y: auto; }
.combatant-card3d .wall-back-name { font-size: 1.05rem; }
.combatant-card3d .wall-stats { font-size: 0.75rem; }
.combatant-card3d.mini .wall-back-name { font-size: 0.9rem; }
.combatant-card3d.mini .wall-stats { font-size: 0.68rem; }
/* Shorter than the roster version -- 2.6rem of button in a 250px card
   leaves no room for the stats above it. Stacked rather than side by side,
   since two 2-word labels don't fit across 190px. */
.combatant-card3d .wall-actions {
  flex-direction: column; gap: 0.35rem; margin-top: 0.75rem;
}
.combatant-card3d .wall-actions button,
.combatant-card3d .wall-actions a {
  height: 1.9rem; font-size: 0.75rem; border-radius: 6px;
}
.combatant-card3d.mini .wall-actions button,
.combatant-card3d.mini .wall-actions a {
  height: 1.7rem; font-size: 0.7rem;
}
/* The stats block pushes itself down with margin-top:auto on the roster
   card. In this shorter one that shoves the buttons off the bottom. */
.combatant-card3d .wall-stats { margin-top: 0.6rem; padding-top: 0.6rem; }

/* ---- What you still owe ----
   Sits above the bookings on the dashboard. Red while something is missing,
   quiet once it isn't -- so it stops demanding attention when it's satisfied. */
.owed-banner {
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-left-width: 3px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  padding: 0.9rem 1.1rem;
  margin: 0 0 1.1rem;
}
.owed-banner .kicker { color: var(--accent); margin: 0; }
.owed-banner p { margin: 0.3rem 0 0; }
.owed-banner .owed-detail { color: var(--muted); font-size: 0.9rem; }
.owed-banner.is-done {
  border-color: var(--border);
  background: var(--surface);
}
.owed-banner.is-done .kicker { color: var(--muted); }

/* ---- Submission deadlines ----
   Two side by side: segments close first, promos later. */
.deadline-row {
  display: flex; flex-wrap: wrap; gap: 1.5rem;
  margin: 0.6rem 0 0 !important;
}
.deadline { display: flex; flex-direction: column; gap: 0.1rem; }
.deadline .kicker { margin: 0; }
.deadline > span:nth-child(2) {
  font-family: var(--display); font-size: 1.35rem; letter-spacing: 0.03em;
  /* Tabular figures so every digit is the same width -- otherwise the text
     beside a changing number shifts left and right each tick, which reads as
     a flicker even when nothing is being redrawn. min-width holds the box
     steady as the value shortens (2d 4h 11m -> 4h 11m 9s). */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  min-width: 8.5ch;
  display: inline-block;
}
.deadline-when { font-size: 0.75rem; color: var(--muted); }
/* A passed deadline stops shouting -- it isn't actionable any more. */
.deadline.is-closed > span:nth-child(2) { color: var(--muted); }
.deadline.is-closed .kicker { color: var(--muted); }

/* ---- Dashboard group headings ----
   Break a long page of collapsible sections into named groups, so it can be
   scanned rather than read top to bottom. */
.dash-group {
  font-family: var(--display);
  font-size: 1.15rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 2.5rem 0 0.9rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem;
}
/* The blurb sits on the same line, in body type -- a second heading-styled
   line would compete with the section titles underneath. */
.dash-group span {
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}
/* The first group shouldn't push away from what's above it. */
.dash-group:first-of-type { margin-top: 1.5rem; }
@media (max-width: 600px) {
  .dash-group { font-size: 1rem; gap: 0.2rem; }
  .dash-group span { flex-basis: 100%; }
}

/* ---- Season page ---- */
.season-shows { list-style: none; margin: 1rem 0 0; padding: 0; }
.season-shows li { border-bottom: 1px solid var(--border); }
.season-shows a {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.9rem;
  padding: 0.75rem 0.2rem; text-decoration: none; color: var(--fg);
}
.season-shows a:hover { background: var(--elevated); }
.season-show-date { font-family: var(--mono); font-size: 0.78rem; color: var(--muted); min-width: 7rem; }
.season-show-name { font-family: var(--display); font-size: 1.25rem; letter-spacing: 0.03em; }
.season-show-type { font-size: 0.75rem; color: var(--muted); margin-left: auto; }

/* Promos in a season, same row treatment as the Callings above them. */
.season-promos { list-style: none; margin: 1rem 0 0; padding: 0; }
.season-promos li { border-bottom: 1px solid var(--border); }
.season-promos a {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.9rem;
  padding: 0.7rem 0.2rem; text-decoration: none; color: var(--fg);
}
.season-promos a:hover { background: var(--elevated); }
.season-promo-date { font-family: var(--mono); font-size: 0.78rem; color: var(--muted); min-width: 7rem; }
.season-promo-title { font-weight: 600; }
.season-promo-by { color: var(--muted); font-size: 0.88rem; }
.season-promo-show { font-size: 0.75rem; color: var(--muted); margin-left: auto; }
@media (max-width: 640px) {
  .season-promo-show { margin-left: 0; flex-basis: 100%; }
}

.season-list { list-style: none; margin: 1rem 0 0; padding: 0; }
.season-list li { display: flex; gap: 1rem; align-items: baseline; padding: 0.45rem 0; border-bottom: 1px solid var(--border); }
.season-list li.is-current a { color: var(--accent); }
.season-list span { font-family: var(--mono); font-size: 0.75rem; color: var(--muted); margin-left: auto; }

/* ---- How ICON Runs ----
   The facts strip is read from live settings, so it sits apart from the
   editable prose below it. */
.run-facts {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin: 1.5rem 0;
}
.run-facts > div {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: var(--surface);
  padding: 0.85rem 1rem;
  display: flex; flex-direction: column; gap: 0.15rem;
}
.run-facts .kicker { margin: 0; }
.run-facts strong { font-family: var(--display); font-size: 1.5rem; letter-spacing: 0.03em; font-weight: 400; }
.run-facts span:last-child { font-size: 0.8rem; color: var(--muted); }

.run-body h2 { font-size: 1.5rem; margin: 1.75rem 0 0.5rem; }
.run-body h2:first-child { margin-top: 0; }
.run-body p { line-height: 1.65; }

/* ---- Bouts on a Calling's card ----
   ONE backdrop across the whole match panel, with the figures standing on
   it. Names are laid over the figures, not captioned beneath them. */
.bout-stage {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--border);
  margin: 0.9rem 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* FIXED height. Previously the stage was sized by its tallest figure, so a
     Pact bout -- whose figures scale down to fit four people -- rendered a
     visibly shorter panel than the singles bout beneath it. Every bout on a
     card is now the same size regardless of how many are in it. */
  height: 24rem;
}
.bout-stage-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* Darkened at the foot so names stay readable over whatever the backdrop is
   doing down there. */
.bout-stage::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, color-mix(in srgb, var(--bg) 92%, transparent) 0%, transparent 38%);
  pointer-events: none;
}
/* NO bottom padding: the figures sit flush with the foot of the stage, so
   nobody appears to be floating above the floor. */
.bout-stage-inner {
  position: relative; z-index: 1;
  display: flex; flex-wrap: wrap;
  align-items: flex-end; justify-content: center;
  /* No gap between the two sides -- the VS already separates them, and a gap
     just pulls the outer figures away from the edges. */
  gap: 0;
  width: 100%;
  /* No padding at all: figures reach the top of the stage AND its left and
     right edges, rather than sitting inset with dead backdrop either side. */
  padding: 0;
  height: 100%;
}
/* A named group's text lies OVER the figures rather than under them, so the
   figures give up no height for it. */

/* Everyone in a group stands on the same floor, whatever their art is
   shaped like. flex-end at every level, so a shorter cut-out doesn't float. */
.bout-group {
  display: flex; flex-wrap: nowrap;
  gap: 0.6rem;
  align-items: flex-end;
  justify-content: center;
  height: 100%;
  flex: 1 1 0; min-width: 0;
}
/* A named group needs the Pact name laid ACROSS the pair, so the wrapper
   becomes the positioning context and the name is absolute within it --
   centred on the group rather than on either figure. */
.bout-group.has-name { position: relative; }
.bout-group-name {
  position: absolute;
  left: 50%; bottom: 2.1rem;
  transform: translateX(-50%);
  margin: 0;
  z-index: 2;
  white-space: nowrap;
  font-family: var(--display);
  font-size: 2.1rem;
  letter-spacing: 0.03em;
  line-height: 1;
  color: #fff;
  /* Same shadow as the VS, so both sit in the same layer of the image. */
  text-shadow: 0 2px 6px #000, 0 0 14px rgba(0, 0, 0, 0.95);
}
/* Member names drop back to a supporting size and make room for the Pact
   name above them. */
.bout-group.has-name .bout-name { bottom: 0.4rem; }
.bout-group.has-name .bout-name-text { font-size: 0.95rem; }
.bout-stage.mini .bout-group-name { font-size: 1.6rem; }
/* Matches the weight of the site-wide a:not(...) chain, which would
   otherwise turn the Pact name red. */
.bout-group-name a:not(.btn):not(.nav-link):not(.apply-link):not(.wordmark) {
  color: inherit; text-decoration: none;
}
.bout-group-name a:hover { color: var(--accent); }
.bout-side-col {
  display: flex; flex-direction: column;
  align-items: center; justify-content: flex-end;
  height: 100%;
  /* Shares the row rather than demanding its natural width. min-width:0 is
     required or a flex item refuses to shrink below its content. */
  flex: 1 1 0; min-width: 0;
}
/* The name is positioned against this, so it has to be the containing box.
   It also has to carry a height, or the figure's percentage height has
   nothing to resolve against and falls back to the image's natural size. */
/* FLEX, not block. The figure is 94% of this box's height, and in a block
   container that leaves the remaining 6% as dead space UNDERNEATH it -- the
   figures hovered above the floor. align-items:flex-end puts the slack above
   them instead. */
.bout-side {
  position: relative;
  display: flex;
  align-items: flex-end;
  height: 100%; width: 100%;
}

/* Sized by HEIGHT so people of different proportions stand at a consistent
   scale. display:block removes the inline-image gap underneath, which is
   what would otherwise leave a sliver of floor below the feet. */
.bout-figure {
  /* Fills its column and scales to fit. A fixed height with auto width could
     not shrink horizontally, so four figures overflowed the stage and the
     far group was clipped away entirely.

     object-position:bottom is what keeps everyone standing on the floor when
     contain letterboxes a narrow column. */
  width: 100%;
  height: 94%;
  object-fit: contain;
  object-position: bottom;
  display: block;
  filter: drop-shadow(0 12px 24px rgba(0, 0, 0, 0.75));
}
/* NO per-count sizing. Every figure on every bout is the same height, so a
   Pact stands exactly as tall as a singles fighter. They fill the stage and
   sit on the floor; the names lie over them. */
/* The silhouette is a flat shape, so it takes no drop shadow -- a shadow on
   a solid black cut-out just muddies its edge. */
.bout-side.is-silhouette .bout-figure { filter: none; opacity: 0.85; }

.bout-name {
  position: absolute; left: 50%; bottom: 0.75rem;
  transform: translateX(-50%);
  margin: 0; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
  width: max-content; max-width: 120%;
}
.bout-name-text {
  font-family: var(--display); font-size: 1.35rem; letter-spacing: 0.03em;
  line-height: 1.15;
  /* Heavy shadow rather than a panel behind it: the name has to stay legible
     against both a lit backdrop and a black silhouette. */
  text-shadow: 0 2px 6px #000, 0 0 14px rgba(0, 0, 0, 0.95);
}
.bout-stage.mini .bout-name-text { font-size: 1.05rem; }
/* Matches the weight of the site-wide a:not(...) chain, which would
   otherwise colour these red. */
a.bout-name-text:not(.btn):not(.nav-link):not(.apply-link):not(.wordmark) {
  color: var(--fg); text-decoration: none;
}
a.bout-name-text:hover { color: var(--accent); }

.bout-champ {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.1rem 0.45rem; border-radius: 3px;
  color: #C9A227; border: 1px solid #C9A227;
  background: color-mix(in srgb, var(--bg) 75%, transparent);
}

/* Sized to match the page h1, so it reads as part of the poster rather than
   as a separator between two pictures.
   White rather than red: red on a dark, busy backdrop was the hardest
   possible combination to read. */
.bout-stage-inner .vs {
  align-self: center;
  /* The groups either side are flex:1 and will take everything they can get.
     Without this the VS is a shrinkable flex item and gets crushed. */
  flex: 0 0 auto;
  font-family: var(--display);
  font-size: clamp(2.4rem, 1.6rem + 3vw, 3.8rem);
  line-height: 1;
  letter-spacing: 0.06em;
  color: #fff;
  text-shadow: 0 2px 6px #000, 0 0 14px rgba(0, 0, 0, 0.95);
  /* Sits above the figures, so a wide cut-out passing behind it does not
     cover the VS. */
  position: relative;
  z-index: 2;
  padding: 0 0.3rem;
}
.bout-stage.mini .vs { font-size: clamp(1.8rem, 1.2rem + 2vw, 2.8rem); }

@media (max-width: 640px) {
  .bout-stage { height: 15rem; }
  .bout-name-text { font-size: 0.95rem; }
  .bout-group-name, .bout-stage.mini .bout-group-name { font-size: 1.25rem; }
  .bout-group.has-name .bout-name-text { font-size: 0.75rem; }
  .bout-stage-inner .vs, .bout-stage.mini .vs { font-size: 2rem; }
  .bout-stage-inner { gap: 0; padding: 0; }
}

/* ---- Combined roster page ---- */
.roster-tabs {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin: 1.5rem 0 1rem;
}
/* Applies to both <button> and <a>: the Info page's Seasons pill is a real
   link, and it has to sit level with the buttons beside it. The site-wide
   a:not(...) chain would otherwise colour it red, so the weight is matched
   here. */
.roster-tab,
a.roster-tab:not(.btn):not(.nav-link):not(.apply-link):not(.wordmark) {
  font-family: var(--mono); font-size: 0.75rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--muted);
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.5rem;
}
.roster-tab:hover, a.roster-tab:hover { border-color: var(--accent); color: var(--fg); }
a.roster-tab { text-decoration: none; }
/* The selected tab inverts, matching the mock-up. */
.roster-tab.is-active {
  background: var(--paper, #EDE7DA); color: #14100E; border-color: transparent;
}
.roster-tab-count {
  font-size: 0.68rem; opacity: 0.7;
  padding: 0 0.3rem; border-radius: 3px;
  border: 1px solid currentColor;
}

/* Staff have no picture, so they get a plainer card than the mugshot wall. */
.staff-grid {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  margin-top: 0.5rem;
}
.staff-card {
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); padding: 1.1rem 1.25rem;
}
.staff-card .kicker { margin: 0 0 0.2rem; }
.staff-card h2 { margin: 0; font-size: 1.6rem; }
.staff-card p { margin: 0.4rem 0 0; color: var(--muted); font-size: 0.9rem; }

@media (max-width: 600px) {
  .roster-tab { padding: 0.5rem 0.8rem; font-size: 0.68rem; }
}

/* ---- The Callings ---- */
.calling-grid {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  margin: 1.75rem 0;
}
.calling-tile {
  position: relative;
  display: flex; flex-direction: column;
  min-height: 15rem;
  padding: 1.1rem 1.1rem 1.2rem;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface);
  text-decoration: none;
}
.calling-tile:hover { border-color: var(--accent); background: var(--elevated); }

/* The numeral is the tile. Everything else sits under it. */
.calling-num {
  font-family: var(--display);
  font-size: 3.4rem; line-height: 1;
  letter-spacing: 0.02em;
  color: var(--fg);
}
/* margin-top:auto pushes the caption block to the foot of the tile, so
   numerals of different widths still line up with each other. */
.calling-kicker {
  margin-top: auto;
  font-family: var(--mono); font-size: 0.65rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
}
.calling-name {
  font-family: var(--display); font-size: 1.9rem;
  letter-spacing: 0.03em; line-height: 1.1;
  margin-top: 0.2rem;
  /* The whole tile is a link, so the name was inheriting the site-wide link
     red. The name is the thing you read on this tile -- it should be the
     brightest text on it, not the most decorated. */
  color: var(--fg);
  /* Long names break rather than pushing the tile wider. */
  overflow-wrap: anywhere;
}
.calling-date {
  font-family: var(--mono); font-size: 0.7rem;
  color: var(--concrete); margin-top: 0.45rem;
}

.calling-badge {
  position: absolute; top: 1.1rem; right: 1.1rem;
  font-family: var(--mono); font-size: 0.6rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.2rem 0.45rem;
  border: 1px solid var(--border); border-radius: 2px;
  color: var(--muted);
}
.calling-badge.is-closed { color: var(--muted); }
.calling-badge.is-next { color: var(--marquee-red); border-color: var(--marquee-red); }
.calling-badge.is-reckoning { color: #C9A227; border-color: #C9A227; }
/* A Reckoning is the night the cycle pays off, so its tile is marked. */
.calling-tile.is-reckoning-tile { border-color: color-mix(in srgb, #C9A227 45%, transparent); }
.calling-tile.is-reckoning-tile .calling-num { color: #C9A227; }

@media (max-width: 600px) {
  .calling-grid { grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: 0.6rem; }
  .calling-tile { min-height: 11rem; padding: 0.8rem; }
  .calling-num { font-size: 2.4rem; }
  .calling-name { font-size: 1.35rem; }
}

/* ---- Drop a Marker ---- */
.marker-block {
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); margin: 0.9rem 0;
}
.marker-block > summary {
  cursor: pointer; padding: 0.7rem 1rem;
  font-family: var(--mono); font-size: 0.7rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
  list-style: none;
}
.marker-block > summary::-webkit-details-marker { display: none; }
.marker-block > summary::before { content: "▸"; margin-right: 0.5rem; color: var(--accent); }
.marker-block[open] > summary::before { content: "▾"; }
.marker-block > summary:hover { color: var(--fg); }
.marker-body { padding: 0 1rem 1rem; }

.marker-sides { display: grid; gap: 0.5rem; margin-bottom: 0.9rem; }
.marker-side {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: 0.7rem; padding: 0.55rem 0.7rem;
  border: 1px solid var(--border); border-radius: 4px; cursor: pointer;
}
.marker-side.is-picked { border-color: var(--accent); }
.marker-side-name { font-family: var(--display); font-size: 1.05rem; }
/* The split, shown as a bar. Counts only -- never anyone's time guess. */
.marker-side-bar { height: 0.4rem; background: var(--elevated); border-radius: 1px; overflow: hidden; }
.marker-side-bar > span { display: block; height: 100%; background: var(--accent); }
.marker-side-pct { font-family: var(--mono); font-size: 0.72rem; color: var(--muted); min-width: 2.5rem; text-align: right; }

.marker-row { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 0.8rem; }
.marker-row label { display: flex; flex-direction: column; gap: 0.2rem; }
.marker-hint { font-family: var(--mono); font-size: 0.65rem; color: var(--concrete); }
.marker-shut { font-family: var(--mono); font-size: 0.72rem; color: var(--concrete); margin: 0 0 0.7rem; }
.marker-result { margin: 0.9rem 0 0; padding-top: 0.8rem; border-top: 1px solid var(--border); font-size: 0.9rem; }

/* ---- Header alert dot ----
   Something is waiting behind this link. Deliberately a dot rather than a
   number: the count is on the page you land on, and a number in the header
   competes with the label beside it. */
.nav-dot {
  display: inline-block;
  width: 0.4rem; height: 0.4rem;
  border-radius: 50%;
  background: var(--marquee-red);
  vertical-align: super;
  margin-left: 0.3rem;
  /* Stops the dot being squeezed out when the nav is tight. */
  flex: 0 0 auto;
}
/* A quiet pulse. Slow enough not to nag, and it stops after a few passes so
   it never becomes background noise on a page left open. */
@media (prefers-reduced-motion: no-preference) {
  .nav-dot { animation: nav-dot-pulse 2s ease-out 3; }
}
@keyframes nav-dot-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(225, 29, 46, 0); }
  50%      { box-shadow: 0 0 0 3px rgba(225, 29, 46, 0.35); }
}
