/* ============================================================================
   pump fun derby — shared shell + spectator page

   The metaphor is a racecourse tote board and timing tower, not a developer
   console: turf-at-night surfaces, condensed signage type for labels, a
   monospace key/value board for the readings, chequered flag as the only
   accent. theme.css supplies the primitives (.btn .card .field .data-table
   .tnum .num .pulse .skeleton .scroll-x) and is not edited; the tokens it
   reads are re-pointed on :root below.

   theme.css puts its components in @layer components. Unlayered rules here
   beat them regardless of specificity, which is deliberate for .btn-primary
   and .card, and a hazard everywhere else — never set a shorthand (overflow,
   background, border, font) on an element that also carries a theme class.
   ========================================================================= */

:root {
  /* Turf at night. The ladder keeps theme.css's small even steps, shifted
     green and warmed on the text end. */
  --color-bg: #0b0f0c;
  --color-surface: #10160f;
  --color-surface-2: #151c14;
  --color-surface-3: #1c261b;
  --color-line: #1e2a1f;
  --color-line-strong: #2b3a2c;
  --color-text: #f1eee3;
  --color-dim: #97a091;
  --color-dimmer: #626b5e;

  /* Status keeps the system colours. */
  --color-positive: #30d158;
  --color-danger: #ff453a;
  --color-warn: #ff9f0a;
  --color-info: #0a84ff;

  /* The one accent: the chequered flag off the broadcast. Live signal, first
     place, primary button. Nothing else, ever. */
  --flag: #ffd21e;
  --flag-dim: #e8bd18;

  --font-cond: "Barlow Condensed", "Inter", ui-sans-serif, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 84px;
}

body {
  margin: 0;
}

/* Form controls do not inherit the page font on their own. Only the family is
   set here: font-size and letter-spacing belong to .btn / .field in the theme,
   and an unlayered rule would override them. */
button,
input,
select,
textarea {
  font-family: inherit;
}

/* The hidden attribute must beat any display we set on the same element. */
[hidden] {
  display: none !important;
}

/* Signage, not software: square off the theme's rounded chrome. */
.card {
  border-radius: 3px;
}

.btn,
.field,
.btn-lg {
  border-radius: 3px;
}

.skeleton {
  display: inline-block;
  border-radius: 1px;
}

/* The one loud element is the flag, not a white rectangle. */
.btn-primary {
  color: #0b0f0c;
  background: var(--flag);
  border-color: var(--flag);
  font-weight: 600;
}

.btn-primary:hover:not(:disabled) {
  background: var(--flag-dim);
  border-color: var(--flag-dim);
}

.pulse-flag {
  background: var(--flag);
}

.skip {
  position: fixed;
  top: -100px;
  left: 12px;
  z-index: 60;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--color-text);
  background: var(--color-surface-2);
  border: 1px solid var(--color-line-strong);
  text-decoration: none;
}

.skip:focus {
  top: 12px;
}

/* --- The mark -------------------------------------------------------------
   The oval track, yellow on whatever sits behind it. brand/ holds the full-size files. */

.brand-logo {
  flex-shrink: 0;
  display: block;
  width: auto;
  height: 22px;
}

/* --- Chequered flag motif -------------------------------------------------
   Used exactly once: the broadcast's top edge. */

