/* =============================================================================
   boards.css — THE LEADERBOARD PAGE, in the house register.

   WHY THIS FILE EXISTS AT ALL (2026-09-07, the Everfall redesign wave). Until
   today this page's rules rode in a `<style>` block inside fragments/boards.html
   and a second set was injected at runtime by js/boardsingle.js. Both were
   token-only and both were honest, and both were still the wrong shape: a rule
   inside a fragment cannot be scanned by the colour gate, cannot be shared with
   the single-board renderer, and cannot be read by anybody looking for "where is
   this page dressed". One sheet, listed in run_all.py's TOKEN_SHEETS the day it
   was born, is the only shape a page's look can safely take.

   THE BRIEF, verbatim: "for leaderboard redesign it fully. make it like natural
   selection leaderboard or clan style similar to [the dynasty page] but better
   ofcourse. for the background use [the roaring theropod]."

   WHAT WAS COPIED FROM THAT REFERENCE, AND WHAT WAS NOT. The SHAPE is copied: a
   wide header plate carrying one subject and three readings; thin-bordered
   panels with tracked-caps heads; a grid of big numerals over tiny labels; a
   ranked table whose marked row carries an accent bar. The reference's own
   CONTENT is not, because Everfall has no clans and no achievement ladder, and
   inventing either would be a picture of facts nobody measured. Everything this
   page draws comes from /api/boards and /api/boards/species — the apex is the
   board's own first row, the records grid is arithmetic over the rows the API
   returned, and a figure the API did not send is an em dash, never a zero.

   TOKEN-ONLY. Not one colour literal, not one owner name, not one asset path.
   Every value is a role token from theme.css or a color-mix() of one, so the
   next island born on this framework gets the same bones in its own palette, on
   its own ground, with no photograph at all.

   THE PHOTOGRAPH IS AN OWNER OPT-IN AND THIS SHEET NEVER NAMES ONE.
   `--art-scene-boards` is emitted by theme.py only for an owner who typed
   `theme.art_scenes.boards`; every var() below carries `none` as its fallback,
   so an owner who typed nothing gets the site's own ground and not a broken
   url(). Same contract, same cross-fade, as livedossier.css's live scene.

   THE HOUSE LOOK LOADS AFTER THIS SHEET. terminal.css's SURFACE REGISTER names
   every plate below and re-states its hairline and its flat face, which is what
   keeps this page in one product with the other eleven. Where a rule here has to
   SURVIVE that — the crest's warmer frame, the accent bar on the reader's own
   plate — the selector is raised rather than shouted at with !important.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. THE GROUND — the owner's photograph, fixed, under a scrim
   -----------------------------------------------------------------------------
   Two fixed layers on the shell rather than on `main`: backdrop.css owns the
   page ground through `.night[data-atmos] ~ main`, and a competing paint on
   `main` would either lose the cascade or win it and erase the atmosphere. A
   pseudo-element of a CHILD sits above `main::before` by tree order at the same
   z-index, which is exactly where a page's own scene belongs — the pattern
   livedossier.css proved on the live page.

   THE SCRIM IS A RAMP, NOT A WASH, AND THE NUMBERS WERE MEASURED. This owner's
   boards scene is a noon-lit jungle: bright sand, high contrast, an animal
   across the middle third. A flat wash over that is either a page whose table
   nobody can read or a photograph nobody can see. The ramp starts at 54% of the
   ground colour, where the crown plate floats and the animal is still legible,
   and closes at 92% under the log, where twenty rows of small type run. The
   panels carry their own 74% face and a blur, so the picture only ever reads
   through the gaps between them — which is the whole trick. Nothing is baked
   into the WebP; this is the one place the darkening lives and the one place to
   tune it. */
.bd-shell::before,
.bd-shell::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-repeat: no-repeat;
  background-position: 50% 34%;
  background-size: cover;
}

/* the blur-up placeholder, under everything */
.bd-shell::before {
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg-deep) 54%, transparent) 0%,
      color-mix(in srgb, var(--bg-deep) 76%, transparent) 46%,
      color-mix(in srgb, var(--bg-deep) 92%, transparent) 100%),
    var(--art-scene-boards-placeholder, none);
}

