/* The 1:2 portrait board + four-face LED totem (vertical.html). */
/* ── 1:2 vertical scoreboard (vertical.html) ──────────────
 * Face-off layout: each team owns half the screen with a giant game-point
 * numeral; set scores sit in the centre spine. Locked to a 1080×2160 canvas
 * (1:2, matching the venue LED's 480×960 pixel spec at exactly half scale),
 * scaled and letterboxed to fit (same convention as the 16:9 viewer).
 * --vport-rot (set from ?rot=cw|ccw) turns the whole board 90° for LED
 * processors that take the portrait panel's signal as 960×480 landscape. */
.vport {
  position: fixed; top: 50%; left: 50%;
  width: 1080px; height: 2160px;
  transform: translate(-50%, -50%) rotate(var(--vport-rot, 0deg)) scale(var(--vport-scale, 1));
  overflow: hidden;
  display: flex; flex-direction: column;
  background: #000;
}
html.vport-fx .vport { background: transparent; z-index: 1; }

.vport-half {
  flex: 1; position: relative;
  display: flex; flex-direction: column;
  align-items: center; justify-content: space-between;
  text-align: center;
  padding: 44px 60px;
  min-height: 0;
}
.vport-half.half-1 { background: linear-gradient(180deg, rgba(255,255,255,0.05), transparent 45%); }
.vport-half.half-2 { background: linear-gradient(0deg,   rgba(255,255,255,0.05), transparent 45%); }
.vport-half.half-1.serving, .vport-half.half-1.win {
  background: linear-gradient(180deg, rgba(152,27,50,0.45), transparent 45%);
}
.vport-half.half-2.serving, .vport-half.half-2.win {
  background: linear-gradient(0deg,   rgba(152,27,50,0.45), transparent 45%);
}
/* Balance the gaps around the spine: the numeral font carries its dead
 * leading above the digits, so the bottom half loses its top padding and
 * pulls its numeral up to visually match the top half's gap. */
.vport-half.half-2 { padding-top: 0; }
.vport-half.half-2 .vport-pt { margin-top: -24px; }
/* Match board: retuned for Bebas digit metrics (82px dead below the ink,
 * 39px above at 430px) so both numerals sit ~60px of INK gap off the spine. */
.vmatch .vport-half.half-1 { padding-bottom: 0; }
.vmatch .vport-half.half-1 .vport-pt { margin-bottom: -22px; }
.vmatch .vport-half.half-2 .vport-pt { margin-top: 22px; }

/* Legibility bump after testing on the physical totem — both vertical boards. */
.vport-brand img { height: 220px; width: auto; object-fit: contain; }

.vport-team {
  width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 26px;
  font-family: var(--head); font-weight: 700;
  font-size: 104px; line-height: 1;
  white-space: nowrap;
  letter-spacing: 0.01em; text-transform: uppercase; color: var(--white);
}
.vport-team .serve-ball { width: var(--serve-dot-vert); height: var(--serve-dot-vert); }
.vport-half.serving .serve-ball { visibility: visible; }

.vport-pt {
  /* Bebas (brand sans display), not Norman — hairline serifs break up on
     the totem's coarse pixel pitch. */
  font-family: 'Bebas Neue', 'Arial Narrow', sans-serif;
  font-size: 430px; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--white);
}
.vport-half.serving .vport-pt { text-shadow: 0 0 140px rgba(152, 27, 50, 0.85); }
.vport-pt.gp { color: var(--red-bright); }

.vport-spine {
  display: flex; align-items: flex-end; justify-content: center; gap: 90px;
  padding: 30px 40px;
  background: rgba(0, 0, 0, 0.92);
}
.spine-chip { text-align: center; }
.spine-chip .lab {
  font-family: var(--body); font-size: 26px; font-weight: 600;
  letter-spacing: 0.32em; text-transform: uppercase; color: var(--stone);
}
.spine-chip .val {
  margin-top: 4px;
  font-family: 'Bebas Neue', 'Arial Narrow', sans-serif; font-weight: 400;
  font-size: 170px; line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--white);
}
/* Step chip size down as sets accumulate so the row always fits 1080px,
 * even on the fallback (non-condensed) fonts. */
.vport-spine[data-chips="4"] { gap: 36px; }
.vport-spine[data-chips="4"] .spine-chip .val { font-size: 112px; }
.vport-spine[data-chips="5"], .vport-spine[data-chips="6"] { gap: 28px; }
.vport-spine[data-chips="5"] .spine-chip .val,
.vport-spine[data-chips="6"] .spine-chip .val { font-size: 92px; }
.spine-chip .val .l    { color: var(--stone); }
.spine-chip .val .dash { color: var(--stone); padding: 0 0.05em; }
.spine-chip .val sup {
  font-family: var(--body); font-size: 0.32em;
  vertical-align: super; opacity: 0.75;
}
/* Match clock chip (state.showClock) — sits beside the set chips, or beside
   the format line on tiebreak-only boards. Same chip language, digits a step
   smaller than set scores so the score stays the hero. */
