/* Genesis Project — "Signal" visual direction.
   Obsidian ground + amber signal accent; full-bleed screenshots carry the
   hero and highlight moments. Unbounded for display type, Manrope for
   reading, IBM Plex Mono for the technical/data-feed details (dates, ids,
   credits labels) — a deliberate nod to transmission without any literal
   C64 pastiche. */

:root {
  /* Four-step ladder from the outer void to a nested box, each one a clear
     step lighter than the last so a container actually reads as a container
     instead of blending into whatever it sits on:
     --canvas (body, behind the page) < --bg (the page sheet itself)
     < --bg-card (a box on the page) < --bg-raised (an input inside a box). */
  --canvas: #050506;
  --bg: #101216;
  --bg-raised: #23262c;
  --bg-card: #1b1d22;
  --fg: #f3efe7;
  --fg-soft: #b9b4a7;
  --fg-mute: #7d786d;
  --line: #34373e;
  --accent: #ffb020;
  --accent-dim: rgba(255, 176, 32, 0.14);
  --accent-ink: #1a1200;
  --radius: 14px;
  --radius-sm: 8px;
  --gutter: clamp(20px, 5vw, 64px);
  --measure: 68ch;
  --shell-max: 1280px;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--canvas);
  color: var(--fg);
  font-family: 'Manrope', system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
/* Everything below the nav sits on one visible "sheet", distinct from the
   canvas behind it — so the page reads as one contained object instead of
   a stack of cards floating in open space. A flex column that stretches to
   fill the viewport (body is the flex column above), with the footer's
   margin-top:auto pushing it to the bottom of that sheet: on a short page
   the footer lands flush with the viewport bottom instead of floating
   halfway up; on a tall page it just follows the content as normal. */