/* the real file, cross-fading over it */
.bd-shell::after {
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bg-deep) 54%, transparent) 0%,
      color-mix(in srgb, var(--bg-deep) 76%, transparent) 46%,
      color-mix(in srgb, var(--bg-deep) 92%, transparent) 100%),
    var(--art-scene-boards, none);
  opacity: 0;
  animation: bd-scene-in .5s ease .26s forwards;
}

@keyframes bd-scene-in { to { opacity: 1; } }

/* THE PHONE FILE, and `center top` rather than `center`: the animal sits in the
   upper half of the portrait crop, so a viewport taller than the file must throw
   its surplus off the FOOT, where the ground already reads as black under the
   scrim. */
@media (max-width: 720px) {
  .bd-shell::before,
  .bd-shell::after { background-position: center top; }

  .bd-shell::before {
    background-image:
      linear-gradient(180deg,
        color-mix(in srgb, var(--bg-deep) 50%, transparent) 0%,
        color-mix(in srgb, var(--bg-deep) 80%, transparent) 44%,
        color-mix(in srgb, var(--bg-deep) 93%, transparent) 100%),
      var(--art-scene-boards-placeholder, none);
  }

  .bd-shell::after {
    background-image:
      linear-gradient(180deg,
        color-mix(in srgb, var(--bg-deep) 50%, transparent) 0%,
        color-mix(in srgb, var(--bg-deep) 80%, transparent) 44%,
        color-mix(in srgb, var(--bg-deep) 93%, transparent) 100%),
      var(--art-scene-boards-phone, none);
  }
}

/* NO CROSS-FADE UNDER REDUCED MOTION. A full-bleed fade is precisely the
   large-area movement that rule exists to stop, so the real file simply IS there
   from the first frame. */
@media (prefers-reduced-motion: reduce) {
  .bd-shell::after { animation: none; opacity: 1; }
}

/* -----------------------------------------------------------------------------
   2. THE PLATE — one surface, used four times
   -----------------------------------------------------------------------------
   Hairline, translucent near-black face, the house radius, and a blur behind it
   because it sits over a photograph. The top edge carries the record's own rule
   with the accent at its head, which is the signature terminal.css gives every
   `.card` on this site — a panel that skipped it would be the one box on the
   page that is not part of the same product. */
.bd-panel,
.bd-apex,
.bd-standing {
  position: relative;
  border: 1px solid var(--tm-hair);
  border-radius: var(--r);
  background-color: color-mix(in srgb, var(--bg-deep) 74%, transparent);
  background-image: var(--grain), var(--tm-face);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.bd-panel::before,
.bd-apex::before,
.bd-standing::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -1px;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg, var(--tm-hot) 0 46px, var(--tm-hair) 46px);
}

/* THE PANEL HEAD. Tracked caps, a hairline under it, and room on the right for a
   control — the period tabs on the standings panel, a reading on the others.
   Centred and not baseline: the right-hand slot can hold a row of buttons, and a
   baseline would hang them below the title. */
.bd-phead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 18px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--tm-hair-soft);
}

.bd-phead h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--tm-h-panel);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: var(--tm-track);
  text-transform: uppercase;
  color: var(--fg);
}

/* the one line a head may carry under its title. Sentence case and quiet: it
   says what the panel below is for, it never competes with the rows. */
.bd-psub {
  margin: 5px 0 0;
  font-size: var(--fs-2);
  line-height: 1.45;
  color: var(--fg-mute);
}

/* -----------------------------------------------------------------------------
   3. THE APEX — the reference's header plate, carrying the board's first row
   -----------------------------------------------------------------------------
   Crest, identity, three readings. It is the ONE place on this page where a
   single player is named large, and it is the board's own leader — not a
   featured account, not a pick, not an editorial. */
.bd-crown { display: grid; gap: 12px; }

#bd-apex { display: grid; gap: 12px; }

/* ★ AN EMPTY SLOT IS INVISIBLE, AND THE SELECTOR HAS TO SAY SO LOUDER THAN THE
   ONE THAT LAID IT OUT. Both mounts are written by script and both are empty
   until there is an answer; `#bd-note` is cleared outright for a signed-in
   reader. A bare `.bd-crown > :empty` rule loses to `.bd-crown .bd-standing`'s
   `display: flex` and leaves a hairline plate with nothing in it standing under
   the apex - which is exactly what shipped in this wave's first render. */