.chequer {
  height: 4px;
  background: repeating-conic-gradient(#0b0f0c 0% 25%, var(--flag) 0% 50%) 0 0 / 4px 4px;
}

/* --- Masthead ------------------------------------------------------------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(11, 15, 12, 0.92);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--color-line-strong);
}

.masthead-inner {
  display: flex;
  align-items: center;
  gap: 22px;
  max-width: 1180px;
  min-height: 64px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Pinch zoom must not also rerasterize a blurred layer over the live iframe. */
@media (any-pointer: coarse) {
  .masthead {
    background: var(--color-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

.brand {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 9px;
  color: var(--color-text);
  text-decoration: none;
}

.brand-word {
  font-family: var(--font-cond);
  font-size: 21px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.055em;
  text-transform: uppercase;
}

/* --- The contract address -------------------------------------------------
   It used to be a script-built grey box dropped above the page after load,
   in default monospace with a default underlined link, which read as something
   a browser extension had injected rather than part of the site. It now sits in
   the masthead where it belongs: fixed height, so nothing shifts when the
   address arrives, and one click takes the whole thing.

   The full 44 characters show wherever they fit. A coin site that renders its
   own address as an ellipsis is asking for a trust it has not earned. */

.ca {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 3px 4px 3px 9px;
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: 7px;
}

.ca[hidden] { display: none; }

.ca-key {
  flex-shrink: 0;
  font-family: var(--font-cond);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-dimmer);
  transition: color 0.12s;
}


.ca-copy {
  position: relative;
  min-width: 0;
  padding: 3px 6px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: -0.01em;
  color: var(--color-text);
  background: transparent;
  border: 0;
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.12s;
}

.ca-copy:hover { background: var(--color-surface-3); }

.ca-copy:focus-visible { outline: 1px solid var(--color-line-strong); outline-offset: 2px; }

/* verify.js owns the copying for every address on the site and reports through
   data-copied. On success the word is laid *over* the address so the chip cannot
   change width and shove the links sideways for a second and a half. */
.ca-copy[data-copied="Copied"] .ca-short { visibility: hidden; }

.ca-copy[data-copied="Copied"]::after {
  content: attr(data-copied);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-cond);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-positive);
  white-space: nowrap;
}

.ca-link {
  flex-shrink: 0;
  padding: 3px 7px;
  font-family: var(--font-cond);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-dim);
  text-decoration: none;
  border-left: 1px solid var(--color-line);
  transition: color 0.12s;
}

.ca-link:hover { color: var(--flag); }

/* The refusal state. verify.js puts the whole address into the chip for as long
   as the message is up, so this only has to let it wrap and stay selectable --
   the layout jumping matters less than every character being reachable. The
   message goes beside the address rather than over it, for the same reason. */
.ca-copy[data-copied]:not([data-copied="Copied"]) {
  color: var(--color-warn);
  text-align: left;
  white-space: normal;
  word-break: break-all;
  /* Chrome will not let a drag select inside a button, so a selection lost to a
     stray click could not be made again. */
  user-select: text;
}

.ca-copy[data-copied]:not([data-copied="Copied"])::after {
  content: attr(data-copied);
  margin-left: 8px;
  font-family: var(--font-cond);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.nav {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
}

.nav a {
  font-family: var(--font-cond);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-dim);
  text-decoration: none;
  transition: color 0.12s;
}

.nav a:hover,
.nav a[data-active="true"] {
  color: var(--color-text);
}

/* The departures board: the one thing up here that is always moving. */
.board {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  padding-left: 20px;
  border-left: 1px solid var(--color-line);
}

.board .pulse {
  flex-shrink: 0;
  align-self: center;
  margin-right: -2px;
}

.board-body {
  min-width: 0;
}

.board-row {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 9px;
  white-space: nowrap;
}

.board-key {
  font-family: var(--font-cond);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-dimmer);
}

.board-clock {
  font-size: 17px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.board-sub {
  margin-top: 2px;
  font-size: 10.5px;
  color: var(--color-dimmer);
}

.board-mode {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--color-dim);
}

.board-mode.mode-demo {
  color: var(--flag);
}

.board-mode.mode-live {
  color: var(--color-positive);
}

.board-mode.mode-offline {
  color: var(--color-danger);
}

/* --- Page ----------------------------------------------------------------- */

.shell-main {
  max-width: 1180px;
  margin: 0 auto;
  padding: 16px 24px 72px;
}

/* Section head: a condensed signage label with the hairline running off it. */
.rule-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 10px;
}

.rule-head::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-line-strong);
}

.rule-head-spaced {
  margin-top: 28px;
}

.rule-label {
  flex-shrink: 0;
  font-family: var(--font-cond);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
}

.rule-note {
  flex-shrink: 0;
  font-size: 11.5px;
  color: var(--color-dimmer);
}

/* --- Banners -------------------------------------------------------------- */

.banner {
  margin: 0 0 10px;
  padding: 7px 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--color-dim);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-left: 2px solid var(--color-line-strong);
}

.banner strong {
  font-weight: 500;
  color: var(--color-text);
}

