/* ── the venue skin ─────────────────────────────────────────────────────────

   Everything below is skin. Every position, size, grid track and mode switch in
   this file was measured against a compressed 480px frame and is left exactly
   where it was: this changes what things look like, not where they are.

   The identity is the site's — site/watch.css, turf at night, one accent. Two
   families do all the work. Barlow Condensed, uppercase and letter-spaced, is
   signage: labels, headings, kickers, WINNER, STARTS IN, the brand word, the
   position numbers. JetBrains Mono is every number and every identifier: the
   Race id, the Field size, the Purse, the clock, gaps, wallets, signatures.
   Nothing is set in anything else.                                          */

/* The chequered strip along the top edge of the stage. watch.css spends this
   motif exactly twice — the masthead mark and here — so the site and the
   broadcast are recognisably the same venue at a glance. The cell is four
   times the site's, because the frame is watched at a quarter size. */
.stage::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 16px;
  z-index: 20;
  pointer-events: none;
  background: repeating-conic-gradient(#0b0f0c 0% 25%, var(--flag) 0% 50%) 0 0 / 16px 16px;
}

/* The same mark as the site's masthead, at the broadcast's scale. */
.brand-logo { display: block; width: auto; height: 32px; }

/* Tote board: one surface, one hairline, no lit bar. */
.bar { background: var(--color-surface); border: 0; border-bottom: 2px solid var(--color-line-strong); }
.bar-foot { background: var(--color-surface); border: 0; border-top: 2px solid var(--color-line-strong); color: var(--color-dim); }
.bar-foot .foot-left { color: var(--color-text); }
.brand-name { text-shadow: none; }
/* These labels share a fixed-height ribbon at every stage scale. */
.brand-name, .conn, .stat-label, .stat-value { white-space: nowrap; }
.stat-value, .stat-hero .stat-value { text-shadow: none; }

/* The running order. Opaque blocks with a hard offset shadow: a translucent
   panel over grass is a smear once the bitrate drops. */
.row, .lower-more {
  background: var(--color-surface-2);
  color: var(--color-text);
  border: 2px solid var(--color-line-strong);
  border-radius: 2px;
  box-shadow: 4px 4px 0 var(--shadow-ink);
}
.row-pos, .lower-more { color: var(--color-dim); }
.row-addr { color: var(--color-text); }
.row-gap { color: var(--color-dim); }
/* The leader's block is the one thing on screen that changes hands, so it is
   the one thing that changes colour when it does. */
.row.lead { background: var(--flag); border-color: var(--flag-dim); }
.row.lead .row-pos, .row.lead .row-addr, .row.lead .row-gap { color: var(--flag-ink); }
.row-silk { width:28px; height:32px; border-radius:0; clip-path:polygon(0 0,100% 0,100% 80%,50% 100%,0 80%); }
.callout { border-radius:2px; }

#rail .rail-bed { background: var(--color-surface-3); border-color: var(--color-line-strong); box-shadow: 4px 4px 0 var(--shadow-ink); }
#rail .rail-fill { background: var(--flag-dim); }
#rail .rail-pack { background: var(--flag); }
#rail.hot .rail-fill { background: var(--flag); }
#rail.hot .rail-pack { background: var(--color-text); }

/* A winner's circle. The portrait reuses the exact silks of the winning wallet.
   Portrait | winner / wallet / purse / authoritative payment receipt */
.result { background: var(--color-surface); color: var(--color-text); padding:60px 80px; }
.result.show {
  display:grid;
  grid-template-columns:680px minmax(0,1fr);
  grid-template-rows:repeat(6,auto);
  align-content:center;
  align-items:center;
  justify-items:start;
  column-gap:70px;
  row-gap:18px;
}
.winner-horse { grid-column:1; grid-row:1/7; width:680px; height:500px; }
.result-kicker {
  grid-column:2; grid-row:1; margin:0;
  color: var(--flag);
  font: 700 36px var(--font-cond);
  letter-spacing:.18em;
  text-transform:uppercase;
}
.result-who { grid-column:2; grid-row:2; gap:20px; }
.result-wallet { font: 700 70px/1.1 var(--font-mono); letter-spacing:-.045em; color: var(--color-text); }
.result-silk { width:40px; height:46px; border-radius:0; clip-path:polygon(0 0,100% 0,100% 80%,50% 100%,0 80%); }
/* The loudest thing in the frame, because it is the only reason anybody
   stopped scrolling. */
.result-purse { grid-column:2; grid-row:3; color: var(--flag); font: 800 108px/1.1 var(--font-mono); margin:0; letter-spacing:-.045em; text-shadow:none; }
.result-usd { grid-column:2; grid-row:4; color: var(--color-dim); font-family: var(--font-mono); margin:0; }
/* The receipt is the point. A number on a screen is a claim; a confirmed
   signature is the only part of this a stranger can go and check. */