.bd-crown > #bd-apex:empty,
.bd-crown > #bd-note:empty { display: none; }

.bd-apex {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px 22px;
  padding: 18px 20px;
}

/* THE CREST. A square plate with the face inside and an inset registration
   frame — the reference's diamond, squared to this site's own geometry. The
   surface token behind the picture stands in while it loads and IS the picture
   for a player Steam had no answer for. The warmer border is raised over the
   house register deliberately: this is the page's one subject. */
.bd-crest {
  position: relative;
  width: 84px;
  height: 84px;
  flex: none;
  display: grid;
  place-items: center;
  border: 1px solid var(--tm-hair);
  border-radius: var(--r);
  background: var(--surface-2);
  overflow: hidden;
}

.bd-apex .bd-crest { border-color: var(--tm-warm); }

.bd-crest img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.bd-crest::after {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid var(--tm-faint);
  border-radius: 0;
  pointer-events: none;
}

.bd-apex-id { min-width: 0; }

.bd-eyebrow {
  margin: 0 0 6px;
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--accent);
}

/* The name. Display face, tracked, and it TRUNCATES rather than pushing the
   readings off the plate — a player-chosen name can be forty characters. */
.bd-apex-who {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-width: 0;
}

.bd-apex-who b {
  font-family: var(--font-display);
  font-size: clamp(23px, 2.9vw, 34px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* the tag chip beside the name — the reference's clan tag, here the rank */
.bd-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border: 1px solid var(--tm-hair);
  border-radius: var(--r);
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-hi);
  background: var(--accent-wash);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.bd-crown .bd-chip { border-color: var(--tm-warm); }

/* THE PERIOD LINE, in the reference's own voice: its header plate carries
   "FOUNDED JULY 2026" under the name in tracked micro caps, and the honest
   equivalent here is the window this leader leads. */
.bd-apex-sub {
  margin: 9px 0 0;
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

/* THE THREE READINGS. Hairline-divided cells, not three boxes: the reference
   draws them as one instrument with rules between, and three separate plates on
   a plate is the shape that makes a page look assembled from parts. */
.bd-tiles {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(78px, auto);
  border: 1px solid var(--tm-hair);
  border-radius: var(--r);
  overflow: hidden;
}

.bd-tile {
  padding: 12px 18px;
  text-align: center;
  border-left: 1px solid var(--tm-hair-soft);
  background: color-mix(in srgb, var(--bg-deep) 40%, transparent);
}

.bd-tiles .bd-tile:first-child { border-left-width: 0; }

.bd-tile b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(19px, 2.1vw, 26px);
  font-weight: 600;
  line-height: 1;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

.bd-tiles .bd-tile:first-child b { color: var(--accent-hi); }

.bd-tile span {
  display: block;
  margin-top: 7px;
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

/* -----------------------------------------------------------------------------
   4. YOUR STANDING — the slim second plate, and the signed-out line in its slot
   -----------------------------------------------------------------------------
   Signed in, this is the reader's own row lifted out of the table. Signed out,
   the same slot carries the sign-in line boards.js writes into #bd-note, so the
   page has ONE answer in ONE place to "where am I on this" rather than a plate in
   one state and a floating sentence in the other. */
.bd-crown .bd-standing {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  padding: 12px 16px;
  box-shadow: inset 2px 0 0 var(--accent);
}

/* THE SIGNED-OUT LINE WEARS THE SAME PLATE. The fragment gives #bd-note the
   `.bd-standing` class, so the sentence a visitor sees and the readings a
   signed-in player sees are ONE surface in one slot rather than two shapes
   that happen to occupy the same gap. Only the type differs. */
.bd-crown #bd-note {
  margin: 0;
  color: var(--fg-dim);
  font-size: var(--fs-2);
}

/* the slim plate carries its eyebrow INLINE, on the same line as the rank and
   the name, so the whole answer is one row rather than a stacked card */
.bd-standing .bd-eyebrow { margin: 0; }

.bd-standing-who {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  margin-right: auto;
}

.bd-standing-who b {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* the inline readings on the slim plate: mono tracked label, tabular figure */
.bd-reads {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
}

.bd-read {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

.bd-read b {
  font-size: var(--fs-3);
  letter-spacing: 0;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

/* the unranked sentence — a fact about this account, not an error */
.bd-standing p {
  margin: 0;
  font-size: var(--fs-2);
  color: var(--fg-dim);
}

/* -----------------------------------------------------------------------------
   5. THE LAYOUT
   -----------------------------------------------------------------------------
   Standings beside records, kill log the full width below — the reference's own
   arrangement, read for what each block IS rather than copied by column count:
   the table is the page's subject and takes the wide seat, the derived figures
   are a margin note, and the log is a wide list of wide rows that would be
   unreadable in a third of the page. */
.bd-shell {
  position: relative;
  display: grid;
  gap: 14px;
  margin-top: 26px;
}

.bd-grid { display: grid; gap: 14px; }

/* ★★★ EVERY GRID ITEM ON THIS PAGE IS min-width: 0, AND THAT IS NOT TIDINESS.
   A grid item's automatic minimum size is its MIN-CONTENT size, so one child
   that cannot wrap sets the width of everything above it. Measured at 390px
   before this line existed: the species chip row (26 chips, `flex-wrap: nowrap`
   on the phone so it scrolls sideways) pushed `document.scrollWidth` to 3480px
   and the whole page scrolled horizontally - the apex plate, the table and the
   log all 3,464px wide inside a 390px viewport. The chip row's own
   `overflow-x: auto` was never the problem; the track it sat in had no floor.
   Nothing below may rely on its content to be narrow. */
.bd-shell > *,
.bd-crown > *,
.bd-grid > * { min-width: 0; }

@media (min-width: 1080px) {
  .bd-grid {
    grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr);
    align-items: start;
  }

  /* ★ A MULTI-BOARD OWNER HAS NO RECORDS PANEL, AND THE PAGE MUST NOT HOLD A
     COLUMN OPEN FOR ONE. #bd-side is written only by the single-board
     renderer; on every other owner it stays empty, and a reserved 1fr track
     beside a panel is 500px of nothing next to the only thing on the page.
     A browser without `:has()` keeps the two-column track, which is the
     layout that shipped before this line - a degrade, never a break. */
  .bd-grid:has(> #bd-side:empty) { grid-template-columns: minmax(0, 1fr); }
}

/* ONE ENTRANCE, and it finishes: the resting state is the finished state, so a
   reader whose animation never runs still meets a complete page. */
@media (prefers-reduced-motion: no-preference) {
  .bd-apex,
  .bd-standing,
  .bd-panel {
    animation: bd-plate-in .42s cubic-bezier(.2, .7, .3, 1) both;
  }

  .bd-grid > :nth-child(2) { animation-delay: .06s; }
  .bd-shell > .bd-panel { animation-delay: .1s; }
}

@keyframes bd-plate-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* -----------------------------------------------------------------------------
   6. THE PERIOD SWITCHER — a tab strip in the panel head
   -----------------------------------------------------------------------------
   A period is a BUTTON, not a link: it changes what this page shows, it does not
   go anywhere. The selected one is drawn from its ARIA state, so what a screen
   reader announces and what an eye sees are the SAME attribute and cannot drift
   apart. Empty until the script has an answer to switch between, and invisible
   while it is empty rather than a reserved gap that looks like a failed load. */
/* ★ ITS OWN ROW IN THE HEAD, ALWAYS, RATHER THAN "BESIDE THE TITLE IF IT
   FITS". Five periods in the owner's own words is a variable width - "As set
   up" and "Last 30 days" here, longer in German - and beside a panel title in
   a 700px column it lands within a few pixels of wrapping. A strip that sits
   inline on one build and drops to a second line on the next is a layout
   nobody chose; a strip that always has its own line is one somebody did. */
#bd-windows {
  display: flex;
  flex-wrap: wrap;
  flex: 1 0 100%;
  gap: 2px 18px;
  margin-top: 2px;
}

#bd-windows:empty { display: none; }

/* ★ THE SELECTOR IS RAISED, AND THE REASON IS MEASURED. terminal.css dresses
   every `[role="tab"]` on the site as an underlined word, and a site theme may
   raise its own version above that - Everfall's does, at `padding: 13px 2px`,
   which is right for a page-wide tab strip and unreadable for five periods
   inside a panel head (measured: the five ran together into one line). `#`
   beats both, so this switcher keeps the site's TAB LANGUAGE - a word, an
   accent rule under the open one, no box - at a spacing that works where it
   actually sits. */
/* ★ NO `background` DECLARATION HERE, AND THAT IS DELIBERATE. These buttons
   carry `role="tab"`, and terminal.css section 13 already gives every tab on
   this site a bare ground - so restating it would be a page sheet describing a
   surface the house look owns, and `test_house_look.py` would (rightly) read a
   background beside a border as a PLATE and demand this class be registered as
   one. It is not a plate. It is a word with a rule under it. */
#bd-windows .bd-win {
  padding: 6px 0;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--fg-mute);
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: color .16s, border-color .16s;
}

#bd-windows .bd-win:hover { color: var(--fg); }

#bd-windows .bd-win[aria-selected="true"] {
  color: var(--accent-hi);
  border-bottom-color: var(--accent);
}

/* -----------------------------------------------------------------------------
   7. THE STANDINGS TABLE (the bs-* contract js/boardsingle.js writes)
   -----------------------------------------------------------------------------
   THE MAGNITUDE BAR IS A REAL FRACTION OF THE LEADER, NEVER OF THE RANK.
   `--bd-fill` is set per row by the renderer as this row's score over the
   leader's. Drawing it from the rank instead would produce a confident,
   evenly-stepped picture of numbers that might be nearly identical or orders of
   magnitude apart — a chart that lies about the thing it is drawn from. It is
   painted as two background layers rather than a positioned pseudo-element,
   because a table row is not a reliable containing block and a bar that only
   lands in some browsers is worse than no bar at all. No fill, no paint. */
.bs-wrap { overflow-x: auto; }

.bs-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 420px;
}