.page-shell {
  background: var(--bg);
  max-width: var(--shell-max);
  margin-inline: auto;
  box-shadow: 0 40px 100px -32px rgba(0, 0, 0, 0.7);
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  width: 100%;
}
@media (min-width: 860px) {
  .page-shell { margin-block: 20px; border-radius: 20px; overflow: hidden; }
}
img { max-width: 100%; display: block; }
a { color: inherit; }
h1, h2, h3, h4 { font-family: 'Unbounded', sans-serif; text-wrap: balance; margin: 0; line-height: 1.08; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
/* A Font Awesome glyph sitting inline with a heading — sized well under the
   heading's own (often very large) font-size so it reads as an accent, not
   a second headline. Every other icon spot (buttons, chips, badges) is
   already an inline-flex row with its own gap, so this is the one place
   that needs explicit sizing rather than relying on flex + a literal space. */
h1 i, h2 i, h3 i, h4 i { font-size: 0.7em; color: var(--accent); margin-right: 0.2em; }
/* width:100% guards against a flexbox quirk: a flex item with auto inline
   margins (this element, when used directly as a child of the .page-shell
   column rather than nested inside a .plate/.header) sizes to fit-content
   instead of stretching, unless it already has an explicit width. */
.container { width: 100%; max-width: 1180px; margin-inline: auto; padding-inline: var(--gutter); }
.eyebrow {
  font-family: 'IBM Plex Mono', monospace;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.72rem;
  color: var(--accent);
}
.mono { font-family: 'IBM Plex Mono', monospace; }
.lede { color: var(--fg-soft); max-width: var(--measure); font-size: 1.05rem; line-height: 1.65; }

/* ---- Nav ----
   The bar itself (.site-nav) stays full-bleed and sticky; .nav-inner caps
   its content at the same width as .page-shell so the logo/menu line up
   with the visible edges of the page sheet instead of the screen edges. */

.site-nav {
  position: sticky; top: 0; z-index: 40;
  background: linear-gradient(to bottom, rgba(5,5,6,0.92), rgba(5,5,6,0.75));
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
}
.site-nav.solid { border-bottom-color: var(--line); }
.nav-inner {
  max-width: var(--shell-max); margin-inline: auto; position: relative;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 16px; flex-wrap: wrap; padding: 18px var(--gutter);
}
.wordmark {
  font-family: 'Unbounded', sans-serif; font-weight: 800; font-size: 1.05rem;
  letter-spacing: 0.01em; white-space: nowrap;
}
.wordmark span { color: var(--accent); }
.nav-links {
  display: flex; gap: 4px; align-items: center; flex-wrap: nowrap;
  max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.nav-links a {
  text-decoration: none; font-size: 0.92rem; font-weight: 600; color: var(--fg-soft);
  padding: 8px 14px; border-radius: 99px; transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.nav-links a:hover, .nav-links a.active { color: var(--fg); background: var(--bg-card); }
.nav-links a.csdb { color: var(--accent); }
.nav-links .fa-arrow-up-right-from-square { font-size: 0.75em; margin-left: 2px; }

/* The hamburger only ever appears/collapses .nav-links once site.js has
   added .js-nav to <html> (confirming a click handler actually got wired
   up) — without it, .nav-toggle stays display:none and .nav-links renders
   inline exactly as it always did, so a broken or blocked script can't
   trap mobile visitors behind a button nothing can open. */
.nav-toggle { display: none; }
@media (max-width: 760px) {
  .js-nav .nav-toggle {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; cursor: pointer;
    border: 1px solid var(--line); border-radius: var(--radius-sm); background: transparent; color: var(--fg);
  }
  .nav-toggle .icon-close { display: none; }
  .nav-toggle[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
  .nav-toggle[aria-expanded="true"] .icon-open { display: none; }
  .nav-toggle[aria-expanded="true"] .icon-close { display: block; }
  .js-nav .nav-links {
    display: none;
  }
  .js-nav .nav-links.open {
    display: flex; flex-direction: column; align-items: stretch;
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--bg); border-bottom: 1px solid var(--line);
    padding: 10px var(--gutter) 18px; gap: 2px; max-width: none; overflow-x: visible;
  }
  .js-nav .nav-links.open a { padding: 12px 14px; border-radius: var(--radius-sm); }
}

/* ---- Buttons / chips ---- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 22px; border-radius: 99px; font-weight: 700; font-size: 0.92rem;
  text-decoration: none; border: 1px solid var(--line);
}
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-ghost { color: var(--fg); }
.btn-ghost:hover { border-color: var(--accent); }
.btn-sm { padding: 8px 14px; font-size: 0.82rem; }
.btn.disabled { opacity: 0.35; pointer-events: none; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid rgba(255,176,32,0.45); color: var(--accent);
  font-family: 'IBM Plex Mono', monospace; font-size: 0.78rem;
  padding: 6px 12px; border-radius: 99px;
}
.tag {
  font-family: 'IBM Plex Mono', monospace; font-size: 0.7rem; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--fg-mute);
}
.badge {
  display: inline-flex; align-items: center; gap: 5px; font-family: 'IBM Plex Mono', monospace;
  font-size: 0.72rem; background: var(--accent-dim); color: var(--accent);
  padding: 4px 10px; border-radius: 99px; white-space: nowrap;
}
/* Distinguished from an achievement badge (a compo placing) — this one is
   CSDb's community rating, so it gets a neutral outline instead of solid amber. */
.badge-rating { background: transparent; border: 1px solid var(--fg-mute); color: var(--fg-soft); }

/* ---- Page headers (compact — no full-bleed art; CSDb screenshots are
   384x272 and look rough blown up to a cinematic hero) ---- */
.chips { display: flex; gap: 10px; flex-wrap: wrap; }
.actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* ---- Plates / sections ---- */
.plate { padding-block: clamp(48px, 8vw, 96px); border-bottom: 1px solid var(--line); }
.plate.tight { padding-block: clamp(32px, 5vw, 56px); }
.plate-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 32px; flex-wrap: wrap; }
.plate-head h2 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); }
.plate-head .see-all { font-weight: 700; font-size: 0.9rem; color: var(--accent); text-decoration: none; white-space: nowrap; }

/* ---- Cards & grids ---- */
.grid { display: grid; gap: 20px; }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 980px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .grid-3, .grid-4 { grid-template-columns: 1fr; } }