.banner-warn {
  color: var(--color-warn);
  border-left-color: var(--color-warn);
}

.banner-warn strong {
  color: var(--color-warn);
}

/* --- Race row ------------------------------------------------------------- */

.panel-row {
  display: grid;
  grid-template-columns: minmax(0, 1.38fr) minmax(0, 1fr);
  gap: 10px;
  /* The screen is locked to 16:9, so the broadcast card cannot absorb slack. */
  align-items: start;
}

.broadcast {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.screen {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--color-bg);
}

.screen iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.broadcast-bar {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 10px;
  border-top: 1px solid var(--color-line);
  /* The whole bar fits on one line at desk width now that the faders are named
     in text rather than boxed in buttons. The wrap is kept for the windows that
     are still too narrow for it -- a half-width window, mostly. */
  flex-wrap: wrap;
}

.broadcast-id {
  flex-shrink: 0;
  font-size: 11.5px;
  color: var(--color-text);
}

.broadcast-phase {
  /* A basis rather than 0, so a status squeezed under ~120px takes the wrap
     instead of collapsing to an ellipsis with nothing left of it. It is still
     the only growing item here, so its width is unchanged wherever the row
     fits on one line. */
  flex: 1 1 120px;
  min-width: 0;
  overflow: hidden;
  font-size: 11.5px;
  color: var(--color-dim);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The faders and Full screen wrap as one unit, so a bar that is a little too
   narrow drops every control to a second line together instead of stranding
   the last button on its own. Pushed right so the status keeps the left. */
.bar-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Wider than the 7px inside a fader, so a name reads as belonging to the
     slider on its right rather than the one on its left. */
  gap: 14px;
  margin-left: auto;
}

/* Two faders under the screen: race effects and the score. They sit beside the
   Race id, so they stay small — the name reads the state, the slider trims it.
   A 1px hairline after the second one keeps Full screen from reading as a third
   fader; the mixers are the only spans in here, so :last-of-type is exact. */
.mixer {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 7px;
}

.mixer:last-of-type {
  padding-right: 14px;
  border-right: 1px solid var(--color-line);
}

/* The name is the mute. Boxed buttons made three rectangles out of a control
   that is really two labelled faders, so the box goes and the word carries the
   state: dim is off, page-white is on. Same condensed caps as the board keys. */
.mix-label {
  flex-shrink: 0;
  /* The word is small; the hit box is not. Negative margins cancel the
     padding visually, so the bar keeps its height and nothing shifts. */
  padding: 7px 4px;
  margin: -7px -4px;
  font-family: var(--font-cond);
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-dimmer);
  background: none;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  appearance: none;
  transition: color 0.12s;
}

.mix-label[aria-pressed="true"] { color: var(--color-text); }
.mix-label:hover { color: var(--color-text); text-decoration: underline; }

.mix-label:focus-visible {
  outline: 1px solid var(--flag);
  outline-offset: 3px;
}