.bs-table th {
  padding: 12px 14px;
  border-bottom: 1px solid var(--tm-hair);
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--fg-mute);
  text-align: left;
  white-space: nowrap;
}

.bs-table th.bs-num,
.bs-table td.bs-num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.bs-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--tm-hair-soft);
  vertical-align: middle;
}

.bs-table tbody tr {
  background-image:
    linear-gradient(90deg, var(--accent), var(--accent-hi)),
    linear-gradient(90deg, var(--tm-faint), transparent);
  background-repeat: no-repeat, no-repeat;
  background-size: var(--bd-fill, 0%) 2px, var(--bd-fill, 0%) 100%;
  background-position: left bottom, left top;
}

.bs-table tbody tr:last-child td { border-bottom-width: 0; }

.bs-rank {
  width: 3ch;
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--fg-mute);
}

/* THE PODIUM IS THE ONE MAGNITUDE THIS SHEET CAN DRAW WITHOUT A NUMBER. Rank is
   already in the markup as document order, so the top three step up in ink and
   the leader takes the accent. */
.bs-table tbody tr:nth-child(-n+3) .bs-rank { color: var(--fg-dim); }
.bs-table tbody tr:first-child .bs-rank { color: var(--accent-hi); font-weight: 700; }
.bs-table tbody tr:nth-child(-n+3) .bs-name { font-weight: 600; }
.bs-table tbody tr:first-child .bs-name { color: var(--fg); }

