/* ============================================================================
   Aden — components. Built once, used everywhere.
   ========================================================================= */

/* --------------------------------------------------------- the page head -- */
/* Aden is pale text on pale mist and the head sits straight on the plate, so it
   carries its own veil, sized to the block. A panel-wide gradient is not enough:
   copy near the top of a tall panel lands in its falloff. (site prompt 9)
   The measured effect: the section kicker went from 1.27:1 to over 9:1. */
/* The padding is the veil's falloff. The gradient below reaches zero exactly on
   the block's own edges, so the copy has to sit well inside them or it lands in
   the thin part — which is why the vertical padding is generous. */
.page-head {
  position: relative;
  z-index: 3;
  padding: clamp(var(--s-6), 5vw, var(--s-8)) clamp(var(--s-5), 6vw, var(--s-9));
  margin-bottom: var(--s-5);
}
/* Two feathers, one element: the background fades out top and bottom, the mask
   fades out left and right. The veil therefore reaches zero opacity on all four
   of its own edges and reads as a band of mist rather than a plate laid on the
   art. The old 52% x 150% radial overshot every edge — it was still above 50%
   opacity where the box ended, which is what drew the dark rectangle across the
   plate on every page. */
.page-head::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(11, 16, 21, 0)   0%,
    rgba(11, 16, 21, .52) 14%,
    rgba(11, 16, 21, .80) 30%,
    rgba(11, 16, 21, .80) 66%,
    rgba(11, 16, 21, .46) 84%,
    rgba(11, 16, 21, 0)   100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, .38) 12%, #000 33%, #000 67%, rgba(0, 0, 0, .38) 88%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, .38) 12%, #000 33%, #000 67%, rgba(0, 0, 0, .38) 88%, transparent 100%);
  pointer-events: none;
}
.page-head > * { position: relative; }

/* The veil should read as weather over the plate, not as a slab behind the
   copy, so it spans the full width of whatever body it sits in rather than the
   text column — the wider the box, the longer its falloff. */
.panel .page-head {
  margin-inline: calc(-1 * clamp(var(--s-4), 4vw, var(--s-9)));
  padding-block: clamp(var(--s-5), 3vw, var(--s-7));
}
.page__body > .page-head { margin-inline: calc(-1 * clamp(var(--s-4), 3vw, var(--s-6))); }
.page-head .lockup:last-child { margin-bottom: 0; }

/* ------------------------------------------------- the section title lockup */
/* Centred Cinzel caps, then a 1 px rule broken by a diamond notch at its
   centre. Every panel and every page opens with this. (site prompt 6.1) */
.lockup { text-align: center; margin: 0 0 clamp(var(--s-5), 3vw, var(--s-7)); }

.lockup__kicker {
  display: block;
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--s-3);
}

.lockup__title {
  font-size: var(--t-3xl);
  font-weight: 400;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--paper);
  text-shadow: var(--text-shadow);
  /* the tracking adds a trailing gap; nudge back so the title reads centred */
  text-indent: var(--track-wide);
  overflow-wrap: break-word;
}

.lockup__rule {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s-3);
  margin-top: var(--s-4);
  color: var(--line-strong);
}
.lockup__rule::before,
.lockup__rule::after {
  content: "";
  height: 1px;
  flex: 1 1 auto;
  max-width: 15rem;
  background: linear-gradient(90deg, transparent, currentColor);
}
.lockup__rule::after { background: linear-gradient(270deg, transparent, currentColor); }
.lockup__rule svg { width: 34px; height: 10px; flex: 0 0 auto; color: var(--cream-edge); }

.lockup__lede {
  margin: var(--s-4) auto 0;
  max-width: 62ch;
  font-size: var(--t-md);
  color: var(--text-dim);
  text-shadow: var(--text-shadow);
}

/* --------------------------------------------------------------- buttons -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: .72rem 1.5rem;
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--gold-text);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease), box-shadow .18s var(--ease);
}
/* Hover darkens the plate and brightens the edge, so the label gains contrast.
   Never lighten fill and label together. (shared spec 10a rule 5) */