.card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; text-decoration: none; color: var(--fg); display: flex; flex-direction: column;
  transition: border-color 0.15s, transform 0.15s;
}
a.card:hover { border-color: var(--accent); transform: translateY(-2px); }
.card .thumb { aspect-ratio: 4/3; background: var(--canvas); position: relative; overflow: hidden; }
.card .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card .thumb.empty::after {
  content: 'G*P'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: 'Unbounded', sans-serif; font-weight: 800; color: var(--line); font-size: 1.6rem;
}
.card .body { padding: 16px 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.card h3 { font-size: 1.02rem; }
.card .meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* Pinned to the bottom of the card (auto margin eats the leftover flex
   space above it) so credits line up along the same edge across a row of
   cards, whatever else — or how little else — is above them. */
.card .body .credits-line { margin-top: auto; }

/* Who worked on a release — shown wherever a release is listed (timeline,
   grid cards, list rows). G*P members get a gold tint; guests (credited
   people who were never G*P members) stay plain grey. Capped at 2 lines
   with an ellipsis (line-clamp, not a hard text cut) so a release with a
   long credit list — a diskmag issue, say — can't blow out a card's height. */
.credits-line {
  color: var(--fg-mute); font-size: 0.78rem; line-height: 1.4;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  min-height: 2.8em;
}
.credit-guest { color: var(--fg-mute); }
.credit-member { color: var(--accent); }
.credit-dim { color: var(--fg-mute); opacity: 0.55; }

/* ---- Stats band ---- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.stat { background: var(--bg-card); padding: 26px 20px; display: flex; flex-direction: column; gap: 4px; }
.stat .num { font-family: 'Unbounded', sans-serif; font-weight: 800; font-size: clamp(1.6rem, 3vw, 2.2rem); color: var(--accent); }
.stat .label { font-size: 0.82rem; color: var(--fg-soft); }
.stat > i { color: var(--accent); font-size: 1.1rem; margin-bottom: 2px; opacity: 0.85; }
@media (max-width: 760px) { .stats { grid-template-columns: repeat(2, 1fr); } }

/* ---- Member roster ---- */
.roster { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.member-card { padding: 18px 20px; }
.member-card .handle {
  font-family: 'Unbounded', sans-serif; font-weight: 700; font-size: 1.1rem;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
/* Clamped to 2 lines so a member with many roles doesn't stretch their
   card (and the whole grid row along with it) taller than everyone else's. */
.member-card .roles {
  color: var(--fg-soft); font-size: 0.86rem;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.leader-badge { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.former-toggle {
  width: 100%; text-align: left; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-sm); color: var(--fg); padding: 14px 18px; font-weight: 700;
  cursor: pointer; font-family: 'Manrope', sans-serif; font-size: 0.95rem;
  display: flex; justify-content: space-between; align-items: center;
}
.former-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px 20px; padding-top: 18px; }
.former-list li { display: flex; justify-content: space-between; gap: 8px; padding-block: 6px; border-bottom: 1px dashed var(--line); font-size: 0.92rem; color: var(--fg-soft); }
.former-list li b { color: var(--fg); font-weight: 600; }
.former-list a { color: inherit; text-decoration: none; }
.former-list a:hover { color: var(--accent); }
[hidden] { display: none !important; }

/* Compact segmented control — used for the members Grid/List switch. */
.seg-toggle { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; margin: 2px 0 28px; }
.seg-toggle button {
  background: transparent; border: none; color: var(--fg-soft); cursor: pointer;
  font-family: 'IBM Plex Mono', monospace; font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.06em;
  padding: 9px 18px; transition: background 0.15s, color 0.15s;
}
.seg-toggle button + button { border-left: 1px solid var(--line); }
.seg-toggle button:hover { color: var(--fg); }
.seg-toggle button.active { background: var(--accent); color: var(--accent-ink); }
.member-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.member-table th, .member-table td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--line); }
.member-table th {
  font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--fg-mute); font-weight: 600; white-space: nowrap;
}
.member-table th[data-sort] { cursor: pointer; user-select: none; }
.member-table th[data-sort]:hover { color: var(--fg); }
.member-table th.sorted { color: var(--accent); }
.member-table th.sorted::after { content: '▲'; margin-left: 5px; font-size: 0.65em; display: inline-block; }
.member-table th.sorted.sorted-desc::after { content: '▼'; }
.member-table td.mono { font-family: 'IBM Plex Mono', monospace; color: var(--fg-mute); }
.member-table tbody tr:hover { background: var(--bg-card); }
.member-table a { color: var(--fg); text-decoration: none; font-weight: 700; }
.member-table a:hover { color: var(--accent); }
.member-table .leader-badge { margin-left: 6px; padding: 2px 8px; font-size: 0.68rem; }