.result-receipt {
  grid-column:2; grid-row:5; flex-wrap:wrap; max-width:100%; gap:12px; margin:8px 0 0; padding:20px 24px;
  background: var(--color-surface-2);
  border: 2px solid var(--color-line-strong);
  border-radius: 2px;
  color: var(--color-dim);
  font: 500 27px/1.3 var(--font-mono);
}
.result-receipt.done { border-color: var(--color-positive); }
.result-receipt .tick { color: var(--color-dim); }
.result-receipt.done .tick { color: var(--color-positive); }
.result-receipt .sig { flex-basis:100%; color: var(--color-dimmer); font-size:23px; }
.result-receipt.wait { border-color: var(--color-warn); background: var(--color-surface-2); }
.result-receipt.wait .tick { color: var(--color-warn); }
.result-receipt.bad { border-color: var(--color-danger); background: var(--color-surface-2); }
.result-receipt.bad .tick { color: var(--color-danger); }
.result-places { grid-column:2; grid-row:6; gap:26px; margin:12px 0 0; color: var(--color-dimmer); font-family: var(--font-mono); font-size:24px; }
@media(prefers-reduced-motion:reduce) {
  *,*::before,*::after { animation:none!important; transition:none!important; }
}

/* The race occupies the frame. A compact score ribbon leaves the venue visible. */
.race-story {
  position:absolute; top:22px; left:40px; z-index:3;
  min-width:570px; padding:12px 24px 14px;
  background: var(--color-surface-2);
  color: var(--color-text);
  border: 2px solid var(--color-line-strong);
  border-left: 6px solid var(--flag);
  box-shadow: 4px 4px 0 var(--shadow-ink);
}
.race-story[hidden] { display:none; }
.race-story strong { display:block; font: 700 39px/1.05 var(--font-cond); letter-spacing:.06em; text-transform:uppercase; }
.race-story span { display:block; margin-top:8px; font: 500 25px/1.1 var(--font-mono); color: var(--color-dim); }
/* The final furlong is the accent turned all the way up, not a second colour. */
.race-story.hot { background: var(--flag); border-color: var(--flag-dim); border-left-color: var(--flag-ink); color: var(--flag-ink); }
.race-story.hot span { color: var(--flag-ink); }
#rail { left:710px; top:40px; height:42px; }
#rail .rail-bed { height:35px; border-width:2px; }
#rail .rail-wire { height:46px; top:-6px; width:20px; background-size:10px 10px; }
#rail .rail-chip { height:28px; top:0; }
.callout { top:146px; left:40px; padding:16px 25px; font-size:36px; transform:none; transform-origin:left center; }
.callout.show { animation:race-call 170ms ease-out; }
@keyframes race-call { from { transform:scale(1.05); opacity:0; } to { transform:scale(1); opacity:1; } }
/* The silk is the same mark as the jockey on the track, and the number on it is
   an identifier, so it is monospaced — the site's saddle chips, at broadcast
   size. */
.row-silk {
  display:flex; align-items:center; justify-content:center;
  width:46px; height:44px; flex-shrink:0; clip-path:none; border-radius:2px;
  font: 700 26px var(--font-mono); text-shadow:none;
}
.row { gap:12px; }
.row-addr { font-family: var(--font-mono); font-size:30px; letter-spacing:-.03em; }
.row-gap { font-size:27px; }
.stage.gate .race-story { opacity:0; }
.brand-name { font-family: var(--font-cond); font-size:34px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; }
.stat-value { font-family: var(--font-mono); font-weight:500; }
.stat-label { font-family: var(--font-cond); font-weight:600; color: var(--color-dim); font-size:23px; letter-spacing:.12em; text-transform:uppercase; }
.stat-hero .stat-value { font-size:53px; font-style:normal; font-weight:700; }
.bar-stats { gap:42px; }
/* Race mode returns space to the course. Rules and historical totals live between Races. */
.stage.race-view { grid-template-rows:78px 1fr 0; }
:is(.race-view,.showcase-view) .bar { padding:16px 30px 0; }
.race-view .bar-foot { visibility:hidden; overflow:hidden; padding:0; }
:is(.race-view,.showcase-view) .brand-name { font-size:29px; }
:is(.race-view,.showcase-view) .stat { flex-direction:row; align-items:baseline; gap:12px; }
:is(.race-view,.showcase-view) .stat-value { font-size:30px; }
:is(.race-view,.showcase-view) .stat-hero .stat-value { font-size:39px; }
:is(.race-view,.showcase-view) .stat-sub { display:none; }
.race-view .race-story { top:16px; left:30px; min-width:420px; padding:10px 18px; border-left-width:5px; }
.race-view .race-story strong { font-size:30px; }
.race-view .race-story span { font-size:24px; margin-top:4px; }
.race-view #rail { left:530px; right:30px; top:36px; }
.race-view .callout { display:none; }
.race-view .lower { left:30px; right:30px; bottom:14px; }
.race-view .lower-more { display:none; }
.race-view .lower-rows { justify-content:center; flex:0 1 auto; }
.race-view .lower { justify-content:center; }
.race-view .row { padding:10px 16px; }
.race-view .row-addr { display:none; }
.race-view .row-gap { font-size:27px; }
.race-view .row-pos { font: 700 24px var(--font-cond); letter-spacing:.06em; color: var(--color-dim); }
.race-view .row.lead .row-pos { color: var(--flag-ink); }
.race-view .row-silk { width:44px; height:39px; }