.btn:hover {
  background: rgba(10, 15, 19, .72);
  border-color: var(--cream);
  color: var(--cream);
  box-shadow: 0 0 0 1px rgba(255, 240, 181, .22);
}
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; box-shadow: none;
  background: transparent; border-color: var(--line); color: var(--text-faint);
}

/* the one saturated thing on a screen */
.btn--primary { background: var(--cream); border-color: var(--cream); color: var(--ink); }
.btn--primary:hover {
  background: var(--cream-edge);          /* darken the plate                */
  border-color: #ffffff;
  color: var(--ink);                      /* ink stays ink — 8.4:1           */
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .5);
}
.btn--ghost { border-color: var(--line); color: var(--text); }
.btn--ghost:hover { border-color: var(--line-strong); color: var(--paper); }
.btn--sm { padding: .42rem .85rem; font-size: var(--t-micro); }
.btn--block { width: 100%; }
.btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* The four controls that close the About panel, in the slot the four figures
   used to fill. They are bigger than a .btn because they are the panel's exit
   and nothing else competes at that height: the glyph sits above the label, so
   the target is a plate rather than a line of type. The glass plate is the
   tile's, not the button's — these sit straight on the panel art. */
.btn--action {
  flex-direction: column;
  gap: var(--s-3);
  min-height: 7.5rem;
  padding: var(--s-5) var(--s-4);
  background: var(--veil-tile);
  border-color: var(--glass-edge);
  text-align: center;
  backdrop-filter: blur(3px);
}
/* Cream plate, ink label — the one place on this panel that inverts, because
   these are the things to do. 8.4:1 either way. */
.btn--action:hover,
.btn--action:focus-visible {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--ink);
  box-shadow: var(--shadow-tile);
}
.btn--action .btn__action-glyph {
  width: 30px; height: 30px;
  transition: transform .2s var(--ease);
}
.btn--action:hover .btn__action-glyph { transform: translateY(-2px); }
.btn__action-label { font-size: var(--t-sm); letter-spacing: var(--track-micro); }
@media (prefers-reduced-motion: reduce) {
  .btn--action .btn__action-glyph { transition: none; }
}

/* the download control: a glyph, a silhouette, and a hover that does something */
.btn--download {
  position: relative;
  padding: .9rem 2.1rem .9rem 1.6rem;
  font-size: var(--t-base);
  background: var(--cream);
  border-color: var(--cream);
  color: var(--ink);
  clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
  overflow: hidden;
}
.btn--download .btn__glyph {
  width: 20px; height: 20px;
  transition: transform .22s var(--ease);
}
.btn--download::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 255, 255, .55) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform .55s var(--ease);
}
.btn--download:hover { background: var(--cream-edge); border-color: #ffffff; color: var(--ink); }
.btn--download:hover::before { transform: translateX(120%); }
.btn--download:hover .btn__glyph { transform: translateY(2px); }
@media (prefers-reduced-motion: reduce) {
  .btn--download::before { display: none; }
}

/* ----------------------------------------------------------- glass tiles -- */
/* Translucent white with a 1 px light border; the active one is solid cream
   with dark ink. Hover lifts the border opacity, not the size. (6.2) */
.tile {
  position: relative;
  display: flex; flex-direction: column;
  padding: clamp(var(--s-4), 2vw, var(--s-6));
  background: var(--glass);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-sm);
  color: var(--text);
  text-decoration: none;
  backdrop-filter: blur(3px);
  transition: background .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.tile::before {                 /* the tile's own veil, so copy never floats */
  content: "";
  position: absolute; inset: 0;
  background: var(--veil-tile);
  border-radius: inherit;
  pointer-events: none;
}
.tile > * { position: relative; z-index: 1; }
.tile:hover { border-color: #ffffff; background: rgba(255, 255, 255, .18); box-shadow: var(--shadow-tile); }

.tile--active,
.tile--active:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--ink);
  box-shadow: var(--shadow-tile);
}
.tile--active::before { background: transparent; }
.tile--active .tile__title,
.tile--active .tile__label { color: var(--ink); }

