/* ==========================================================================
   Gable Steveson fan archive — design system
   Dark editorial shell, per-discipline accent. Every page sets --accent on
   <body> from the discipline it is showing — Minnesota maroon for folkstyle,
   Olympic gold for freestyle, red for the cage — so colour shifts as you move
   through the career while the shell stays one system.

   The neutrals are pulled a few degrees warm rather than blue-grey, because
   maroon and gold on a cold black read as dirty rather than as warm. Inherited
   from the reference build in ../lana_del_rey and kept deliberately: the shell
   is the part worth reusing, the accents are the part worth replacing.
   ========================================================================== */

:root {
  --bg:        #0b0a0c;
  --bg-raised: #16141a;
  --bg-hover:  #1e1b23;
  --line:      #2a262f;
  --line-soft: #1d1a22;
  --text:      #f0ecee;
  --text-dim:  #a79fa6;
  --text-mute: #756d75;
  --accent:    #d9a441;
  --ink:       #0b0a0c;   /* text on a filled accent */

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  --radius: 10px;
  --maxw: 1240px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }

/* ---------- Type ---------- */
h1, h2, h3 { font-family: var(--serif); font-weight: 600; line-height: 1.15; margin: 0; }
h1 { font-size: clamp(2.2rem, 5vw, 3.6rem); letter-spacing: -0.02em; }
h2 { font-size: clamp(1.5rem, 3vw, 2.1rem); letter-spacing: -0.015em; }
h3 { font-size: 1.15rem; }

.eyebrow {
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.lede { font-size: 1.05rem; color: var(--text-dim); max-width: 62ch; }
.dim { color: var(--text-dim); }
.mute { color: var(--text-mute); }

/* ---------- Header ---------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  background: rgba(11, 10, 12, 0.86);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.topbar-in {
  max-width: var(--maxw); margin: 0 auto; padding: 0 24px;
  height: 62px; display: flex; align-items: center; gap: 28px;
}
.brand { font-family: var(--serif); font-size: 1.15rem; font-weight: 600; letter-spacing: -0.01em; }
.brand span { color: var(--accent); }
.nav { display: flex; gap: 22px; margin-left: auto; align-items: center; }
.nav a {
  font-size: 0.83rem; font-weight: 500; color: var(--text-dim);
  letter-spacing: 0.02em; padding: 6px 0; border-bottom: 1.5px solid transparent;
  transition: color .15s, border-color .15s;
}
.nav a:hover { color: var(--text); }
.nav a.active { color: var(--text); border-bottom-color: var(--accent); }

.nowplaying {
  display: flex; align-items: center; gap: 10px;
  max-width: var(--maxw); margin: 0 auto; padding: 7px 24px 9px;
  font-size: 0.78rem; color: var(--text-dim);
  border-top: 1px solid var(--line-soft);
}
.nowplaying[hidden] { display: none; }
.np-label { font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-mute); }
.np-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--text); }
.np-btn, .np-sound {
  background: none; border: 1px solid var(--line); border-radius: 5px;
  color: var(--text-dim); font-size: 0.7rem; padding: 3px 9px; cursor: pointer;
  font-family: var(--sans); line-height: 1.4;
}
.np-btn:hover, .np-sound:hover { color: var(--text); border-color: var(--text-mute); }
/* Amber while muted: the visitor can't hear anything and needs to know why. */
.np-sound.muted { background: #eab308; border-color: #eab308; color: var(--ink); }
@media (max-width: 640px) { .np-label { display: none; } .nowplaying { padding: 6px 14px 8px; } }

/* ---------- Era rail: the discography as its own navigation ----------------
   One dot per studio record in its own colour, expanding to the album's name on
   hover. Collapsed it is a palette of the catalogue; opened it is a menu. The
   label is in the markup rather than a ::after content string so screen readers
   and search engines get the album names too. */
.rail { display: flex; gap: 5px; align-items: center; }
.rail .dot {
  height: 26px; display: flex; align-items: center;
  /* max-width, not width: `width: auto` is not an animatable value, so a dot
     that expands by width snaps open instead of sliding. */
  min-width: 26px; max-width: 26px; overflow: hidden;
  border: 1px solid var(--line); border-radius: 13px;
  background: color-mix(in srgb, var(--era) 26%, transparent);
  font-size: 0.72rem; font-weight: 600; color: var(--text-dim);
  white-space: nowrap;
  transition: max-width .24s ease, background .15s, color .15s, border-color .15s;
}
.rail .dot span { padding: 0 10px; opacity: 0; transition: opacity .18s; }
.rail .dot:hover, .rail .dot.active {
  max-width: 260px; background: var(--era); border-color: var(--era); color: var(--ink);
}
.rail .dot:hover span, .rail .dot.active span { opacity: 1; }

/* ---------- Hero ---------- */
.hero { position: relative; padding: 76px 0 60px; overflow: hidden; }
.hero::before {
  content: ""; position: absolute; inset: -40% 30% 40% -10%;
  background: radial-gradient(ellipse at center, var(--accent) 0%, transparent 68%);
  opacity: 0.13; pointer-events: none;
}
.hero-grid {
  position: relative; display: grid; gap: 48px;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); align-items: center;
}
.hero h1 { margin-bottom: 18px; }
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 26px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 20px; border-radius: 8px; border: 1px solid var(--line);
  font-size: 0.86rem; font-weight: 600; color: var(--text);
  background: transparent; cursor: pointer; transition: all .15s;
  font-family: var(--sans);
}
.btn:hover { background: var(--bg-hover); border-color: var(--text-mute); }
.btn-accent { background: var(--accent); border-color: var(--accent); color: var(--ink); }
.btn-accent:hover { filter: brightness(1.12); background: var(--accent); }
.btn-sm { padding: 7px 13px; font-size: 0.78rem; }