/* The pre-race programme shares the course and actual wallet silks. */
.stage.showcase-view { grid-template-rows:78px 1fr 0; }
.showcase-view .bar-foot { display:none; }
.lineup-view .interstitial { background:transparent; }
.lineup-view .inter-inner { grid-template-rows:100px 1fr 38px; }
.lineup-view :is(.course-map,.field-parade) { display:none; }
.lineup-view .showcase-foot { grid-row:3; }
.lineup-view :is(.showcase-heading,.showcase-countdown,.showcase-foot) {
  background: var(--color-surface); padding:10px 18px; border-radius:2px; border:2px solid var(--color-line);
}
.conn[hidden] { display:none; }
/* The screen that is up for most of every cycle sits on the stage's own ground
   rather than on a panel of its own: nothing here should look like a modal. */
.interstitial { background: var(--color-bg); color: var(--color-text); }
.inter-inner { width:100%; height:100%; box-sizing:border-box; padding:28px 64px 32px; display:grid; grid-template-columns:1fr 300px; grid-template-rows:100px minmax(0,1fr) 176px 66px 38px; gap:16px 32px; text-align:left; }
.showcase-heading { align-self:center; }
.showcase-heading h1 { margin:0 0 7px; font: 800 58px/1 var(--font-cond); letter-spacing:.05em; text-transform:uppercase; color: var(--color-text); }
.showcase-heading p { margin:0; color: var(--color-dim); font: 500 26px var(--font-mono); }
.showcase-countdown { text-align:right; align-self:center; border-left:2px solid var(--color-line); padding-left:32px; }
.inter-kicker { margin:0 0 3px; color: var(--color-dim); font: 600 25px var(--font-cond); letter-spacing:.14em; text-transform:uppercase; }
.inter-clock { font: 700 68px/1 var(--font-mono); color: var(--color-text); letter-spacing:-.05em; text-shadow:none; }
.inter-clock.urgent { color: var(--flag); }
/* Setting the Field puts a count in the clock's slot rather than a time. It runs
   smaller because a count and its separators are half again as wide as `0:00`,
   and the column stays 300px whatever the coin's holder list is doing. */
.inter-clock.count { font-size:48px; letter-spacing:-.02em; font-variant-numeric:tabular-nums; white-space:nowrap; }
.inter-unit { margin-top:5px; color: var(--color-dimmer); font: 600 19px var(--font-cond); letter-spacing:.14em; text-transform:uppercase; }
.inter-unit:empty { display:none; }
.course-map { grid-column:1/-1; min-height:0; overflow:hidden; background: var(--color-surface); border:2px solid var(--color-line); }
.course-map canvas { display:block; width:100%; height:100%; object-fit:contain; }
.field-parade { grid-column:1/-1; min-height:0; background:var(--color-surface); border-top:2px solid var(--color-line); border-bottom:2px solid var(--color-line); }
.field-parade canvas { display:block; width:100%; height:100%; object-fit:contain; }
.showcase-foot { grid-column:1/-1; display:flex; justify-content:space-between; gap:24px; align-items:center; color: var(--color-dim); }
.inter-last,.inter-sub { margin:0; font: 500 23px var(--font-mono); color:inherit; }
.inter-sub { max-width:1080px; text-align:right; }
.gate-rail { position:absolute; left:0; right:0; bottom:0; width:100%; margin:0; height:7px; }
.gate-rail .rail-bed { height:7px; border:0; border-radius:0; background: var(--color-surface-3); box-shadow:none; }
.gate-rail .rail-fill { background: var(--flag); }
.gate-rail .rail-wire,.gate-rail .rail-poles { display:none; }
.inter-bar { position:absolute; bottom:0; left:0; width:100%; height:7px; margin:0; }

