/* ==========================================================================
   Cliff Hanger Scoreboard — display styles
   The Cellar Church Holiday Bible Club, 28–31 July 2026

   Authored at exactly 1920x1080. Every number in this file is a CSS pixel
   at 1:1 on that canvas and comes from
   design_handoff_cliff_hanger_scoreboard/README.md. The whole frame is
   scaled with ONE transform in scoreboard.js — nothing here re-flows, so
   there are no media queries, no viewport units and no percentages except
   where the design itself uses them (token heights, torn-paper polygons).
   ========================================================================== */

/* ------------------------------------------------------------------ fonts */
/* Self-hosted. The hall display must render correctly with no internet. */

@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url('fonts/anton-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url('fonts/anton-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fredoka';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: block;
  src: url('fonts/fredoka-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fredoka';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: block;
  src: url('fonts/fredoka-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ----------------------------------------------------------------- tokens */

:root {
  --pine:  #253320;   /* frame background, all dark text and motifs */
  --leaf:  #5FB246;   /* band fills, secondary labels, highlight column */
  --sage:  #DCE7C6;   /* plateau, base plates, rope, light text */
  --red:   #E0392B;   /* state tag, flag, callout, trophy */
  --peach: #F7DACD;   /* day badge, motif discs, BASECAMP chip, rings */

  --cliff-1: #1B2716;
  --cliff-2: #22301B;
  --cliff-3: #2B3B23;
  --cliff-4: #324429;
  --cliff-5: #37492D;
  --cliff-6: #3C5131;
  --cliff-hi: #4C6440;

  --anton: 'Anton', 'Haettenschweiler', 'Arial Narrow Bold', sans-serif;
  --fredoka: 'Fredoka', system-ui, sans-serif;
}

/* Team colours are fixed — they match badges parents already hold. */
.team-rocky-rockets     { --tc: #2F9BD6; }
.team-summit-superstars { --tc: #FFC629; }
.team-mountain-movers   { --tc: #C2CCC4; }
.team-peak-performers   { --tc: #F5822A; }

/* ------------------------------------------------------------- letterbox */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--pine);
}

body { font-family: var(--fredoka); }

/* The letterbox. The frame inside it is positioned at the top left and
   centred by the same single transform that scales it, so there is only
   ever one transform to reason about. */
#screen {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--pine);
  --sk: 9px;             /* shake amplitude; scoreboard.js scales it to the TV */
}

/* A short jolt on every award. Applied here rather than to #frame so it can
   never disturb the single fit transform, and because the surround is the
   same pine as the frame nothing shows at the edges while it moves. */
#screen.shake { animation: board-shake 620ms cubic-bezier(.36, .07, .19, .97) both; }

@keyframes board-shake {
  0%,
  100% { transform: translate(0, 0) rotate(0deg); }
  8%   { transform: translate(calc(var(--sk) * -1), calc(var(--sk) * 0.5)) rotate(-0.45deg); }
  18%  { transform: translate(var(--sk), calc(var(--sk) * -0.4)) rotate(0.4deg); }
  30%  { transform: translate(calc(var(--sk) * -0.75), calc(var(--sk) * 0.3)) rotate(-0.32deg); }
  42%  { transform: translate(calc(var(--sk) * 0.6), calc(var(--sk) * -0.25)) rotate(0.26deg); }
  55%  { transform: translate(calc(var(--sk) * -0.42), calc(var(--sk) * 0.18)) rotate(-0.18deg); }
  68%  { transform: translate(calc(var(--sk) * 0.28), calc(var(--sk) * -0.12)) rotate(0.12deg); }
  82%  { transform: translate(calc(var(--sk) * -0.14), calc(var(--sk) * 0.06)) rotate(-0.06deg); }
}

body.idle { cursor: none; }

/* ----------------------------------------------------------------- frame */

#frame {
  position: absolute;
  left: 0;
  top: 0;
  width: 1920px;
  height: 1080px;
  background: var(--pine);
  overflow: hidden;
  transform-origin: top left;
}

/* ---------------------------------------------------------------- header */

.hdr {
  position: absolute;
  left: 0;
  top: 0;
  width: 1920px;
  height: 112px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 56px;
  z-index: 20;
}

.hdr-left { display: flex; align-items: center; gap: 16px; }

.lockup-mark {
  position: relative;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--leaf);
  display: flex;
  align-items: center;
  justify-content: center;
}
.lockup-mark i {
  width: 22px;
  height: 20px;
  background: var(--pine);
  clip-path: polygon(50% 6%, 96% 94%, 4% 94%);
}
.lockup-words { display: flex; flex-direction: column; gap: 3px; }
.lockup-words span {
  font-family: var(--anton);
  font-size: 19px;
  letter-spacing: 4px;
  line-height: 1;
}
.lockup-words .l1 { color: var(--sage); }
.lockup-words .l2 { color: var(--leaf); }

.hdr-mid { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.wordmark {
  font-family: var(--fredoka);
  font-weight: 700;
  font-size: 62px;
  line-height: 1;
  letter-spacing: 1px;
  color: var(--sage);
}
.strapline {
  font-family: var(--anton);
  font-size: 15px;
  letter-spacing: 6px;
  color: var(--leaf);
}

.hdr-right { display: flex; align-items: center; justify-content: flex-end; gap: 16px; }
.state-tag {
  font-family: var(--anton);
  font-size: 22px;
  letter-spacing: 3px;
  color: var(--red);
}
.day-badge {
  background: var(--peach);
  border-radius: 999px;
  padding: 11px 26px 9px;
}
.day-badge span {
  font-family: var(--anton);
  font-size: 28px;
  letter-spacing: 3px;
  color: var(--pine);
  line-height: 1;
}

/* ----------------------------------------------------------------- stage */

.stage {
  position: absolute;
  left: 0;
  top: 112px;
  width: 1920px;
  height: 968px;
  overflow: hidden;
}

/* ------------------------------------------------------------ cliff face */
/* Flat angular facets, re-authored from the design reference as a tile that
   repeats vertically so the cliff can scroll for ever. Palette, ledges and
   flat treatment are unchanged; only the coordinates moved, which the design
   README expressly allows ("they are decorative and may be re-authored").

   Every facet sits between y=50 and y=900 of the 968px tile, so each join
   lands on flat base colour and cannot be seen. */

.cliff-base { position: absolute; inset: 0; background: var(--cliff-3); z-index: 0; }

/* The two layers that move with the camera. Same transform on both, applied
   by scoreboard.js; their z-indexes keep the design's stacking order:
   cliff (1) < plateau (2,3) < routes (6) < basecamp (8) < plates (12). */
.world-back  { position: absolute; inset: 0; z-index: 1; }
.world-front { position: absolute; inset: 0; z-index: 8; }
.world-back,
.world-front { transition: transform 900ms cubic-bezier(.22, 1, .36, 1); will-change: transform; }
#frame.no-anim .world-back,
#frame.no-anim .world-front { transition: none; }

/* Tall strip of stacked tiles, anchored to the bottom of the stage and
   extending up the mountain. scoreboard.js clones the tile and sets --tiles. */
.cliff-scroll {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1920px;
  height: calc(968px * var(--tiles, 1));
}

.cliff-tile { position: absolute; left: 0; width: 1920px; height: 968px; }
.cliff-tile > div { position: absolute; }

.fc1  { left: -40px;  top: 60px;  width: 600px; height: 380px; background: var(--cliff-4); clip-path: polygon(0 0, 68% 0, 100% 17%, 80% 39%, 100% 61%, 72% 100%, 0 100%); }
.fc2  { left: 250px;  top: 90px;  width: 470px; height: 400px; background: var(--cliff-2); clip-path: polygon(0 0, 100% 5%, 70% 45%, 100% 77%, 38% 100%, 0 60%); }
.fc3  { left: 540px;  top: 120px; width: 560px; height: 500px; background: var(--cliff-5); clip-path: polygon(14% 0, 86% 9%, 100% 51%, 64% 100%, 8% 83%, 0 35%); }
.fc4  { left: 860px;  top: 60px;  width: 500px; height: 360px; background: var(--cliff-6); clip-path: polygon(0 0, 72% 3%, 100% 43%, 50% 77%, 10% 50%); }
.fc5  { left: 1190px; top: 80px;  width: 560px; height: 560px; background: var(--cliff-2); clip-path: polygon(20% 0, 100% 11%, 86% 55%, 100% 100%, 24% 91%, 0 43%); }
.fc6  { left: 1540px; top: 50px;  width: 460px; height: 500px; background: var(--cliff-4); clip-path: polygon(28% 0, 100% 0, 100% 100%, 8% 100%, 32% 60%, 0 28%); }
.fc7  { left: 120px;  top: 500px; width: 420px; height: 400px; background: var(--cliff-6); clip-path: polygon(0 22%, 64% 0, 100% 46%, 72% 100%, 6% 84%); }
.fc8  { left: 620px;  top: 600px; width: 520px; height: 300px; background: var(--cliff-2); clip-path: polygon(10% 0, 88% 14%, 100% 78%, 44% 100%, 0 52%); }
.fc9  { left: 1120px; top: 560px; width: 520px; height: 340px; background: var(--cliff-4); clip-path: polygon(0 14%, 70% 0, 100% 40%, 80% 100%, 14% 88%); }
.fc10 { left: 1660px; top: 400px; width: 300px; height: 320px; background: var(--cliff-6); clip-path: polygon(0 30%, 60% 0, 100% 52%, 54% 100%); }
.fc11 { left: 30px;   top: 180px; width: 240px; height: 260px; background: var(--cliff-1); clip-path: polygon(0 40%, 56% 0, 100% 58%, 40% 100%); }
.fc12 { left: 1360px; top: 700px; width: 260px; height: 200px; background: var(--cliff-1); clip-path: polygon(0 26%, 58% 0, 100% 66%, 32% 100%); }

/* Bridging facets. Each is drawn twice per tile, exactly 968px apart, so the
   copy hanging off one tile's top edge lands precisely on the copy hanging
   off the next tile's bottom edge. That carries rock across every join and
   stops the flat base colour reading as a band scrolling up the screen. */
.fcb1a { left: 300px;  top: -70px; width: 520px; height: 200px; background: var(--cliff-4); clip-path: polygon(6% 0, 78% 12%, 100% 62%, 54% 100%, 0 74%); }
.fcb1b { left: 300px;  top: 898px; width: 520px; height: 200px; background: var(--cliff-4); clip-path: polygon(6% 0, 78% 12%, 100% 62%, 54% 100%, 0 74%); }
.fcb2a { left: 1150px; top: -60px; width: 480px; height: 190px; background: var(--cliff-5); clip-path: polygon(0 22%, 62% 0, 100% 48%, 70% 100%, 12% 84%); }
.fcb2b { left: 1150px; top: 908px; width: 480px; height: 190px; background: var(--cliff-5); clip-path: polygon(0 22%, 62% 0, 100% 48%, 70% 100%, 12% 84%); }
.fcb3a { left: -60px;  top: -50px; width: 400px; height: 170px; background: var(--cliff-2); clip-path: polygon(0 0, 72% 8%, 100% 54%, 46% 100%, 0 82%); }
.fcb3b { left: -60px;  top: 918px; width: 400px; height: 170px; background: var(--cliff-2); clip-path: polygon(0 0, 72% 8%, 100% 54%, 46% 100%, 0 82%); }

/* three full-width angled ledges, each with a highlight sliver above it */
.ledge  { left: 0; width: 1920px; background: var(--cliff-1); }
.ledge1 { top: 210px; height: 34px; clip-path: polygon(0 34%, 100% 0, 100% 66%, 0 100%); opacity: 0.65; }
.ledge2 { top: 470px; height: 30px; clip-path: polygon(0 0, 100% 40%, 100% 100%, 0 62%); opacity: 0.6; }
.ledge3 { top: 740px; height: 32px; clip-path: polygon(0 40%, 100% 4%, 100% 62%, 0 100%); opacity: 0.6; }

.sliver  { left: 0; width: 1920px; height: 6px; background: var(--cliff-hi); }
.sliver1 { top: 206px; clip-path: polygon(0 40%, 100% 0, 100% 60%, 0 100%); opacity: 0.7; }
.sliver2 { top: 466px; clip-path: polygon(0 0, 100% 40%, 100% 100%, 0 60%); opacity: 0.6; }
.sliver3 { top: 736px; clip-path: polygon(0 42%, 100% 2%, 100% 60%, 0 100%); opacity: 0.6; }

.crack  { width: 8px; background: var(--cliff-1); }
.crack1 { left: 410px;  top: 300px; height: 300px; clip-path: polygon(40% 0, 100% 32%, 55% 66%, 100% 100%, 0 96%, 45% 60%, 0 26%); opacity: 0.8; }
.crack2 { left: 1010px; top: 180px; height: 340px; clip-path: polygon(50% 0, 100% 30%, 40% 62%, 100% 100%, 10% 94%, 60% 58%, 0 24%); opacity: 0.75; }
.crack3 { left: 1490px; top: 520px; height: 280px; clip-path: polygon(40% 0, 100% 34%, 50% 64%, 100% 100%, 0 92%, 55% 58%, 0 28%); opacity: 0.75; }

/* Overlays span the whole scrolling strip, so the texture travels with the
   rock. Both gradients repeat, so there is no seam to line up. */
.strata {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(0deg,
    rgba(220, 231, 198, 0.05) 0 2px, rgba(220, 231, 198, 0) 2px 44px);
}
.diagonals {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(102deg,
    rgba(21, 30, 15, 0.14) 0 3px, rgba(21, 30, 15, 0) 3px 110px);
}

/* -------------------------------------------------------- summit plateau */
/* Two stacked torn-paper bands, the back one 14px taller, sharing one
   polygon. This is the poster's signature motif. */

.plateau {
  position: absolute;
  left: 0;
  top: 0;
  width: 1920px;
  clip-path: polygon(0 0, 100% 0, 100% 74%, 96% 92%, 92% 76%, 88% 94%, 84% 78%,
    80% 95%, 76% 79%, 72% 93%, 68% 76%, 64% 94%, 60% 78%, 56% 95%, 52% 79%,
    48% 93%, 44% 76%, 40% 94%, 36% 78%, 32% 95%, 28% 79%, 24% 93%, 20% 76%,
    16% 94%, 12% 78%, 8% 95%, 4% 79%, 0 92%);
}
.plateau-back  { height: 132px; background: var(--leaf); z-index: 2; }
.plateau-front { height: 118px; background: var(--sage); z-index: 3; }

/* Nothing else may live in this strip — a team on the summit stands here. */
.summit {
  position: absolute;
  left: 56px;
  top: 14px;
  height: 80px;
  display: flex;
  align-items: center;
  gap: 20px;
  z-index: 8;
}
.summit-pole {
  position: relative;
  width: 14px;
  height: 74px;
  background: var(--pine);
  border-radius: 3px;
}
.summit-pennant {
  position: absolute;
  left: 14px;
  top: 2px;
  width: 74px;
  height: 40px;
  background: var(--red);
  clip-path: polygon(0 0, 100% 26%, 0 52%, 0 0);
}
.summit-title {
  margin-left: 64px;
  font-family: var(--anton);
  font-size: 40px;
  letter-spacing: 5px;
  color: var(--pine);
  line-height: 1;
}
.summit-target {
  font-family: var(--anton);
  font-size: 22px;
  letter-spacing: 3px;
  color: var(--leaf);
  line-height: 1;
  padding-top: 6px;
}

/* ---------------------------------------------------------------- routes */
/* top 132, height 596. That 596 IS the scoring track: 0% = basecamp,
   100% = the summit target. */

.routes {
  position: absolute;
  left: 56px;
  right: 56px;
  top: 132px;
  height: 596px;
  display: flex;
  gap: 24px;
  z-index: 6;
}

.route {
  position: relative;
  flex: 1 1 0;
  height: 596px;
  opacity: 1;
  transition: opacity 400ms ease;
}

.rope {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 0;
  bottom: 0;
  width: 7px;
  border-radius: 4px;
  opacity: 0.85;
  background: repeating-linear-gradient(180deg,
    var(--sage) 0 15px, rgba(220, 231, 198, 0.12) 15px 24px);
}

/* altitude gradation marks at 25 / 50 / 75% */
.mark {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 112px;
  height: 5px;
  border-radius: 3px;
  background: var(--sage);
  opacity: 0.45;
}
.mark-label {
  position: absolute;
  left: 50%;
  margin-left: 98px;
  transform: translateY(50%);
  font-family: var(--anton);
  font-size: 20px;
  letter-spacing: 2px;
  color: var(--sage);
  opacity: 0.5;
  line-height: 1;
}
.m25 { bottom: 25%; }
.m50 { bottom: 50%; }
.m75 { bottom: 75%; }

/* ----------------------------------------------------------------- token */
/* 150x150 box, vertical centre at bottom: score / target * 100%.
   This is the anchor point if flat vector artwork is ever commissioned. */

.token {
  position: absolute;
  left: 50%;
  bottom: 0%;
  transform: translate(-50%, 50%);
  width: 150px;
  height: 150px;
  z-index: 7;
  display: flex;
  align-items: center;
  justify-content: center;
}
.carabiner {
  position: absolute;
  left: 50%;
  top: -6px;
  width: 34px;
  height: 52px;
  border-radius: 17px;
  border: 9px solid var(--pine);
  transform: translateX(-50%);
}
.footbar {
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: 56px;
  height: 14px;
  border-radius: 7px;
  background: var(--pine);
  transform: translateX(-50%);
}
.disc {
  position: relative;
  width: 132px;
  height: 132px;
  border-radius: 50%;
  background: var(--tc);
  box-shadow: 0 0 0 8px var(--pine);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---------------------------------------------------------------- motifs */

.motif { position: relative; }

.motif.rocket { width: 64px; height: 80px; }
.motif.rocket .body {
  position: absolute; left: 19px; top: 0;
  width: 30px; height: 60px;
  border-radius: 16px 16px 5px 5px;
  background: var(--pine);
}
.motif.rocket .port {
  position: absolute; left: 27px; top: 14px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--tc);
}
.motif.rocket .fin-l {
  position: absolute; left: 0; bottom: 8px; width: 20px; height: 28px;
  background: var(--pine); clip-path: polygon(100% 0, 100% 100%, 0 100%);
}
.motif.rocket .fin-r {
  position: absolute; right: 0; bottom: 8px; width: 20px; height: 28px;
  background: var(--pine); clip-path: polygon(0 0, 100% 100%, 0 100%);
}

.motif.star {
  width: 76px; height: 76px; background: var(--pine);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%,
                     21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.motif.boulder {
  width: 80px; height: 66px; background: var(--pine);
  border-radius: 56% 44% 62% 38% / 62% 56% 44% 48%;
}
.motif.peak {
  width: 84px; height: 64px; background: var(--pine);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

/* small versions, inside the 54px disc on a base plate */
.motif.sm.rocket { width: 30px; height: 36px; }
.motif.sm.rocket .body { left: 8px; top: 0; width: 15px; height: 28px; border-radius: 8px 8px 3px 3px; }
.motif.sm.rocket .port { left: 12px; top: 7px; width: 6px; height: 6px; background: var(--peach); }
.motif.sm.rocket .fin-l { left: 1px; bottom: 6px; width: 9px; height: 13px; }
.motif.sm.rocket .fin-r { right: 1px; bottom: 6px; width: 9px; height: 13px; }
.motif.sm.star    { width: 34px; height: 34px; }
.motif.sm.boulder { width: 36px; height: 30px; }
.motif.sm.peak    { width: 38px; height: 29px; }

/* -------------------------------------------------------- basecamp band */

.band {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1920px;
  clip-path: polygon(0 12%, 4% 3%, 8% 14%, 12% 4%, 16% 15%, 20% 5%, 24% 13%,
    28% 3%, 32% 14%, 36% 6%, 40% 15%, 44% 4%, 48% 13%, 52% 5%, 56% 14%,
    60% 3%, 64% 15%, 68% 6%, 72% 13%, 76% 4%, 80% 14%, 84% 5%, 88% 15%,
    92% 3%, 96% 13%, 100% 6%, 100% 100%, 0 100%);
}
.band-back  { height: 252px; background: var(--sage); z-index: 8; }
.band-front { height: 238px; background: var(--leaf); z-index: 9; }

.basecamp-chip {
  position: absolute;
  left: 56px;
  bottom: 252px;
  z-index: 13;
  background: var(--peach);
  border-radius: 8px;
  padding: 9px 16px 6px;
}
.basecamp-chip span {
  font-family: var(--anton);
  font-size: 22px;
  letter-spacing: 5px;
  color: var(--pine);
  line-height: 1;
}

/* ------------------------------------------------------------ base plates */

.plates {
  position: absolute;
  left: 56px;
  right: 56px;
  bottom: 22px;
  display: flex;
  gap: 24px;
  z-index: 12;
}

.plate {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  background: var(--sage);
  border-radius: 10px;
  border-top: 12px solid var(--tc);
  padding: 14px 20px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-shadow: 0 8px 0 rgba(21, 30, 15, 0.22);
}

.plate-row1 { display: flex; align-items: center; gap: 14px; }
.plate-disc {
  position: relative;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--peach);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.plate-id { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.route-label {
  font-family: var(--anton);
  font-size: 15px;
  letter-spacing: 3px;
  color: var(--pine);
  opacity: 0.5;
  line-height: 1;
}
.team-name {
  font-family: var(--fredoka);
  font-weight: 700;
  font-size: 28px;
  line-height: 1;
  color: var(--pine);
  white-space: nowrap;
  text-transform: uppercase;
}

.plate-row2 {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}
.score-group { display: flex; align-items: flex-end; gap: 8px; }
.score {
  font-family: var(--anton);
  font-size: 96px;          /* never below 80px — the hall is 10m deep */
  line-height: 0.76;
  letter-spacing: -1px;
  color: var(--pine);
  font-variant-numeric: tabular-nums;
}
.pts {
  font-family: var(--anton);
  font-size: 20px;
  letter-spacing: 2px;
  color: var(--pine);
  opacity: 0.55;
  padding-bottom: 6px;
}
.chips { display: flex; align-items: center; gap: 10px; padding-bottom: 8px; }

.chip {
  border-radius: 7px;
  padding: 8px 14px 5px;
  font-family: var(--anton);
  font-size: 26px;
  letter-spacing: 2px;
  line-height: 1;
}
.chip-rank  { background: var(--pine); color: var(--sage); }
.chip-award { background: var(--red);  color: var(--peach); }

/* flat trophy, winner's plate only */
.trophy { position: relative; width: 40px; height: 50px; flex: none; }
.trophy .cup   { position: absolute; left: 6px;  top: 0;    width: 28px; height: 23px; border-radius: 4px 4px 15px 15px; background: var(--red); }
.trophy .ear-l { position: absolute; left: 0;    top: 3px;  width: 9px;  height: 14px; border-radius: 6px 0 0 6px; border: 4px solid var(--red); border-right: none; }
.trophy .ear-r { position: absolute; right: 0;   top: 3px;  width: 9px;  height: 14px; border-radius: 0 6px 6px 0; border: 4px solid var(--red); border-left: none; }
.trophy .stem  { position: absolute; left: 16px; top: 23px; width: 8px;  height: 11px; background: var(--red); }
.trophy .foot  { position: absolute; left: 6px;  top: 34px; width: 28px; height: 9px;  border-radius: 3px; background: var(--pine); }

/* ==========================================================================
   STATE 2 — POINTS AWARDED
   Everything below is inert until scoreboard.js puts .is-awarding on the
   frame and .awarded on one route + its plate.
   ========================================================================== */

.highlight,
.burst,
.ring,
.callout,
.chip-award,
.rank-flag,
.chip-rank,
.trophy { display: none; }

.highlight {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: 200px;
  height: 596px;
  border-radius: 100px 100px 0 0;
  background: linear-gradient(180deg, rgba(95, 178, 70, 0) 0%, rgba(95, 178, 70, 0.26) 100%);
}

.burst {
  position: absolute;
  left: 50%;
  bottom: 0%;
  width: 440px;
  height: 440px;
  transform: translate(-50%, 50%);
  background: repeating-conic-gradient(from 0deg,
    #FFC629 0deg 4deg, rgba(255, 198, 41, 0) 4deg 20deg);
  -webkit-mask-image: radial-gradient(circle, rgba(0,0,0,0) 26%, #000 40%, rgba(0,0,0,0) 74%);
          mask-image: radial-gradient(circle, rgba(0,0,0,0) 26%, #000 40%, rgba(0,0,0,0) 74%);
  opacity: 0.9;
}

.ring {
  position: absolute;
  left: 50%;
  bottom: 0%;
  width: 196px;
  height: 196px;
  transform: translate(-50%, 50%);
  border: 7px solid var(--peach);
  border-radius: 50%;
  opacity: 0.9;
}

.callout {
  position: absolute;
  left: 50%;
  bottom: 0%;
  margin-left: 88px;
  transform: rotate(-7deg) translateY(-56px);
  background: var(--red);
  border-radius: 16px;
  padding: 12px 28px 8px;
  box-shadow: 0 10px 0 rgba(21, 30, 15, 0.35);
  z-index: 9;
  white-space: nowrap;
}
.callout span {
  font-family: var(--anton);
  font-size: 76px;
  letter-spacing: 2px;
  color: var(--peach);
  line-height: 1;
}

/* the awarded route shows its celebration, the other three drop back */
#frame.is-awarding .route:not(.awarded) { opacity: 0.5; }
#frame.is-awarding .route.awarded .highlight,
#frame.is-awarding .route.awarded .burst,
#frame.is-awarding .route.awarded .ring,
#frame.is-awarding .route.awarded .callout { display: block; }
/* altitude labels are hidden on a route showing a burst */
#frame.is-awarding .route.awarded .mark-label { display: none; }
#frame.is-awarding .plate.awarded .chip-award { display: block; }

/* ==========================================================================
   STATE 3 — FINAL RESULT
   ========================================================================== */

.rank-flag {
  position: absolute;
  left: 50%;
  bottom: 0%;
  margin-left: -192px;
  transform: translateY(50%);
  background: var(--peach);
  border-radius: 12px;
  padding: 10px 20px 7px;
  z-index: 9;
}
.rank-flag span {
  font-family: var(--anton);
  font-size: 40px;
  letter-spacing: 2px;
  color: var(--pine);
  line-height: 1;
}

#frame.is-final .chip-rank { display: block; }
#frame.is-final .rank-flag { display: block; }
#frame.is-final .plate.winner .trophy { display: block; }

/* ==========================================================================
   ANIMATION
   Only the token and the celebration move. The layout never does.
   ========================================================================== */

.token { transition: bottom 900ms cubic-bezier(.22, 1, .36, 1); }

/* Suppress the rise transition when the board first paints or re-syncs, so a
   page refresh does not animate four tokens up from the basecamp. */
#frame.no-anim .token { transition: none; }

#frame.is-awarding .route.awarded .burst,
#frame.is-awarding .route.awarded .ring,
#frame.is-awarding .route.awarded .callout,
#frame.is-awarding .route.awarded .highlight,
#frame.is-awarding .plate.awarded .chip-award {
  animation: burst-in 300ms ease-out both;
}

@keyframes burst-in {
  from { opacity: 0; transform: var(--from-tf, scale(0.6)); }
  to   { opacity: 1; transform: var(--to-tf, scale(1)); }
}

/* Each celebration part has its own resting transform, so each needs its own
   from/to pair rather than a shared scale(). */
#frame.is-awarding .route.awarded .burst {
  --from-tf: translate(-50%, 50%) scale(0.6);
  --to-tf:   translate(-50%, 50%) scale(1);
}
#frame.is-awarding .route.awarded .ring {
  --from-tf: translate(-50%, 50%) scale(0.6);
  --to-tf:   translate(-50%, 50%) scale(1);
}
#frame.is-awarding .route.awarded .callout {
  --from-tf: rotate(-7deg) translateY(-56px) scale(0.6);
  --to-tf:   rotate(-7deg) translateY(-56px) scale(1);
}
#frame.is-awarding .route.awarded .highlight {
  --from-tf: translateX(-50%) scaleY(0.6);
  --to-tf:   translateX(-50%) scaleY(1);
  transform-origin: bottom center;
}
#frame.is-awarding .plate.awarded .chip-award {
  --from-tf: scale(0.6);
  --to-tf:   scale(1);
}

/* fade the whole celebration out over 400ms before returning to standings */
#frame.is-awarding.award-out .route.awarded .burst,
#frame.is-awarding.award-out .route.awarded .ring,
#frame.is-awarding.award-out .route.awarded .callout,
#frame.is-awarding.award-out .route.awarded .highlight,
#frame.is-awarding.award-out .plate.awarded .chip-award {
  animation: none;
  opacity: 0;
  transition: opacity 400ms ease;
}
#frame.is-awarding.award-out .route:not(.awarded) { opacity: 1; }