.bs-who { display: flex; align-items: center; gap: 10px; min-width: 0; }

.bs-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--fg-dim);
}

.bs-table td.bs-kills { color: var(--fg); font-weight: 600; }

/* THE READER'S OWN ROW, marked the way the reference marks its leading row: an
   accent bar on the leading edge and a wash light enough to leave the magnitude
   bar underneath visible. */
.bs-table tr.is-you td { background-color: var(--accent-wash); }
.bs-table tr.is-you td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* THE FACE (the faces lane): a circle on the row's leading edge. The surface
   token behind it stands in while the picture loads. */
.bd-face {
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface-2);
  border: 1px solid var(--tm-hair);
}

.bs-table tbody tr:first-child .bd-face { border-color: var(--tm-warm); }

/* -----------------------------------------------------------------------------
   8. ISLAND RECORDS — numerals over labels, and nothing that was not measured
   -----------------------------------------------------------------------------
   The reference's records grid, mapped onto the only figures this API returns.
   There is no achievement ladder here and there is not going to be one: nothing
   in /api/boards earns a target, and a progress bar against a number nobody
   publishes is a picture of a fact that does not exist. */
.bd-figs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.bd-fig {
  padding: 15px 16px;
  border-right: 1px solid var(--tm-hair-soft);
  border-bottom: 1px solid var(--tm-hair-soft);
  min-width: 0;
}