/* ---------- Sections ---------- */
.section { padding: 62px 0; border-top: 1px solid var(--line-soft); }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; margin-bottom: 30px; flex-wrap: wrap;
}

/* ---------- Album grid ---------- */
.albums { display: grid; gap: 26px; grid-template-columns: repeat(auto-fill, minmax(208px, 1fr)); }
.album-card { display: block; }
.album-art {
  position: relative; aspect-ratio: 1; border-radius: var(--radius);
  overflow: hidden; background: var(--bg-raised); border: 1px solid var(--line);
  transition: transform .22s cubic-bezier(.2,.7,.3,1), border-color .22s;
}
.album-art img { width: 100%; height: 100%; object-fit: cover; }
.album-card:hover .album-art { transform: translateY(-4px); border-color: var(--era); }
.album-art::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 45%;
  background: linear-gradient(transparent, rgba(0,0,0,.75)); opacity: 0; transition: opacity .22s;
}
.album-card:hover .album-art::after { opacity: 1; }
.album-play {
  position: absolute; left: 12px; bottom: 12px; z-index: 2;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--era); color: var(--ink); display: grid; place-items: center;
  font-size: 0.9rem; opacity: 0; transform: translateY(6px); transition: all .22s;
}
.album-card:hover .album-play { opacity: 1; transform: none; }
/* The home hero cover is the page's main call to action, so its play badge is
   always visible rather than waiting for a hover that never happens on touch. */
.hero-art { cursor: pointer; }
.hero-play { opacity: .92; transform: none; width: 54px; height: 54px; font-size: 1.1rem; }
.hero-art:hover .hero-play, .hero-art:focus-visible .hero-play { opacity: 1; }
.hero-art:focus-visible { outline: 2px solid var(--era); outline-offset: 3px; }
.album-meta { margin-top: 12px; }
.album-title { font-family: var(--serif); font-size: 1.08rem; line-height: 1.25; }
.album-sub { font-size: 0.78rem; color: var(--text-mute); margin-top: 3px; }
/* Always-visible actions. A hover-only play button makes a grid of covers look
   inert, which is exactly how this page read before. */