/* ---- Release type families ---- */
/* Every family-coloured element carries its hue as --fam-h inline; "other"
   (untracked/misc types) gets no --fam-h and keeps the plain card look. */
.type-filters { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0 28px; }
.type-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px solid var(--line); color: var(--fg-soft);
  font-family: 'IBM Plex Mono', monospace; font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 7px 13px; border-radius: var(--radius-sm); cursor: pointer; transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.type-chip .count { color: var(--fg-mute); }
.type-chip:hover { border-color: var(--fg-soft); color: var(--fg); }
.type-chip.active {
  border-color: hsl(var(--fam-h, 39) 55% 42%); color: hsl(var(--fam-h, 39) 75% 78%);
  background: hsl(var(--fam-h, 39) 45% 14%);
}
.type-chip.active .count { color: inherit; opacity: 0.7; }

.card[data-family]:not([data-family="other"]) {
  background: linear-gradient(160deg, hsl(var(--fam-h) 45% 15%) 0%, var(--bg-card) 65%);
  border-color: hsl(var(--fam-h) 32% 28%);
}
.card[data-family]:not([data-family="other"]) .type-tag { color: hsl(var(--fam-h) 70% 72%); }
.release-row[data-family]:not([data-family="other"]) { border-left: 3px solid hsl(var(--fam-h) 50% 40%); padding-left: 11px; }
.release-row[data-family]:not([data-family="other"]) .type-tag { color: hsl(var(--fam-h) 70% 68%); }

/* ---- Release index / table ---- */
/* Search box + Grid/List switch sharing one row — search stretches, the
   switch is pinned to the right instead of falling onto its own line. */
.search-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px; margin-bottom: 28px; }
.search-toolbar .seg-toggle { margin: 0; }
.search-field { position: relative; flex: 1; min-width: 200px; max-width: 480px; }
.search-field i {
  position: absolute; left: 16px; top: 21px; transform: translateY(-50%);
  color: var(--fg-mute); pointer-events: none; font-size: 0.85rem;
}
.search-field input {
  width: 100%; background: var(--bg-card); border: 1px solid var(--line); color: var(--fg);
  padding: 10px 14px 10px 38px; border-radius: 99px; font-family: 'Manrope', sans-serif; font-size: 0.9rem;
}
/* Global search results dropdown (releases.mjs's [data-global-search]) */
.search-results {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
  max-height: 360px; overflow-y: auto; box-shadow: 0 20px 40px -12px rgba(0,0,0,0.6);
}
.search-result {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 16px; text-decoration: none; color: var(--fg); font-size: 0.9rem;
  border-bottom: 1px solid var(--line);
}
.search-result:last-child { border-bottom: none; }
.search-result:hover { background: var(--bg-card); }
.search-result .tag { flex: 0 0 auto; white-space: nowrap; }
.search-empty { padding: 14px 16px; color: var(--fg-mute); font-size: 0.85rem; }
/* Flex, not grid: the date gets a fixed flex-basis and sits last, so it
   always lands in the same RHS column no matter whether the badge before it
   is present or how wide it is — a badge can never push the date around. */