/* A control inside a cream tile inverts: gold-on-cream is unreadable, and the
   hover still darkens the plate rather than lightening it. */
.tile--active .btn {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
.tile--active .btn:hover {
  background: rgba(12, 17, 22, 1);
  border-color: rgba(12, 17, 22, 1);
  color: #ffffff;
  box-shadow: 0 0 0 1px rgba(43, 50, 56, .5);
}

.tile__icon { width: 40px; height: 40px; color: var(--gold-text); margin-bottom: var(--s-3); }
.tile--active .tile__icon { color: var(--ink); }

.tile__title {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--paper);
  text-wrap: balance;
}
.tile__label {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-faint);
}


/* --------------------------------------------------------------- crests --- */
/* Derived, not stored: a diamond plate with an initial, hue seeded from the
   name and kept inside the palette band. Ships no image files. */
.crest {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--crest-size, 40px); height: var(--crest-size, 40px);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-sm);
  background: var(--crest-bg, var(--glass));
  color: var(--crest-fg, var(--paper));
  font-size: calc(var(--crest-size, 40px) * .40);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
  text-transform: uppercase;
  user-select: none;
}
.crest--lg { --crest-size: 54px; }
.crest--sm { --crest-size: 28px; }

/* --------------------------------------------------------------- badges --- */
.badge {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .16rem .5rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: var(--t-micro);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
}
.badge--pinned { color: var(--cream); border-color: var(--cream-edge); }
.badge--locked { color: var(--text-faint); }
.badge--staff  { color: var(--gold-text); background: rgba(255, 240, 181, .10); border-color: var(--cream-edge); font-weight: 600; }
.badge--ok     { color: var(--ok); border-color: rgba(169, 220, 180, .5); }
.badge--warn   { color: var(--danger); border-color: rgba(255, 155, 143, .5); }
.badge svg { width: 11px; height: 11px; }

.pill {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .28rem .7rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-dim);
}
.pill__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.pill--online { color: var(--ok); border-color: rgba(169, 220, 180, .48); }
.pill--maintenance { color: var(--gold-text); border-color: var(--cream-edge); }
.pill--offline { color: var(--danger); border-color: rgba(255, 155, 143, .48); }

/* ------------------------------------------------------------- stat plate - */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.stat-plate {
  padding: var(--s-4);
  background: rgba(16, 22, 27, .55);
  text-align: center;
}
.stat-plate__value {
  display: block;
  font-size: var(--t-xl);
  font-weight: 600;
  color: var(--gold-text);
  line-height: 1.1;
}
.stat-plate__label {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-dim);
}

/* --------------------------------------------------------------- tables --- */
.table-wrap {
  width: 100%;
  overflow-x: auto;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
}
.table { width: 100%; border-collapse: collapse; font-size: var(--t-base); }
.table th, .table td {
  padding: .62rem var(--s-4);
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
}
.table th {
  position: sticky; top: 0;
  z-index: 1;
  background: rgba(14, 20, 25, .96);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-dim);
}
.table tbody tr:nth-child(odd) { background: rgba(255, 255, 255, .028); }
.table tbody tr:hover { background: rgba(255, 255, 255, .07); }
.table tbody tr:last-child td { border-bottom: 0; }
.table td.num, .table th.num { text-align: right; font-variant-numeric: lining-nums tabular-nums; }
.table .rank { color: var(--gold-text); font-weight: 600; }

.th-sort {
  appearance: none; border: 0; background: transparent; padding: 0;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: .35rem;
}
.th-sort:hover { color: var(--paper); }
.th-sort__arrow { opacity: 0; font-size: .8em; }
.table th[aria-sort] .th-sort { color: var(--cream); }
.table th[aria-sort] .th-sort__arrow { opacity: 1; }