.album-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.act {
  font-size: 0.7rem; font-weight: 600; padding: 4px 10px; border-radius: 5px;
  border: 1px solid var(--line); color: var(--text-dim); background: transparent;
  cursor: pointer; font-family: var(--sans); transition: all .14s;
}
.act:hover { color: var(--text); border-color: var(--text-mute); }
.act-play:hover { color: var(--ink); background: var(--era); border-color: var(--era); }
.act-sp:hover { color: #1db954; border-color: #1db954; }

.badge {
  display: inline-block; padding: 2px 8px; border-radius: 20px;
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  border: 1px solid var(--line); color: var(--text-dim);
}
.badge-full { color: var(--era); border-color: color-mix(in srgb, var(--era) 45%, transparent); }
.badge-partial { color: #eab308; border-color: #6b5a12; }
.badge-none { color: var(--text-mute); }

/* ---------- Album page ---------- */
.album-hero { padding: 54px 0 40px; position: relative; overflow: hidden; }
.album-hero::before {
  content: ""; position: absolute; inset: -60% 0 50% 0;
  background: radial-gradient(ellipse at 20% 100%, var(--accent), transparent 62%);
  opacity: 0.16; pointer-events: none;
}
.album-hero-grid {
  position: relative; display: grid; gap: 40px;
  grid-template-columns: 264px minmax(0, 1fr); align-items: end;
}
.album-hero-art {
  aspect-ratio: 1; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: 0 24px 60px rgba(0,0,0,.55);
}
.facts { display: flex; gap: 26px; flex-wrap: wrap; margin-top: 22px; }
.fact-k { font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-mute); }
.fact-v { font-size: 1rem; font-family: var(--serif); margin-top: 2px; }

/* ---------- Tracklist ---------- */
.tracklist { border-top: 1px solid var(--line-soft); }
.track {
  display: grid; grid-template-columns: 34px 1fr auto auto auto;
  gap: 14px; align-items: center;
  padding: 11px 12px; border-bottom: 1px solid var(--line-soft);
  border-radius: 7px; transition: background .12s;
}
.track.playable { cursor: pointer; }
.track.playable:hover { background: var(--bg-hover); }
.track.unplayable { opacity: 0.42; cursor: default; }
/* Has no official video but is on streaming — dimmed, not disabled, and its
   Spotify link stays permanently visible since there's nothing else to click. */
.track.no-video { opacity: 0.8; }
.track.no-video .track-links { opacity: 1; }
.track-no { font-family: var(--mono); font-size: 0.78rem; color: var(--text-mute); text-align: right; }
.track.playable:hover .track-no { color: var(--accent); }
.track-title { font-size: 0.95rem; }
.track-note {
  font-size: 0.66rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-mute); border: 1px solid var(--line); border-radius: 4px; padding: 1px 6px;
}
.track-dur { font-family: var(--mono); font-size: 0.78rem; color: var(--text-mute); }
.track-links { display: flex; gap: 6px; opacity: 0; transition: opacity .14s; }
.track:hover .track-links { opacity: 1; }
.lnk { font-size: 0.64rem; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 4px; border: 1px solid var(--line); color: var(--text-dim); }
.lnk-sp:hover { color: #1db954; border-color: #1db954; }

/* ---------- Tracks index (the data table) ---------- */
.filterbar {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  margin-bottom: 22px; position: sticky; top: 62px; z-index: 20;
  background: var(--bg); padding: 16px 0; border-bottom: 1px solid var(--line-soft);
}
.search-input {
  flex: 1 1 320px; min-width: 220px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 8px;
  padding: 11px 14px; color: var(--text); font-size: 0.92rem; font-family: var(--sans);
}
.search-input:focus { outline: none; border-color: var(--accent); }
.count { font-size: 0.8rem; color: var(--text-mute); font-family: var(--mono); }

table.data { width: 100%; border-collapse: collapse; }
table.data th {
  text-align: left; font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-mute); font-weight: 700; padding: 8px 12px;
  border-bottom: 1px solid var(--line); cursor: pointer; user-select: none; white-space: nowrap;
}
table.data th:hover { color: var(--text); }
table.data td { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); font-size: 0.9rem; }
table.data tr.playable { cursor: pointer; }
table.data tr.playable:hover td { background: var(--bg-hover); }
table.data tr.unplayable { opacity: 0.4; }
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 9px; vertical-align: middle; }

/* ---------- Gallery ----------
   Masonry via CSS columns, so the original aspect ratios survive instead of
   everything being cropped to a square.

   Column width is deliberately modest. An earlier version asked for two 460px
   columns, which on a 1440px screen renders each photograph seven hundred pixels
   wide — that is a slideshow with a scrollbar, not a gallery, and it makes a set
   of 466 images feel like a set of six. Four columns is enough to see a face and
   few enough to see the frame. */