.bd-figs > .bd-fig:nth-child(2n) { border-right-width: 0; }

.bd-fig b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(24px, 2.6vw, 34px);
  font-weight: 600;
  line-height: 1;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bd-fig-l {
  display: block;
  margin-top: 9px;
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

/* the two species readings are WORDS, not figures: they run the full width and
   drop a size, because a species name is up to twenty characters */
.bd-fig-wide { grid-column: 1 / -1; border-right-width: 0; }

.bd-fig-wide b {
  font-size: clamp(17px, 1.8vw, 21px);
  color: var(--accent-hi);
  letter-spacing: .04em;
}

/* the note under a figure: which player holds it, out of how many fights */
.bd-fig small {
  display: block;
  margin-top: 5px;
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .04em;
  color: var(--fg-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* THE CAPTION NAMES THE WINDOW. A grid of totals with no period on it is a set of
   numbers a reader cannot place in time, which is the same defect the board
   cards' window pill exists to prevent. */
.bd-cap {
  margin: 0;
  padding: 12px 16px;
  font-size: var(--fs-2);
  line-height: 1.5;
  color: var(--fg-mute);
}

/* -----------------------------------------------------------------------------
   9. THE KILL LOG
   -----------------------------------------------------------------------------
   A chip per species and one row per fight: who (as what) killed whom (as what),
   how grown each was, and when. Newest first, paged. */
.bs-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--tm-hair-soft);
  max-height: 152px;
  overflow-y: auto;
}

@media (max-width: 720px) {
  .bs-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    max-height: none;
    scrollbar-width: thin;
  }
}

.bs-chip {
  padding: 5px 10px;
  border: 1px solid var(--tm-hair);
  border-radius: var(--r);
  background: none;
  color: var(--fg-mute);
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: color .16s, border-color .16s, background-color .16s;
}

.bs-chip:hover { color: var(--fg); border-color: var(--edge); }

.bs-chip[aria-pressed="true"] {
  color: var(--accent-hi);
  border-color: var(--tm-warm);
  background-color: var(--accent-wash);
}

.bs-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A FIGHT IS A ROW, NOT A CARD. Hairline-separated entries in one register read
   as a log; twenty bordered boxes read as twenty things that each need reading.
   Killer right-aligned, victim left-aligned, the skull between them: the two
   sides face each other across the mark rather than queueing. */
.bs-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto;
  gap: 6px 14px;
  align-items: center;
  padding: 10px 16px;
  border-bottom: 1px solid var(--tm-hair-soft);
}

.bs-rows > .bs-row:last-child { border-bottom-width: 0; }

.bs-side {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px 8px;
}

.bs-killer { justify-content: flex-end; text-align: right; }