.vol {
  width: 64px;
  min-width: 64px;
  height: 16px; /* Hit area, not the track: the track is drawn 2px inside it. */
  margin: 0;
  background: transparent;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

/* Off is one flat hairline. On fills the travel left of the thumb, so a glance
   reads the level without reading the number — watch.js keeps --fill in step
   with the value. Each vendor pseudo-element needs its own rule: a browser
   drops the whole selector list the moment it meets one it does not know. */
.vol::-webkit-slider-runnable-track {
  height: 2px;
  background: var(--color-line);
  border-radius: 1px;
}

.vol::-moz-range-track {
  height: 2px;
  background: var(--color-line);
  border-radius: 1px;
}

.mix-label[aria-pressed="true"] + .vol::-webkit-slider-runnable-track {
  background: linear-gradient(to right, var(--color-text) var(--fill, 100%), var(--color-line-strong) 0);
}

.mix-label[aria-pressed="true"] + .vol::-moz-range-track {
  background: linear-gradient(to right, var(--color-text) var(--fill, 100%), var(--color-line-strong) 0);
}

/* Hollow while the track is silent, solid once it is playing. Plain text-white,
   not the flag: the flag is the one loud thing on the page and two yellow dots
   under the video would argue with it. */
.vol::-webkit-slider-thumb {
  box-sizing: border-box;
  width: 8px;
  height: 8px;
  margin-top: -3px;
  background: transparent;
  border: 1px solid var(--color-dimmer);
  border-radius: 50%;
  appearance: none;
  -webkit-appearance: none;
}

.vol::-moz-range-thumb {
  box-sizing: border-box;
  width: 8px;
  height: 8px;
  background: transparent;
  border: 1px solid var(--color-dimmer);
  border-radius: 50%;
}

.mix-label[aria-pressed="true"] + .vol::-webkit-slider-thumb {
  background: var(--color-text);
  border-color: var(--color-text);
}

.mix-label[aria-pressed="true"] + .vol::-moz-range-thumb {
  background: var(--color-text);
  border-color: var(--color-text);
}

.vol:focus-visible {
  outline: 1px solid var(--flag);
  outline-offset: 1px;
}

/* --- The Field ------------------------------------------------------------
   Its own full-width row under the Race, headed like Results. Tucked inside
   the broadcast card it had to share a column with a 16:9 screen, which left
   the chips too small to tap and the right-hand rail hanging in mid-air. */

/* Every Racer at once. A scroller hid four fifths of the Field behind a
   scrollbar; the Field is the one thing on this page that has to look
   complete. auto-fill lets the same markup be 30 columns on a desk and 9 on a
   phone without a second layout. */
.fieldgrid {
  /* Fallback only; every chip sets its own from its silks. */
  --halo: #0b0f0c;

  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 3px;
  padding: 9px 10px 8px;
}

/* A saddlecloth: the Holder's silks carrying their number. The pattern puts
   two colours under one digit, so the digit is outlined in whichever of the
   two page inks it is not — legible on either half, and it leaves the silks
   whole instead of covering them with a patch. --halo is set per chip. */
.saddle {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  height: 26px;
  padding: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  text-shadow:
    0 0 2px var(--halo),
    0 1px 0 var(--halo),
    1px 0 0 var(--halo),
    0 -1px 0 var(--halo),
    -1px 0 0 var(--halo);
  border: 1px solid rgba(0, 0, 0, 0.5);
  border-radius: 2px;
  appearance: none;
  cursor: pointer;
  /* The wallet check scrolls a chip into view with block:"nearest", which
     otherwise parks it flush against the bottom edge of a phone screen.
     scroll-padding-top on html already clears the sticky masthead. */
  scroll-margin-bottom: 24px;
}

.saddle:hover {
  box-shadow: inset 0 0 0 1px rgba(241, 238, 227, 0.6);
}

/* Focus and selection must not read as the same thing: the white outline
   follows the keyboard, the flag ring is the Racer being read out below. Both
   at once stays legible — an outline sits outside the box-shadow. */
.saddle:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 1px;
}

.saddle[aria-pressed="true"] {
  z-index: 1;
  box-shadow: 0 0 0 2px var(--flag);
}

/* One line under the grid, always present so the card never changes height
   when a Racer is picked. */
.field-note {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 17px;
  margin: 0;
  padding: 0 10px 9px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--color-dimmer);
}

.field-note.has-pick {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--color-dim);
}

.field-note .proof {
  margin-left: 6px;
}

/* --- Click-to-copy --------------------------------------------------------
   Every address on the page is takeable, and taking one must not move anything.
   The chip is a button pinned back to exactly what the plain text rendered as —
   the UA button stylesheet would otherwise drop its own font, letter-spacing and
   alignment in and reflow the Results column the first time it appeared. */

.copy-chip {
  position: relative;
  margin: 0;
  padding: 0;
  appearance: none;
  background: none;
  border: 0;
  border-radius: 0;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  text-align: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.copy-chip:hover {
  color: var(--color-info);
}

.copy-chip:focus-visible {
  outline: 1px solid var(--color-line-strong);
  outline-offset: 2px;
}

/* The confirmation is laid *over* the stub, the way the CA button does it. It
   used to float a line above the chip, which put it on top of whatever sat
   there -- the saddle grid above the Field note, the row above in Results --
   where it was unreadable and half clipped. Inside the chip's own box nothing
   moves and nothing else is covered. Anchored left rather than centred: a
   Holder name from /wallet-names can be shorter than the word itself. */
.copy-chip[data-copied="Copied"] {
  color: transparent;
}

.copy-chip[data-copied="Copied"]::after {
  content: attr(data-copied);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  font-family: var(--font-cond);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-positive);
  white-space: nowrap;
  pointer-events: none;
}