/* ------------------------------------------------------------------ tabs -- */
.tabs {
  display: flex; flex-wrap: wrap;
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  overflow: hidden;
  margin-bottom: var(--s-5);
}
.tab {
  appearance: none; border: 0;
  flex: 1 1 auto;
  min-width: 7.5rem;
  padding: .68rem var(--s-4);
  background: rgba(16, 22, 27, .62);
  color: var(--text-dim);
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  cursor: pointer;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.tab:hover { background: rgba(8, 12, 16, .82); color: var(--paper); }
.tab[aria-selected="true"] { background: var(--cream); color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------- pagination - */
.pager {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-5);
}
.pager__btn {
  appearance: none;
  min-width: 2.3rem;
  padding: .4rem .7rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .05);
  color: var(--text-dim);
  font-size: var(--t-sm);
  cursor: pointer;
  transition: background .16s var(--ease), border-color .16s var(--ease), color .16s var(--ease);
}
.pager__btn:hover:not(:disabled) { background: rgba(10, 15, 19, .7); border-color: var(--line-strong); color: var(--paper); }
.pager__btn[aria-current="page"] { background: var(--cream); border-color: var(--cream); color: var(--ink); font-weight: 600; }
.pager__btn:disabled { opacity: .35; cursor: not-allowed; }
.pager__status { font-size: var(--t-sm); color: var(--text-faint); margin: 0 var(--s-3); }

/* ------------------------------------------------------------ breadcrumbs - */
/* Forum only. Removed from every other page on request. (10a rule 3) */
/* The trail sits at the far left of the head, out in the veil's falloff, so it
   carries a small bed of its own. */
.crumbs {
  position: relative;
  display: inline-flex; flex-wrap: wrap; align-items: center; gap: .45rem;
  margin-bottom: var(--s-4);
  /* the padding is the veil's falloff — see the chip veil above */
  padding: .45rem 1.1rem;
  background: transparent;
  border: 0;
}
.crumbs a, .crumbs span {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--text-faint);
  text-decoration: none;
}
.crumbs a:hover { color: var(--cream); }
.crumbs [aria-current="page"] { color: var(--paper); }
.crumbs__sep { color: var(--line-strong); }

/* --------------------------------------------------------- states, skels -- */
.state {
  display: flex; flex-direction: column; align-items: center; gap: var(--s-3);
  padding: var(--s-8) var(--s-4);
  text-align: center;
  color: var(--text-dim);
}
.state svg { width: 34px; height: 34px; color: var(--text-faint); }
.state__title { font-family: var(--font-display); font-size: var(--t-md); letter-spacing: .1em; text-transform: uppercase; color: var(--paper); }

.skeleton {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .12) 50%, rgba(255, 255, 255, .05) 75%);
  background-size: 240% 100%;
  animation: skel 1.25s linear infinite;
}
@keyframes skel { to { background-position: -240% 0; } }
.skeleton--line { height: 1rem; margin-bottom: var(--s-3); }
.skeleton--row { height: 3.6rem; margin-bottom: var(--s-2); }
.skeleton--tile { height: 11rem; }

/* --------------------------------------------------------------- dialog --- */
dialog.modal {
  width: min(760px, calc(100vw - 2rem));
  max-height: calc(100vh - 3rem);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, rgba(26, 34, 40, .985), rgba(20, 26, 31, .99));
  color: var(--text);
  box-shadow: var(--shadow-pop);
  overflow: auto;
}
dialog.modal::backdrop { background: rgba(10, 15, 19, .74); backdrop-filter: blur(3px); }

/* Info variant — an About card, opened large and centred.
   The card it came from is a 200 px plate; this is the same content at reading
   size, so the plate has to look like it GREW out of the card rather than
   appearing on top of it. That is the whole animation: it starts at .94 and a
   little low, and settles.

   A transition, not a keyframe animation, because it has to run in both
   directions — `data-enter` is flipped on by info-dialog.js one frame after
   showModal() and flipped off before close(), which waits for `transitionend`.
   A keyframe animation would play on the way in and snap on the way out. */