.release-row {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 12px 14px; border-radius: var(--radius-sm); text-decoration: none; color: var(--fg);
}
.release-row:hover { background: var(--bg-card); }
.release-row .thumb { flex: 0 0 64px; width: 64px; height: 48px; border-radius: 6px; background: var(--canvas); overflow: hidden; }
.release-row .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.release-row > div { flex: 1 1 220px; min-width: 0; }
.release-row .name { font-weight: 700; }
/* Flex, not inline text: a type tag plus an achievement badge used to be
   joined with a literal " - ", which could wrap right between them and
   strand the badge, dangling hyphen and all, on its own line. As flex items
   the badge either sits beside the type tag or wraps to a fresh line as a
   whole unit — never split, never left hanging off punctuation. */
.release-row .sub { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; color: var(--fg-mute); font-size: 0.82rem; }
.release-row .credits-line { margin-top: 2px; }
.release-row .badge-cell { flex: 0 0 auto; }
.release-row > .tag { flex: 0 0 90px; text-align: right; white-space: nowrap; }
.year-heading { font-family: 'IBM Plex Mono', monospace; color: var(--accent); font-size: 0.85rem; letter-spacing: 0.1em; margin: 28px 0 8px; padding-top: 8px; border-top: 1px solid var(--line); }
.year-heading:first-child { border-top: none; margin-top: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---- Pagination ---- */
.pagination { display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; margin-top: 36px; }
.page-numbers { display: flex; gap: 6px; flex-wrap: wrap; }
.page-btn, .page-num {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; height: 40px; padding: 0 6px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); color: var(--fg-soft); text-decoration: none;
  font-family: 'IBM Plex Mono', monospace; font-size: 0.85rem; transition: border-color 0.15s, color 0.15s;
}
.page-btn:hover, .page-num:hover { border-color: var(--accent); color: var(--fg); }
.page-num.active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 700; }
.page-btn.disabled { opacity: 0.3; pointer-events: none; }

/* ---- Release / member detail ---- */
/* Reusable containment card — used standalone (Credits) and inside .side-panel (Details). */
.box { background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; }
.box h4 { font-size: 0.95rem; margin-bottom: 10px; }
.credit-groups { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.credit-group .tag { margin-bottom: 8px; display: block; }
.credit-group ul { display: flex; flex-direction: column; gap: 6px; }
.credit-group a { text-decoration: none; font-weight: 600; }
.credit-group a:hover { color: var(--accent); }
.prose p { margin-bottom: 1.1em; color: var(--fg-soft); }
.prose p:last-child { margin-bottom: 0; }
.prose a.ref-link { color: var(--accent); text-decoration: underline; text-decoration-color: rgba(255,176,32,0.4); }

/* Every release page gets the same size screenshot frame, whatever the
   source resolution — almost everything here is native C64 pixel art
   (384x272-ish) but the odd non-C64 release (a PC tool's own screenshot)
   comes in at a completely different resolution and aspect ratio. Rather
   than stretch that to fit, .screenshot-frame fixes the 384:272 ratio and
   object-fit: contain scales *within* it preserving the source's own
   ratio, letterboxing or pillarboxing with the frame's own background
   instead of distorting anything. image-rendering: pixelated keeps
   nearest-neighbour sampling instead of the browser's default blur when a
   small source image is scaled up. */
.screenshot-hero {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 20px; margin-bottom: 32px; max-width: 720px; margin-inline: auto;
}
.screenshot-frame { aspect-ratio: 384 / 272; display: flex; align-items: center; justify-content: center; }
.screenshot-frame img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; image-rendering: pixelated; }

/* align-items: start, not the grid default of stretch — otherwise a short
   left column (a release with one credit) gets stretched to match the
   taller side panel and leaves dead space under its own content. */
.two-col { display: grid; grid-template-columns: 2fr 1fr; gap: 40px; align-items: start; }
@media (max-width: 860px) { .two-col { grid-template-columns: 1fr; } }
.side-panel { display: flex; flex-direction: column; gap: 20px; }
.series-nav { display: flex; flex-direction: column; gap: 10px; }
.series-nav .nav-buttons { display: flex; gap: 6px; }
/* Squared-off and compact, not a pill .btn — a prev/next pair reads as a
   utility control, not a call to action, so it shouldn't compete visually
   with the page's actual buttons (Download, View on CSDb). */