/* ── the contract address ──────────────────────────────────────────────────

   The address used to be a 12px monospace line injected into whatever container
   a script could find. Authored at 1920 and watched at about 500, that is three
   pixels tall on the stream -- so on the one surface where the address is the
   entire point of the broadcast, it was not on screen at all. It also carried a
   Copy button, on a video, rendered by a machine with no keyboard.

   So it is sized the way everything else here is sized: against what survives a
   four-times downscale. The band on the countdown sets the address at 42px and
   the strip during the race at 30px -- the same size as a stat value, which is
   the floor this page already trusts.

   It stays off the flag yellow deliberately. That accent belongs to the Purse,
   first place and the wire, and an address that outshouts the money would be
   reading the room wrong. Width is the loudness here, not colour. */

.ca-board {
  grid-column:1/-1;
  display:flex;
  align-items:center;
  gap:28px;
  min-width:0;
  padding:0 24px;
  background: var(--color-surface);
  border:2px solid var(--color-line-strong);
}
.ca-board-key {
  flex-shrink:0;
  font: 600 25px var(--font-cond);
  letter-spacing:.14em;
  text-transform:uppercase;
  color: var(--color-dim);
}
/* Never ellipsised. A truncated address is not an address, and if it ever did
   overflow the frame that is a bug worth seeing rather than hiding. */
.ca-board-value {
  font: 700 42px var(--font-mono);
  letter-spacing:-.02em;
  color: var(--color-text);
}

/* 27px is not a compromise picked by eye: it is the largest the address can be
   set and still clear the Purse in the narrowest header this page has, measured
   against the widest numbers it will ever hold. It is also exactly the size of
   the gap figures beside each Racer, which is this view's established floor for
   something a viewer is expected to read. Nothing here shrinks or ellipsises --
   if the bar ever did run out of room that should be visible, not swallowed. */
.ca-strip { display:flex; flex-shrink:0; align-items:baseline; gap:12px; min-width:0; white-space:nowrap; }
.ca-strip-key {
  font: 600 19px var(--font-cond);
  letter-spacing:.16em;
  text-transform:uppercase;
  color: var(--color-dimmer);
}
.ca-strip-value {
  font: 700 27px var(--font-mono);
  letter-spacing:-.03em;
  color: var(--color-text);
}
/* The two views that shrink the header also tighten it, because they are the two
   carrying the widest stats. */
:is(.race-view,.showcase-view) .bar { gap:24px; }

/* The parade is the exception, and the reason is in race-camera.js: the lens
   keeps the nearest Racer clear of the bottom 95 pixels of the frame, and the
   band is 66 tall sitting 57 pixels inside that reserve. Everywhere else that
   does not matter, because the countdown paints an opaque background over the
   course -- but the lineup is deliberately transparent, so the real turf is
   showing through and the band would sit across the near horses' legs for the
   ten seconds before every Gate. So the lineup keeps the layout it had, and the
   address rides in the header there instead.

   Otherwise: one address on screen at a time. The header's copy stands down
   whenever the board is up, which is not the same as `showcase-view` -- the
   countdown also covers the paused and waiting phases, which set no view class
   at all. */
.lineup-view .ca-board { display:none; }
.stage:has(.interstitial.show):not(.lineup-view) .ca-strip { display:none; }

.ca-board[hidden], .ca-strip[hidden] { display:none; }

/* ── the sound prompt ─────────────────────────────────────────────────────── */

/* Everything else on this page is authored for a machine with nobody at the
   keyboard. This one thing is authored for the person who opened the broadcast
   in their own browser and heard nothing, because browsers will not let a page
   make a sound until it has been clicked. It only unhides when the audio really
   is blocked, so on the stream -- where Chromium is launched with autoplay
   allowed -- it is never in the frame.

   Styled as a paddock sign rather than a media control: the same hard offset
   shadow and heavy border the rail and the running order use, with the flag
   colour on the speaker so it reads at a glance instead of being a grey chrome
   button parked on the turf. */
.sound-hint {
  position: absolute;
  right: 40px;
  bottom: 30px;
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 26px 14px 20px;
  border: 2px solid var(--color-line-strong);
  border-radius: 2px;
  background: var(--color-surface);
  box-shadow: 4px 4px 0 var(--shadow-ink);
  color: var(--color-text);
  font: 700 30px var(--font-cond);
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  animation: sound-hint-in .28s ease-out both;
}
.sound-hint:hover { background: var(--color-surface-2); }

/* A speaker with two waves, drawn rather than imported, so it needs no font and
   no file and cannot arrive late. */
.sound-hint-icon {
  width: 30px;
  height: 30px;
  flex: none;
  background: var(--flag);
  clip-path: polygon(0 34%, 30% 34%, 62% 4%, 62% 96%, 30% 66%, 0 66%);
}
@keyframes sound-hint-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.sound-hint[hidden] { display: none; }