dialog.modal--info {
  width: min(46rem, calc(100vw - 2rem));
  max-height: min(78vh, 40rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;                 /* the body is the scroller, not the plate */
  opacity: 0;
  transform: translateY(14px) scale(.94);
  transition: opacity .22s var(--ease), transform .26s var(--ease);
}
dialog.modal--info[data-enter="true"] { opacity: 1; transform: none; }
dialog.modal--info::backdrop { opacity: 0; transition: opacity .22s var(--ease); }
dialog.modal--info[data-enter="true"]::backdrop { opacity: 1; }

.modal--info .modal__head { align-items: center; flex: 0 0 auto; }
.modal--info .modal__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal--info .modal__body:focus-visible { outline: none; }

.modal__lockup { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.modal__icon { display: flex; flex: 0 0 auto; color: var(--gold-text); }
.modal__glyph { width: 26px; height: 26px; }
.modal__title { font-size: var(--t-xl); text-indent: 0; }

@media (prefers-reduced-motion: reduce) {
  dialog.modal--info,
  dialog.modal--info::backdrop { transition: none; }
  dialog.modal--info { opacity: 1; transform: none; }
}

/* Auth variant — Log in / Register over the page.
   Narrower than the checkout dialog: it carries the same deck as the auth page
   and .auth-column is 38rem there, so the form keeps the measure it was drawn
   at rather than stretching to a 760 px plate. */
dialog.modal--auth { width: min(38rem, calc(100vw - 2rem)); }

/* The deck's switch is its own heading, so on those two panes the head is just
   the close control and must not reserve a title's worth of space. */
.modal--auth .modal__head[data-bare="true"] {
  padding: var(--s-3) var(--s-3) 0;
  justify-content: flex-end;
}

/* the head already sets the top margin */
.modal--auth .modal__body > .lockup__lede { margin-top: 0; }

.modal__head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-4);
  padding: var(--s-5) var(--s-6) 0;
}
.modal__body { padding: var(--s-5) var(--s-6) var(--s-6); }
.modal__close {
  appearance: none; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .06); color: var(--text-dim);
  width: 34px; height: 34px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.modal__close:hover { background: rgba(10, 15, 19, .7); color: var(--paper); border-color: var(--line-strong); }
.modal__close svg { width: 15px; height: 15px; }

/* ---------------------------------------------------------------- toast --- */
.toast-host {
  position: fixed;
  left: 50%; bottom: var(--s-6);
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: grid; gap: var(--s-2);
  width: min(420px, calc(100vw - 2rem));
  pointer-events: none;
}
.toast {
  padding: var(--s-3) var(--s-4);
  background: rgba(20, 27, 32, .96);
  border: 1px solid var(--line);
  border-left: 3px solid var(--cream);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-pop);
  font-size: var(--t-base);
  color: var(--paper);
}
.toast--error { border-left-color: var(--danger); }

/* ------------------------------------------------------------ misc bits --- */
.notice {
  display: flex; align-items: flex-start; gap: var(--s-3);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-left: 3px solid var(--cream-edge);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .05);
  color: var(--text-dim);
  font-size: var(--t-base);
}
.notice svg { width: 17px; height: 17px; flex: 0 0 auto; margin-top: .18rem; color: var(--gold-text); }
.notice--ok { border-left-color: var(--ok); }
.notice strong { color: var(--paper); font-weight: 600; }

.divider { height: 1px; background: var(--line-soft); margin: var(--s-6) 0; border: 0; }

.stack   { display: grid; gap: var(--s-4); }
.stack-5 { display: grid; gap: var(--s-5); }
.row     { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.row--end { justify-content: flex-end; }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap;
  margin-bottom: var(--s-4);
}
.section-head h2, .section-head h3 {
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--paper);
}

.meta-num { font-variant-numeric: lining-nums tabular-nums; }
.text-dim { color: var(--text-dim); }
.text-faint { color: var(--text-faint); }
.gold { color: var(--gold-text); }