/* The refusal state only: the chip is holding a full address for the moment the
   reader has to select it by hand, and forty-four characters will not sit on the
   one line a stub was sized for. It wraps and stays selectable rather than
   running out of its cell -- the layout moving matters less than every character
   being reachable, and it is back to a stub two and a half seconds later. */
.copy-chip[data-copied]:not([data-copied="Copied"]) {
  color: var(--color-warn);
  white-space: normal;
  word-break: break-all;
  /* Chrome will not let a drag select inside a button, so a selection lost to a
     stray click could not be made again. */
  user-select: text;
}

/* The refusal message goes beside the address, never over it -- the reader is
   being asked to select those characters by hand, so nothing may cover them. */
.copy-chip[data-copied]:not([data-copied="Copied"])::after {
  content: attr(data-copied);
  margin-left: 8px;
  font-family: var(--font-cond);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-warn);
  white-space: nowrap;
}

/* --- The board (key / value readout) --------------------------------------
   Replaces a stat grid. One column of right-aligned monospace values, dot
   leaders back to the lowercase keys, hairlines between groups. No captions
   under numbers, no uppercase-label-plus-big-figure tiles. */

.readout {
  display: grid;
  grid-template-columns: max-content minmax(10px, 1fr) max-content 26px max-content;
  align-items: center;
  padding: 9px 12px;
}

/* Both columns are max-content, so the widest key and the widest value size
   them for every row. Keys swap ("purse pool" → "this race's purse") and
   values swap ("1:15" → "racing now") as the cycle turns; without a floor the
   whole board would step sideways twice a Race. The floors clear the longest
   string either column carries. */
.rk {
  min-width: 106px;
  padding: 4px 0;
  font-size: 12px;
  color: var(--color-dim);
}

.rl {
  margin: 7px 8px 0;
  border-bottom: 1px dotted var(--color-line-strong);
}

.rv {
  min-width: 88px;
  padding: 4px 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-align: right;
  color: var(--color-text);
}

.rv-positive {
  color: var(--color-positive);
}

.ru {
  padding: 4px 0 4px 5px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-dimmer);
}

.rx {
  padding: 4px 0 4px 10px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  text-align: right;
  color: var(--color-dimmer);
}

.rsep {
  grid-column: 1 / -1;
  height: 1px;
  margin: 6px 0;
  background: var(--color-line);
}

/* The wallet the readings above are readings of. Not a row, because it is an
   address and a sentence rather than a key and a number, but it belongs to this
   board and nowhere else on the page. */
.readout-foot {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 9px;
  margin-top: 7px;
  padding-top: 8px;
  border-top: 1px solid var(--color-line);
}

.readout-foot-key {
  font-size: 12px;
  color: var(--color-dim);
}

.readout-foot-value {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--color-text);
}

.readout-foot-note {
  flex: 1 1 100%;
  font-size: 11px;
  line-height: 1.45;
  color: var(--color-dimmer);
}

.dev-wallet-chip {
  color: inherit;
}

/* --- Right rail ----------------------------------------------------------- */

.rail {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

/* --- Wallet check --------------------------------------------------------- */

.wallet-card {
  padding: 12px;
}

.wallet-copy {
  margin: 0 0 11px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--color-dim);
}

.wallet-key {
  display: block;
  margin-bottom: 5px;
  font-size: 11.5px;
  color: var(--color-dimmer);
}

.wallet-input {
  display: flex;
  gap: 6px;
}

.wallet-input .field {
  min-width: 0;
  font-size: 12px;
}

.wallet-result {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 11px 0 0;
  padding-top: 9px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--color-dim);
  border-top: 1px solid var(--color-line);
}

.wallet-result.is-in {
  color: var(--color-positive);
}

.wallet-result.is-out {
  color: var(--color-danger);
}

.wallet-result.is-none {
  color: var(--color-warn);
}