.bs-pname {
  font-weight: 600;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.bs-env { font-weight: 600; color: var(--fg-mute); font-style: italic; }

.bs-sp {
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

.bs-sp.is-pick {
  color: var(--accent-hi);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-underline-offset: 3px;
}

.bs-g {
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  color: var(--fg-mute);
  font-variant-numeric: tabular-nums;
}

.bs-skull {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  color: var(--fg-mute);
}

.bs-skull svg { width: 16px; height: 16px; }

.bs-row[data-cause="pvp"] .bs-skull { color: var(--bad); }

.bs-time {
  font-family: var(--font-mono);
  font-size: var(--tm-h-micro);
  color: var(--fg-mute);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  justify-self: end;
}

.bs-more { padding: 14px 16px; }
.bs-more:empty { display: none; }

/* -----------------------------------------------------------------------------
   10. THE WORDED STATES
   -----------------------------------------------------------------------------
   Every state on this page is a rendered answer inside its panel. None of them
   draws a plate of its own: a bordered box inside a bordered box is the shape a
   reader reads as "something broke", and four of these are perfectly ordinary. */
#bd-status,
.bs-status {
  margin: 0;
  padding: 22px 16px;
  font-size: var(--fs-2);
  line-height: 1.6;
  color: var(--fg-dim);
}

.bs-status[hidden] { display: none; }

/* MULTI-BOARD OWNERS. `web.boards.mode` other than "single" renders boards.js's
   several cards, and they land in the same standings panel as the house's own
   record plates. The blur is the only thing this page adds, and it is added
   because a card over a photograph without one is a rectangle of noise —
   nothing here re-describes `.card`, which belongs to the house look. */
/* AS MANY COLUMNS AS THE PANEL CAN HOLD AT A READABLE WIDTH, and `start` so an
   empty board is a short card rather than a tall box: a ten-row board and a
   "nothing scored yet" line have nothing to gain from being the same height. */
.bd-boards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  align-items: start;
  gap: 14px;
  padding: 16px;
}

.bd-boards .card {
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.bd-explain { margin: -4px 0 10px; font-size: var(--fs-2); }

/* the ranked list a multi-board card draws, in the same register as the table */
.bd-rows { list-style: none; margin: 10px 0 0; padding: 0; }

.bd-rows li {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  padding: 7px 0;
  background-image: linear-gradient(90deg, var(--accent), var(--accent-hi));
  background-repeat: no-repeat;
  background-size: var(--bd-fill, 0%) 2px;
  background-position: left bottom;
}

/* the separator rides BETWEEN rows rather than under each one: a list whose
   last row carries a rule has a line hanging under nothing */
.bd-rows li + li { border-top: 1px solid var(--tm-hair-soft); }

.bd-who { display: flex; align-items: center; gap: 9px; min-width: 0; }

.bd-rank {
  flex: none;
  min-width: 2ch;
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--fg-mute);
}

.bd-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bd-score {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--fg);
  font-weight: 600;
}

.bd-rows li:first-child .bd-rank { color: var(--accent-hi); font-weight: 700; }
.bd-rows li:nth-child(-n+3) .bd-name { color: var(--fg); font-weight: 600; }

/* -----------------------------------------------------------------------------
   11. THE PHONE — the same DOM, never a second page
   ----------------------------------------------------------------------------- */
@media (max-width: 720px) {
  .bd-apex {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 14px 16px;
    padding: 16px;
  }

  /* the readings drop below the crest and the name and run the full width */
  .bd-tiles { grid-column: 1 / -1; grid-auto-columns: minmax(0, 1fr); }
  .bd-tile { padding: 11px 8px; }
  .bd-crest { width: 60px; height: 60px; }

  .bd-phead { padding: 12px 13px; }

  .bs-chips,
  .bd-cap,
  .bs-more,
  .bd-boards { padding-left: 13px; padding-right: 13px; }

  /* ★ THE WHOLE TABLE FITS A PHONE, and that is worth one truncated name.
     `min-width: 420px` is the desktop floor that keeps five columns from
     collapsing into each other; kept on a 390px screen it pushed K/D off the
     right edge behind a sideways scroll, so the one figure a player came for
     was the one they could not see. Dropped to nothing here, with the name
     allowed to shrink to an ellipsis - which at these name lengths it never
     has to. */
  .bs-table { min-width: 0; }
  .bs-who .bs-name { min-width: 0; }

  .bs-table th,
  .bs-table td { padding-left: 6px; padding-right: 6px; }

  .bs-rank { width: 2ch; }

  #bd-windows { gap: 2px 14px; }

  .bd-fig { padding: 13px; }

  /* the fight row folds: the two sides keep facing each other, the stamp drops
     to its own line rather than squeezing the names to nothing */
  .bs-row {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    padding: 10px 13px;
  }

  .bs-time { grid-column: 1 / -1; justify-self: start; }

  .bd-crown .bd-standing,
  .bd-crown #bd-note { padding: 11px 13px; }
}

/* -----------------------------------------------------------------------------
   12. PRINT AND FORCED COLOURS
   -----------------------------------------------------------------------------
   A leaderboard is a thing people print and screenshot. The photograph is not
   part of the record, and a fixed full-bleed layer would come out as one page of
   ink and then a table with no ground under it. */
@media print {
  .bd-shell::before,
  .bd-shell::after { display: none; }

  .bd-panel,
  .bd-apex,
  .bd-standing {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

@media (forced-colors: active) {
  .bd-shell::before,
  .bd-shell::after { display: none; }

  .bd-win[aria-selected="true"],
  .bs-chip[aria-pressed="true"] { forced-color-adjust: none; }
}