/* ------------------------------------------------------------- back link -- */
/* One control, top-left of every sub-page. It carries no border and no plate of
   its own: the veil behind it is the same two-feather build the page headers
   use — a vertical gradient that fades to nothing top and bottom, masked by a
   horizontal one that fades to nothing left and right — so it dissolves into
   the art instead of ending on a line. The blur belongs to the veil, and the
   mask clips it too, so even the softening fades out at the edges.

   The arrow is the animation: at rest the shaft is a stub beside the chevron,
   and on hover it draws itself out to full length (a dash offset, not a width
   change, so nothing reflows). */
.back-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
  /* the padding is the veil's falloff, so it is wider than a bordered control */
  padding: .55rem 1.7rem .55rem 1.4rem;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: color .18s var(--ease);
}
/* The chip veil, shared by the back control and the forum trail: no border and
   no plate, just a gradient that fades to nothing top and bottom, masked by one
   that fades to nothing left and right, with the blur inside the mask so even
   the softening dissolves at the edges. Anything that sits as a small chip
   straight on the art wears this rather than a bordered slab. */
.back-btn::before,
.crumbs::before {
  content: "";
  position: absolute;
  inset: -.5rem -1rem;
  z-index: -1;
  background: linear-gradient(180deg,
    rgba(11, 16, 21, 0)   0%,
    rgba(11, 16, 21, .46) 22%,
    rgba(11, 16, 21, .74) 40%,
    rgba(11, 16, 21, .74) 62%,
    rgba(11, 16, 21, .40) 80%,
    rgba(11, 16, 21, 0)   100%);
  -webkit-backdrop-filter: blur(7px);
          backdrop-filter: blur(7px);
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, .35) 12%, #000 32%, #000 68%, rgba(0, 0, 0, .35) 88%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, .35) 12%, #000 32%, #000 68%, rgba(0, 0, 0, .35) 88%, transparent 100%);
  /* the veil sits under full strength so hover has somewhere to go — a
     background gradient is not reliably interpolatable, opacity always is */
  opacity: .84;
  transition: opacity .18s var(--ease);
  pointer-events: none;
}
/* Hover deepens the veil and brightens the label — the plate never lightens
   under the copy. (shared spec 10a rule 5) */
.back-btn:hover { color: var(--cream); }
.back-btn:hover::before,
.back-btn:focus-visible::before { opacity: 1; }

/* The trail is a shorter chip than the back control, so its veil is tighter.
   Declared here, after the shared rule, or the shared inset wins on order. */
.crumbs::before { inset: -.35rem -.8rem; }

.back-btn__label {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
}

.back-btn__arrow { width: 34px; height: 12px; flex: 0 0 auto; overflow: visible; }

/* 30 units of shaft, 22 of it held back, leaves an 8-unit stub at the head. */
.back-btn__tail {
  stroke-dasharray: 30;
  stroke-dashoffset: 22;
  transition: stroke-dashoffset .32s var(--ease);
}
.back-btn__head { transition: transform .32s var(--ease); }

.back-btn:hover .back-btn__tail,
.back-btn:focus-visible .back-btn__tail { stroke-dashoffset: 0; }
.back-btn:hover .back-btn__head,
.back-btn:focus-visible .back-btn__head { transform: translateX(-2px); }

.back-btn:active { transform: translateX(-2px); }

@media (prefers-reduced-motion: reduce) {
  .back-btn__tail { stroke-dashoffset: 0; }
}

/* ------------------------------------------------------------- the swap --- */
/* Statistics changes table and Rules changes document without either panel
   changing size, which is exactly why the change needs saying: the tab lights
   up and nothing else moves. The incoming content rises the last few pixels
   into a box that was already there.

   An animation rather than a transition: the node is new on every change, so
   there is no previous state to transition from. Re-adding the class after a
   forced reflow is what replays it when you come back to a tab you have
   already seen. */
@keyframes panel-swap-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.is-entering { animation: panel-swap-in .30s var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  .is-entering { animation: none; }
}