/* --- Silks ----------------------------------------------------------------
   Content, not chrome: a Holder's colours are their identity in every Race. */

.silks {
  display: inline-block;
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  border: 1px solid rgba(0, 0, 0, 0.55);
  border-radius: 2px;
}

/* --- Results -------------------------------------------------------------- */

/* Explicit longhands: a plain `overflow: hidden` here is unlayered and would
   beat theme.css's layered .scroll-x, killing the horizontal scroll on mobile.
   A non-visible overflow-x still clips the panel's corners. */
.results-card {
  overflow-x: auto;
  overflow-y: hidden;
}

.results-card .data-table th {
  font-family: var(--font-cond);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  color: var(--color-dimmer);
}

.results-card .data-table td {
  height: 30px;
}

.cell-wallet {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 11.5px;
}

.cell-mono {
  font-family: var(--font-mono);
  font-size: 11.5px;
}

.cell-dim {
  color: var(--color-dim);
}

.place-1 {
  color: var(--flag);
}

.results-empty {
  padding: 16px 10px;
  font-size: 12px;
  color: var(--color-dim);
  /* .data-table td is nowrap; the empty sentence must be allowed to wrap. */
  white-space: normal;
}

.status-paid {
  color: var(--color-positive);
}

.status-pending {
  color: var(--color-dim);
}

.status-unresolved {
  color: var(--color-warn);
}

.status-failed {
  color: var(--color-danger);
}

.proof {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-dimmer);
  text-decoration: none;
  text-underline-offset: 3px;
  transition: color 0.12s;
}

.proof:hover {
  color: var(--color-info);
  text-decoration: underline;
}

/* Zero specificity, so every rule that already colours a stub keeps winning.
   This only has to beat the browser's own blue-and-underlined link default. */
a:where(.tx-link) {
  color: inherit;
  text-decoration: none;
}

a:where(.tx-link):hover {
  text-decoration: underline;
}

.wallet-result-chip,
.field-note-chip {
  color: inherit;
}

.wallet-result .proof {
  margin-left: 6px;
}

/* --- Verify ---------------------------------------------------------------
   The claim this page makes about fairness is checkable, so the check is on the
   page rather than in a document somewhere. The link is the quietest thing in
   its row until somebody wants it; the panel below the table is the loud part,
   and it only exists once one has been clicked. */

.verify-link {
  padding: 0;
  font-family: var(--font-cond);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-dimmer);
  background: none;
  border: 0;
  appearance: none;
  cursor: pointer;
  transition: color 0.12s;
}

.verify-link:hover {
  color: var(--flag);
}

.verify-link:focus-visible {
  outline: 1px solid var(--color-line-strong);
  outline-offset: 2px;
}

/* Outside the table on purpose: Results is rebuilt from scratch on every sync,
   and a panel somebody is reading must not be one of the things thrown away. */
.verify-panel {
  margin-top: 10px;
  padding: 10px 12px 12px;
}

.verify-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--color-line);
}

.verify-title {
  font-family: var(--font-cond);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
}

.verify-head .btn {
  margin-left: auto;
}

.verify-verdict {
  margin: 10px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--color-dim);
}

.verify-verdict.is-ok {
  color: var(--color-positive);
}

.verify-verdict.is-bad {
  color: var(--color-danger);
}

.verify-verdict.is-warn {
  color: var(--color-warn);
}

/* The same board as the rail, given the width of the page. The finish-order rows
   carry addresses, so the value column is what sets the leaders' length here. */
.verify-readout {
  margin-top: 8px;
  padding: 2px 0;
}

.verify-readout .rv {
  min-width: 0;
}

.verify-hash {
  color: inherit;
}

.verify-material {
  margin-top: 11px;
  font-size: 11.5px;
  color: var(--color-dimmer);
}

.verify-material summary {
  color: var(--color-dim);
  cursor: pointer;
}

.verify-material code {
  display: block;
  margin-top: 7px;
  padding: 7px 9px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.55;
  color: var(--color-dim);
  background: var(--color-surface-2);
  border: 1px solid var(--color-line);
  word-break: break-all;
}

.verify-note {
  margin: 11px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--color-dim);
}

/* --- Rules ---------------------------------------------------------------- */