.gallery { columns: 4 260px; column-gap: 16px; }
@media (min-width: 1800px) { .gallery { columns: 5 260px; } }
@media (max-width: 900px)  { .gallery { columns: 2 150px; column-gap: 12px; } }
.shot {
  break-inside: avoid; margin-bottom: 20px; position: relative;
  border-radius: 10px; overflow: hidden; border: 1px solid var(--line);
  cursor: zoom-in; background: var(--bg-raised);
}
/* height:auto is load-bearing. Every tile carries width/height attributes so the
   layout doesn't jump while images stream in, and those attributes are also a
   presentational hint: with the CSS setting only `width`, the browser uses the
   HEIGHT ATTRIBUTE as the used height and stretches the photograph to it. The
   worst offenders came out 60% too tall. */
.shot img { width: 100%; height: auto; display: block;
  /* aspect-ratio + cover crops the extremes to the clamped shape set inline;
     a tile already inside the bounds gets its true ratio and is not cropped. */
  aspect-ratio: var(--ar, auto); object-fit: cover; object-position: center 30%;
  transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.shot:hover img { transform: scale(1.03); }
.shot-cap {
  position: absolute; inset: auto 0 0 0; padding: 40px 16px 14px;
  background: linear-gradient(transparent, rgba(0,0,0,.88));
  font-size: 0.86rem; line-height: 1.4; opacity: 0; transition: opacity .2s;
}
.shot:hover .shot-cap { opacity: 1; }
/* An image Wikimedia refuses to serve leaves a broken-image glyph, which looks
   far worse than an absent tile — so a failed load removes the tile entirely. */
.shot.broken { display: none; }

/* ---------- Shared bits that outgrew one page ----------
   Both of these were defined inside a single template's scoped <style>, which
   was fine while one page used them. /unreleased now uses both, and a component
   that renders unstyled on its second consumer is a component in the wrong
   file. */
.factgrid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.factcard { background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 15px 17px; }
.factcard-v { font-family: var(--serif); font-size: 1.4rem; line-height: 1.25; margin-top: 4px; }

/* Jump links for the long list pages. */
.jumps { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 6px; }
.jumps a {
  font-size: .74rem; padding: 4px 11px; border-radius: 20px;
  border: 1px solid var(--line); color: var(--text-dim); transition: all .15s;
}
.jumps a:hover { color: var(--ink); background: var(--era); border-color: var(--era); }
.jumps a[hidden] { display: none; }

/* ---------- Quotes ---------- */
.quotes { columns: 3 320px; column-gap: 20px; }
.quote {
  break-inside: avoid; margin-bottom: 20px; padding: 26px 24px;
  background: var(--bg-raised); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: var(--radius);
}
.quote blockquote {
  margin: 0 0 16px; font-family: var(--serif); font-size: 1.14rem; line-height: 1.45;
}
.quote-src { font-size: 0.74rem; color: var(--text-mute); }
.quote-topics { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }
.chip {
  font-size: 0.66rem; padding: 2px 9px; border-radius: 20px;
  border: 1px solid var(--line); color: var(--text-dim); cursor: pointer;
}
.chip.active { background: var(--accent); border-color: var(--accent); color: var(--ink); }
.unverified {
  display: inline-block; margin-left: 6px; font-size: 0.62rem; letter-spacing: .08em;
  text-transform: uppercase; color: #eab308;
}

/* ---------- Coverage ---------- */
.bar { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; min-width: 120px; }
.bar > i { display: block; height: 100%; background: var(--accent); }

/* ---------- Footer ---------- */
.footer {
  border-top: 1px solid var(--line-soft); margin-top: 60px; padding: 40px 0 60px;
  font-size: 0.8rem; color: var(--text-mute);
}
.footer strong { color: var(--text-dim); }
.footer a { color: var(--text-dim); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .hero-grid, .album-hero-grid { grid-template-columns: 1fr; gap: 28px; }
  .album-hero-grid { align-items: start; }
  .album-hero-art { max-width: 220px; }
  .nav { gap: 14px; }
  .nav .rail { display: none; }
  .gallery { columns: 2 140px; }
  .quotes { columns: 1; }
}
@media (max-width: 640px) {
  .topbar-in { gap: 12px; }
  .nav a { font-size: 0.76rem; }
  .hero { padding: 44px 0 34px; }
  .track { grid-template-columns: 26px 1fr auto; }
  .track-note, .track-links { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ---------- Hero inline player ----------
   The landing page plays in place instead of throwing up a popup. The poster
   sits over the frame until YouTube has something to draw, so there's no black
   flash on load, and it comes back if the video turns out to be unplayable. */
.hero-player { border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-raised);
  box-shadow: 0 24px 60px rgba(0,0,0,.5); }
.hp-frame { position: relative; aspect-ratio: 16 / 9; background: #000; }
.hp-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.hp-poster { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; transition: opacity .5s; }
.hp-poster.gone { opacity: 0; pointer-events: none; }
.hp-bar { display: flex; align-items: center; gap: 7px; padding: 9px 11px; }
.hp-track { flex: 1 1 auto; min-width: 0; font-family: var(--serif); font-size: .95rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hp-btn { background: none; border: 1px solid var(--line); border-radius: 5px;
  color: var(--text-dim); font-size: .72rem; padding: 5px 9px; cursor: pointer;
  font-family: var(--sans); white-space: nowrap; line-height: 1.3; }
.hp-btn:hover { color: var(--text); border-color: var(--era); }
.hp-sound.muted { background: #eab308; border-color: #eab308; color: var(--ink); font-weight: 700; }

/* Homepage shop strip. The site is the one audience Etsy search can't reach,
   so the shop needs a route from the busiest page, not just a nav link. */
.shopstrip { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.strip-item { display: block; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--bg-raised); transition: border-color .15s; }
.strip-item:hover { border-color: var(--accent); }
.strip-item img { width: 100%; aspect-ratio: 5/6; object-fit: cover; display: block; }
.strip-item span { display: block; padding: 10px 12px; font-size: .84rem; color: var(--text-dim); }

/* ==========================================================================
   Career components
   Everything below is new for the athlete build. The shell above is shared
   with the musician sites; these are the shapes a competitive record needs
   and a discography does not — results, medals, head-to-heads, season tables.
   ========================================================================== */

/* ---------- Campaign cards ---------- */
/* A tournament with no footage still needs a tile, and a grey box reads as a
   broken image. The plate carries the record instead, which is the thing the
   card is actually about. */
.album-art.plate {
  display: grid; place-content: center; gap: 4px; text-align: center;
  aspect-ratio: 16 / 9; background:
    linear-gradient(150deg, color-mix(in srgb, var(--era) 22%, var(--bg-raised)), var(--bg-raised));
}
.plate-record { font-family: var(--serif); font-size: 1.9rem; color: var(--text); }
.plate-sub { font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
             color: var(--text-mute); }
.album-art { position: relative; aspect-ratio: 16 / 9; }
.grid-cell[hidden] { display: none; }

/* ---------- Medals ---------- */
.medal {
  display: inline-block; font-size: .62rem; letter-spacing: .12em;
  text-transform: uppercase; padding: 3px 8px; border-radius: 999px;
  border: 1px solid; font-weight: 700;
}
.album-art .medal { position: absolute; top: 10px; left: 10px; z-index: 2;
                    backdrop-filter: blur(6px); background: rgba(11,10,12,.55); }
.medal-gold   { color: #e9c46a; border-color: #7d6320; }
.medal-silver { color: #cfd4da; border-color: #5c6169; }
.medal-bronze { color: #cd9575; border-color: #6d4a37; }

.medals { border-top: 1px solid var(--line-soft); }
.medal-row {
  display: grid; grid-template-columns: 92px 1fr 1fr auto; gap: 14px;
  align-items: center; padding: 11px 6px; border-bottom: 1px solid var(--line-soft);
  font-size: .9rem;
}
.medal-comp { color: var(--text-dim); }
.medal-event { color: var(--text); }
@media (max-width: 700px) {
  .medal-row { grid-template-columns: 78px 1fr; }
  .medal-weight { display: none; }
}

/* ---------- Match rows ---------- */
/* Five columns: result, who, how it ended, who filmed it, running record.
   The running record is the column that makes the list read as a career
   rather than a list of matches — you can watch 1–0 become 113–8. */
.match {
  display: grid; grid-template-columns: 34px 1fr 150px 130px 68px;
  gap: 14px; align-items: center; padding: 11px 6px;
  border-bottom: 1px solid var(--line-soft);
}
.match.playable { cursor: pointer; }
.match.playable:hover { background: var(--bg-hover); }
.match.unplayable .match-src { opacity: .35; }
.matchrow { color: inherit; }
.match-res {
  font-family: var(--mono); font-size: .78rem; font-weight: 700;
  text-align: center; border-radius: 5px; padding: 2px 0;
}
.result-win  .match-res { color: #7fc08a; background: rgba(127,192,138,.10); }
.result-loss .match-res { color: #e0736f; background: rgba(224,115,111,.12); }
.match-name { font-size: .95rem; }
.match-flag {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .06em;
  color: var(--text-mute); border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 5px; margin-left: 7px; vertical-align: 2px;
}
.match-note {
  display: inline-block; font-size: .72rem; color: var(--text-mute);
  margin-left: 9px;
}
.match-score { font-family: var(--mono); font-size: .84rem; color: var(--text-dim); }
.match-score .match-note { margin-left: 6px; font-family: var(--sans); }
.match-src .lnk { border: 1px solid var(--line); color: var(--text-mute); }
.match.playable:hover .match-src .lnk { color: var(--era); border-color: var(--era); }
.match-rec { font-family: var(--mono); font-size: .78rem; color: var(--text-mute);
             text-align: right; }
@media (max-width: 860px) {
  .match { grid-template-columns: 30px 1fr auto; }
  .match-src, .match-rec { display: none; }
}

.year-rule {
  display: flex; align-items: center; gap: 12px; padding: 26px 6px 8px;
  font-family: var(--mono); font-size: .74rem; letter-spacing: .16em;
  color: var(--text-mute);
}
.year-rule::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); }
.year-rule[hidden] { display: none; }

/* ---------- Filters ---------- */
.chips { display: flex; gap: 7px; flex-wrap: wrap; }
.filterbar { display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
             padding-bottom: 18px; }
.filterbar .search-input { flex: 1 1 320px; }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: .9rem; min-width: 560px; }
.tbl th {
  text-align: left; font-size: .64rem; letter-spacing: .14em; font-weight: 600;
  text-transform: uppercase; color: var(--text-mute); padding: 9px 12px 9px 0;
  border-bottom: 1px solid var(--line);
}
.tbl td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--line-soft); }
.tbl .tbl-total td { font-weight: 700; color: var(--text); }
.tbl tr.result-loss td:first-child { box-shadow: inset 2px 0 0 #e0736f; padding-left: 10px; }

/* ---------- Opponents ---------- */
/* object-fit is set per image from the data, not here: a 3:1 panorama forced
   to `cover` in a portrait tile becomes a photograph of somebody's shoulder,
   so fetch_gallery.py marks the extreme shapes `contain` and they letterbox. */
.opp-card { display: flex; flex-direction: column; border: 1px solid var(--line);
            border-radius: var(--radius); overflow: hidden; background: var(--bg-raised); }
.opp-shot { position: relative; aspect-ratio: 4 / 3; background: #0f0d11;
            display: grid; place-items: center; }
.opp-shot img { width: 100%; height: 100%; object-position: 50% 22%; }
.opp-meta { padding: 14px 16px 16px; }
.opp-lines { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.opp-line {
  display: grid; grid-template-columns: 44px 1fr auto; gap: 10px;
  font-size: .78rem; color: var(--text-mute); padding: 4px 0;
  border-top: 1px solid var(--line-soft);
}
.opp-line:hover { color: var(--text-dim); }
.opp-line.result-loss { color: #e0736f; }
.opp-initials { font-family: var(--serif); font-size: 1.6rem; color: var(--text-mute); }
.no-shot { background:
  repeating-linear-gradient(135deg, #131117, #131117 8px, #17141b 8px, #17141b 16px); }

.opp-grid { border-top: 1px solid var(--line-soft); }
.opp-row {
  display: grid; grid-template-columns: 44px 1fr 62px 92px minmax(0, 200px);
  gap: 14px; align-items: center; padding: 9px 6px;
  border-bottom: 1px solid var(--line-soft);
}
.opp-row[hidden] { display: none; }
.opp-row.lost-to { box-shadow: inset 2px 0 0 #e0736f; }
.opp-thumb { width: 44px; height: 44px; border-radius: 50%; overflow: hidden;
             display: grid; place-items: center; background: #131117; }
.opp-thumb img { width: 100%; height: 100%; object-position: 50% 20%; }
.opp-thumb .opp-initials { font-size: .82rem; }
.opp-name a { border-bottom: 1px solid transparent; }
.opp-name a:hover { border-bottom-color: var(--accent); }
.opp-rec { font-family: var(--mono); font-size: .84rem; }
.opp-when { font-family: var(--mono); font-size: .74rem; }
.opp-links { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
.opp-links .lnk { border: 1px solid var(--line); color: var(--text-mute); }
.opp-links .lnk.result-loss { color: #e0736f; border-color: #5c2f2f; }
.opp-links .lnk:hover { color: var(--text); border-color: var(--text-mute); }
@media (max-width: 780px) {
  .opp-row { grid-template-columns: 40px 1fr auto; }
  .opp-when, .opp-links { display: none; }
}

/* ---------- Embeds and notices ---------- */
.embed { position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius);
         overflow: hidden; border: 1px solid var(--line); background: #000; }
.embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.notice {
  border-left: 2px solid var(--accent); background: var(--bg-raised);
  padding: 12px 16px; border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--text-dim); font-size: .88rem; margin-bottom: 20px;
}

.nextfight {
  display: flex; gap: 20px; align-items: center; justify-content: space-between;
  flex-wrap: wrap; padding: 20px 22px; border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 12%, var(--bg-raised)), var(--bg-raised));
}
.nextfight-v { font-family: var(--serif); font-size: 1.7rem; margin: 2px 0 4px; }

/* ---------- About ---------- */
.about-hero { display: grid; grid-template-columns: 1.35fr .65fr; gap: 40px;
              align-items: start; }
.about-portrait img { width: 100%; aspect-ratio: 4 / 5; border-radius: var(--radius);
                      border: 1px solid var(--line); object-position: 50% 25%; }
.about-portrait figcaption { margin-top: 10px; font-size: .78rem; color: var(--text-mute); }
.credit { font-size: .72rem; color: var(--text-mute); display: block; margin-top: 6px; }
.credit a { text-decoration: underline; text-underline-offset: 2px; }

.chapter-head { max-width: 62ch; margin-bottom: 26px; }
.chapter-body { display: grid; grid-template-columns: 1.5fr .8fr; gap: 40px;
                align-items: start; }
.prose p { margin: 0 0 18px; max-width: 68ch; color: var(--text-dim); }
.prose p:first-child { color: var(--text); }
.chapter-side { display: flex; flex-direction: column; gap: 14px; }
.chapter-shot img { width: 100%; border-radius: var(--radius);
                    border: 1px solid var(--line); aspect-ratio: 4 / 3;
                    object-position: 50% 22%; }
.sourcelist { list-style: none; padding: 0; margin: 18px 0 0; }
.sourcelist li { padding: 8px 0; border-bottom: 1px solid var(--line-soft); }
.sourcelist a { color: var(--text-dim); text-decoration: underline;
                text-underline-offset: 3px; }
.sourcelist a:hover { color: var(--text); }
@media (max-width: 900px) {
  .about-hero, .chapter-body { grid-template-columns: 1fr; gap: 26px; }
  .about-portrait { max-width: 320px; }
}

/* ---------- Fixes found by looking at the rendered pages ---------- */
/* The shared .album-hero-art was written for a square album cover. A video
   thumbnail is 16:9, and dropped into a square box it left a black panel under
   every campaign hero. */
.album-hero-art img {
  width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--line);
}
.album-hero-grid { align-items: center; }

/* place-items:center is for the initials plate; an <img> in the same box has to
   fill it or a portrait photograph makes the card twice as tall as its
   neighbours and the row stops aligning. */
.opp-shot { overflow: hidden; }
.opp-shot > img { width: 100%; height: 100%; align-self: stretch; justify-self: stretch; }
.albums { align-items: start; }

/* A live feed should say whether it is live. Grey until the fetch lands, then
   the accent — the difference between "these numbers are from the deploy" and
   "these numbers are from thirty seconds ago" is worth one dot. */
.live-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-mute); margin-left: 7px; vertical-align: 1px;
}
.live-dot.is-live { background: var(--accent); box-shadow: 0 0 0 3px
  color-mix(in srgb, var(--accent) 22%, transparent); }

/* ---------- Stat grids (the tale of the tape, striking numbers) ---------- */
.statgrid { display: grid; gap: 12px;
            grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); }
.stat { background: var(--bg-raised); border: 1px solid var(--line);
        border-radius: var(--radius); padding: 15px 17px 16px; }
.stat-k { font-size: .62rem; letter-spacing: .14em; text-transform: uppercase;
          color: var(--text-mute); }
.stat-v { font-family: var(--serif); font-size: 1.5rem; line-height: 1.2;
          margin-top: 5px; }
.stat-note { font-size: .74rem; color: var(--text-mute); margin-top: 6px;
             line-height: 1.4; }

.nextfight-odds { text-align: right; }
.odds-v { font-family: var(--mono); font-size: 1.5rem; margin-top: 4px; }
.nextfight[hidden] { display: none; }

/* The next-fight card lost its button; the opponent's details take the space,
   and the odds column only exists on the days there is a price. */
.nextfight-side { min-width: 220px; }
.nextfight-side .mute { margin-top: 4px; font-size: .88rem; }
.nextfight-odds[hidden] { display: none; }

/* ---------- What's next: the two codes side by side ---------- */
.whatsnext { display: grid; gap: 16px;
             grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.next-card {
  display: block; padding: 20px 22px; border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--era) 40%, var(--line));
  background: linear-gradient(120deg,
              color-mix(in srgb, var(--era) 12%, var(--bg-raised)), var(--bg-raised));
  transition: border-color .15s, transform .15s;
}
.next-card:hover { border-color: var(--era); transform: translateY(-2px); }
.next-v { font-family: var(--serif); font-size: 1.6rem; margin: 4px 0 4px; }
.next-note { font-size: .82rem; margin-top: 8px;
             border-top: 1px solid var(--line-soft); padding-top: 8px; }


/* ---------- Vitals strip ----------
   Age, height, reach, record and UFC status, on the home page above the fold.
   These are the five highest-volume things anyone searches about him, and a
   visitor who has to hunt for his height on a fan site will go back to Google. */
.vitals { list-style: none; display: flex; flex-wrap: wrap; gap: 10px;
  margin: 22px 0 24px; padding: 0; }
.vitals li { display: flex; flex-direction: column; gap: 2px;
  padding: 9px 14px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--bg-raised); }
.vitals span { font-size: .62rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--text-mute); }
.vitals strong { font-size: .98rem; font-weight: 600; white-space: nowrap; }
@media (max-width: 560px) { .vitals li { flex: 1 1 calc(50% - 10px); } }


/* ---------- Mobile menu ----------
   Hidden on desktop; below 900px it replaces the link row, which was wider than
   a phone viewport and made every page scroll sideways. */
.navtoggle {
  display: none; margin-left: auto; width: 42px; height: 38px; padding: 9px 8px;
  flex-direction: column; justify-content: space-between; cursor: pointer;
  background: none; border: 1px solid var(--line); border-radius: 8px;
}
.navtoggle span { display: block; height: 2px; width: 100%; border-radius: 2px;
  background: var(--text-dim); transition: transform .2s ease, opacity .15s ease; }
.navtoggle.open span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.navtoggle.open span:nth-child(2) { opacity: 0; }
.navtoggle.open span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
.navtoggle.open span { background: var(--accent); }

@media (max-width: 900px) {
  .navtoggle { display: flex; }
  .nav {
    position: absolute; top: 100%; left: 0; right: 0; margin: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    /* Solid: the header carries its own backdrop-filter, and a translucent
       panel over it composites to something you can read straight through. */
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .55);
    max-height: 0; overflow: hidden; visibility: hidden;
    transition: max-height .24s ease, visibility .24s;
  }
  .nav.open { max-height: 80vh; overflow-y: auto; visibility: visible; }
  .nav a { padding: 14px 24px; font-size: 0.95rem;
    border-bottom: 1px solid var(--line-soft); border-left: 3px solid transparent; }
  .nav a:last-child { border-bottom: 0; }
  .nav a.active { border-bottom-color: var(--line-soft); border-left-color: var(--accent); }
}