.series-link {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 10px; border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--bg-raised); color: var(--fg-soft);
  font-family: 'IBM Plex Mono', monospace; font-size: 0.78rem; font-weight: 500;
  text-decoration: none; transition: border-color 0.15s, color 0.15s;
}
.series-link:hover { border-color: var(--accent); color: var(--fg); }
.series-link.disabled { opacity: 0.35; pointer-events: none; }
.series-nav select {
  width: 100%; background: var(--bg-raised); border: 1px solid var(--line); color: var(--fg);
  padding: 10px 12px; border-radius: var(--radius-sm); font-family: 'Manrope', sans-serif; font-size: 0.86rem;
}
.kv { display: flex; justify-content: space-between; padding-block: 6px; border-bottom: 1px dashed var(--line); font-size: 0.9rem; }
.kv:last-child { border-bottom: none; }
.kv .k { color: var(--fg-mute); }

/* ---- Timeline (history page) ---- */
.timeline { position: relative; padding-left: 28px; display: flex; flex-direction: column; gap: 28px; }
.timeline::before { content: ''; position: absolute; left: 5px; top: 6px; bottom: 6px; width: 2px; background: var(--line); }
.timeline-item { position: relative; }
.timeline-item::before {
  content: ''; position: absolute; left: -28px; top: 4px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--accent);
}
.timeline-item .year { font-family: 'IBM Plex Mono', monospace; color: var(--accent); font-size: 0.85rem; }
.timeline-item .type-tag { color: hsl(var(--fam-h, 39) 70% 68%); margin-left: 8px; }
.timeline-item h3 { font-size: 1.1rem; margin-top: 4px; }
.timeline-item p { color: var(--fg-soft); margin-top: 6px; }
.timeline-item .credits-line { margin-top: 2px; }

/* The standalone "2026" etc. divider reads bigger than a per-entry date —
   it's a section break, not just another timestamp. */
.timeline .year-heading { font-size: 1.4rem; font-weight: 700; letter-spacing: 0.02em; }

/* History page's mega-timeline: a real icon (gold/silver/bronze trophy, a
   medal, a user-plus, ...) sitting on the spine instead of a plain dot,
   coloured per-event via an inline style. */
.timeline-item.has-icon::before { content: none; }
.timeline-item .timeline-icon {
  position: absolute; left: -30px; top: 1px; width: 16px; text-align: center;
  font-size: 0.85rem; color: var(--accent);
}

/* Upcoming (not-yet-happened) entries on the Parties timeline get a solid
   accent dot instead of the default hollow one, plus a badge by the date. */
.timeline-item.upcoming::before { background: var(--accent); }

/* "Now" divider row: sits in the timeline flow like any other item, marking
   the boundary between upcoming and past entries. */
.timeline-now { position: relative; display: flex; align-items: center; gap: 10px; }
.timeline-now::before {
  content: ''; position: absolute; left: -28px; top: 50%; width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent); transform: translateY(-50%); box-shadow: 0 0 0 3px var(--bg);
}
.timeline-now .line { flex: 1; height: 2px; background: var(--accent); opacity: 0.4; }
.timeline-now .label {
  font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; letter-spacing: 0.12em;
  color: var(--accent); text-transform: uppercase; white-space: nowrap;
}

/* ---- News ---- */
.news-card .date { font-family: 'IBM Plex Mono', monospace; font-size: 0.78rem; color: var(--fg-mute); }

/* ---- Footer ---- */
.site-footer { margin-top: auto; padding: 48px var(--gutter) 64px; display: flex; flex-direction: column; gap: 18px; }
.site-footer .slogans { display: flex; gap: 16px; flex-wrap: wrap; color: var(--fg-mute); font-family: 'IBM Plex Mono', monospace; font-size: 0.8rem; }
.site-footer .bottom { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; color: var(--fg-mute); font-size: 0.82rem; padding-top: 18px; border-top: 1px solid var(--line); }
.site-footer a { color: var(--fg-soft); text-decoration: none; }
.site-footer a:hover { color: var(--accent); }

/* ---- 404 ---- */
.error-page { min-height: 60vh; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 16px; }