.rules-list {
  margin: 0;
  border-top: 1px solid var(--color-line);
}

.rules-item {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  gap: 20px;
  padding: 9px 0;
  border-bottom: 1px solid var(--color-line);
}

.rules-item dt {
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-family: var(--font-cond);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
}

.rules-no {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--color-dimmer);
}

.rules-item dd {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--color-dim);
}

.diamond {
  margin-top: 10px;
}

/* --- Skeletons ------------------------------------------------------------ */

.skel-val {
  width: 62px;
  height: 12px;
}

.skel-cell {
  height: 11px;
}

.skel-inline {
  width: 34px;
  height: 11px;
}

.w-2 { width: 26px; }
.w-3 { width: 42px; }
.w-4 { width: 60px; }
.w-6 { width: 94px; }

/* --- Responsive ----------------------------------------------------------- */

@media (max-width: 900px) {
  .panel-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .rules-item {
    grid-template-columns: minmax(0, 1fr);
    gap: 3px;
  }
}

@media (max-width: 700px) {
  .rule-head {
    flex-wrap: wrap;
    gap: 8px;
  }

  .rule-note {
    flex: 1 1 100%;
    order: 1;
  }

  .masthead-inner {
    flex-wrap: wrap;
    gap: 0 16px;
    min-height: 0;
    padding: 9px 14px;
  }

  .brand {
    order: 1;
  }

  .board {
    order: 2;
    padding-left: 0;
    border-left: 0;
  }

  .nav {
    order: 4;
    gap: 14px;
    width: 100%;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--color-line);
  }

  /* On a phone the masthead already wraps, so the address stops competing for
     the top row and takes a full row of its own, which also gives the copy
     button a thumb-sized target instead of a chip wedged beside the clock. */
  .ca {
    order: 3;
    width: 100%;
    margin-top: 8px;
    justify-content: space-between;
  }

  .ca-copy {
    flex: 1;
    text-align: left;
  }

  .brand-word {
    font-size: 18px;
  }

  .board-clock {
    font-size: 15px;
  }

  .shell-main {
    padding: 14px 14px 56px;
  }

  .broadcast-phase {
    flex: 1 1 100%;
    order: 3;
  }

  /* Phones: the status gets its row, then the controls get theirs. */
  .bar-tools {
    flex: 1 1 100%;
    order: 4;
  }

  /* The faders drop below the status line and share it. The names stay the size
     they are everywhere else; it is the sliders that stretch into whatever is
     left, so a thumb is still findable with a thumb. */
  .mixer {
    flex: 1 1 92px;
  }

  /* The width has to stay a real number even though the slider grows: a range
     input left on `auto` reports its ~129px UA default as its smallest size,
     which is what used to shove Full screen onto a line of its own. */
  .vol {
    flex: 1 1 52px;
    width: 52px;
    min-width: 0;
  }

  /* The hairline only separates; with the row this tight it would just be one
     more mark, and it can land at the end of a wrapped line. */
  .mixer:last-of-type {
    padding-right: 0;
    border-right: 0;
  }

  /* Thumb-sized saddlecloths. Sized by viewport rather than pointer type so it
     is the same rule the layout already breaks on. */
  .fieldgrid {
    grid-template-columns: repeat(auto-fill, minmax(32px, 1fr));
    gap: 4px;
  }

  .saddle {
    height: 30px;
  }

  /* Room for two lines (border-box, so the 9px padding is inside it): a long
     Holder name must not grow the card the moment a Racer is tapped. */
  .field-note {
    min-height: 43px;
  }

  /* Seven columns will not fit; let the card scroll rather than crush Place
     and Racer, which are the two anybody reads first. */
  .results-card .data-table {
    min-width: 640px;
  }

  /* A blockhash is forty-four characters and the finish order is three
     addresses; neither fits a phone on one line. */
  .verify-readout .rv {
    word-break: break-all;
  }
}

@media (max-width: 420px) {
  .nav a {
    font-size: 13px;
    letter-spacing: 0.08em;
  }

  .readout {
    padding: 8px;
  }

  .rk {
    font-size: 11.5px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .pulse,
  .skeleton,
  .fade {
    animation: none;
  }
}