.spine-clock { align-self: center; }
.spine-clock .val {
  font-size: 120px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
}
.spine-status {
  align-self: center;
  font-family: var(--head); font-weight: 700; font-size: 44px;
  line-height: 1.4;
  letter-spacing: 0.3em; text-transform: uppercase; color: var(--red);
  text-align: center;
  padding: 40px 0;
}

/* 50px with tighter tracking after the totem test (was 30px/0.24em); full
 * width + nowrap so each board's JS can shrink-to-fit long lines. */
.vport-footer {
  font-family: var(--body); font-weight: 600;
  font-size: 50px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
  width: 100%; white-space: nowrap;
}
.vport-footer .server { color: var(--white); }

/* Idle holding screen (both vertical boards): full-canvas event logo while
 * no match is live. Covers the board; each board's JS toggles .idle. */
.vport-idle {
  position: absolute; inset: 0; z-index: 6;
  display: none;
  background: #000;
  overflow: hidden;
}
.vport.idle .vport-idle { display: block; }

/* The idle logo band (?spin/?logo, js/idle-spin.js), drifting right to left.
 * It is ONE band wrapped around the whole pillar, not a per-face loop: each
 * face slides it a further canvas width (--face-index, set by led-wall.js) so
 * face 2 carries on exactly where face 1 ends. That is what lets two logos
 * share the entire column — a logo crossing a seam is drawn by both faces at
 * the same place, so it walks across the join in one piece.
 * Everything is in canvas px (the board is a fixed 1080-wide canvas that
 * scales as a whole), so a cell is an exact division of the pillar and the
 * pattern still lines up where face 4 meets face 1. --idle-shift stays inside
 * one cell: at a full cell the band has landed exactly where it started, so
 * the wrap back to 0 is invisible. At 0 (spin off) the cells sit where they
 * were marked up and this is the plain logo. */
.idle-band {
  position: absolute; top: 0; left: 0;
  width: calc((var(--idle-cells, 1) + 1) * var(--idle-cell-w, 1080px));
  height: 100%;
  display: flex;
  transform: translate3d(
    calc((var(--idle-shift, 0) + var(--face-index, 0) * 1080) * -1px), 0, 0);
}
.idle-cell {
  width: var(--idle-cell-w, 1080px); height: 100%;
  display: flex; align-items: center; justify-content: center;
}
.idle-cell img { width: var(--idle-logo-w, 778px); height: auto; }

/* Critical moment card takes over the centre band (sits on the spine). */
.vport .critical-card {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  margin: 0; max-width: none; white-space: nowrap;
  font-size: 36px; padding: 22px 56px;
  z-index: 5;
}

/* ── Four-face LED totem playback (?led=4, led-wall.js) ────
 * The venue LED is a four-sided column fed by one 960×480 signal: the
 * processor slices it into four 240×480 columns, one per face. Each face
 * shows the whole board — 240×480 is the same 1:2 ratio as the 1080×2160
 * design canvas, so the board scales onto every side pixel for pixel. */
.ledwall {
  position: fixed; top: 50%; left: 50%;
  width: 960px; height: 480px;
  /* Non-uniform: fills the window so no letterbox bars reach the totem;
     the processor's own scale to its 960×480 raster undoes the stretch.
     led-wall.js sets both factors (equal when ?fit=contain). */
  transform: translate(-50%, -50%) scale(var(--ledwall-sx, 1), var(--ledwall-sy, 1));
  display: flex;
  background: #000;
}
html.vport-fx .ledwall { background: transparent; z-index: 1; }
.led-face { position: relative; width: 240px; height: 480px; overflow: hidden; }
html.ledmode .vport {
  position: absolute; top: 0; left: 0;
  transform: scale(calc(240 / 1080));
  transform-origin: 0 0;
}


/* ── Point tick (V2 motion) ─────────────────────────────────
 * vertical.js pulses .tick when a giant point value changes. */
.vport-pt.tick { animation: vport-tick var(--motion-fast) cubic-bezier(0.2, 0.9, 0.3, 1.2); }
@keyframes vport-tick {
  0%   { transform: translateY(0); }
  40%  { transform: translateY(-0.14em); opacity: 0.4; }
  100% { transform: translateY(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .vport-pt.tick { animation: none; } }
