/* ============================================================================
   eurocup.css — shared shell for the four EUROCUP modules.

     eurocup-flagreveal · eurocup-roar · eurocup-chant · eurocup-predict

   Loaded by every one of the eight pages, ahead of the per-module sheet.

   DAYLIGHT RULES
   An outdoor LED wall at 14:00 in September does not lose its highlights, it
   loses the bottom of the curve: blacks lift, fine detail disappears, smooth
   gradients turn to mud. Everything below follows from that:

     · full-luminance saturated blocks, nothing below ~15% luma
     · thick keylines so white AND black bands both hold an edge
     · hard stepped transitions, never a crossfade — a cut survives sun
     · nothing smaller than a fist at 60 m
     · no gradient, no blur, no box-shadow, no text-shadow, anywhere

   tests/eurocup-test.php asserts that last line: add a box-shadow to any
   eurocup sheet and the suite fails.

   THEMING
   Every custom property below is a FALLBACK. js/eurocup-theme.js overwrites
   them from json/{module}{game_id}.json — the same per-game file every other
   module themes from. Nothing here is a client colour.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------------- brand
     Every value here is a FALLBACK. js/eurocup-theme.js overwrites all of them
     from json/{module}{game_id}.json — the same per-game file every other
     module themes from — so nothing below is a client colour.

     The nine colour fields the back office offers map to nine ROLES, not to
     nine decorations. An operator who sets "Color 3" is setting the urgent
     state, and the panel label says so. */
  --ec-hot: #FFE94A;                    /* primary_color   — accent, counters, the call */
  --ec-dim: #7C8595;                    /* secondary_color — supporting text */
  --ec-warn: #FF4D3D;                   /* third_color     — the last seconds, urgency */
  --ec-text: #FFFFFF;                   /* fourth_color    — type on the field */
  --ec-rule: #FFFFFF;                   /* fifth_color     — keylines and meter frames */
  --ec-surface: #161B24;                /* sixth_color     — panels, option plates */

  --ec-field: #101319;                  /* background_color — charcoal, not black:
                                           keeps LED black-crush honest */
  --ec-field-2: #161B24;                /* background_secondary_color */
  --ec-field-night: #05070B;            /* background_third_color — the night wall */

  /* Ink is derived from the field, not themed separately: it is what type is
     knocked out of, and it has to stay darker than whatever is behind it. */
  --ec-ink: #0B0E14;
  --ec-on-hot: #000000;

  /* ------------------------------------------------------------- neutrals
     These are transparency, not colour. A white at 10% over a themed field is
     the right tint whatever that field is, which is exactly why they are NOT
     wired to brand slots — hardcoding a brand colour here would fight the
     theme instead of following it. */
  --ec-tint-1: #FFFFFF10;               /* empty track */
  --ec-tint-2: #FFFFFF1A;               /* unlit meter segment */
  --ec-tint-3: #FFFFFF26;               /* filled overlay bar */
  --ec-line: #FFFFFF1F;                 /* hairline rules */
  --ec-keyline: #FFFFFF33;              /* flag chip borders */
  --ec-shade: #00000014;                /* ink wash on a lit plate */

  --ec-font: "Arial Narrow", "Helvetica Neue Condensed", Impact, system-ui, sans-serif;
  --ec-font-2: var(--ec-font);
  --ec-mono: ui-monospace, Menlo, Consolas, monospace;

  /* Secondary copy scale — eyebrows, tags, the chant's "next line". Set from
     intro.secondary_font_size; the fallback keeps it just under body size. */
  --ec-font-size-2: 0.9rem;

  --ec-pad: 3.2vmin;
  --ec-bg-image: none;
  --ec-bg-darken: 0;
}

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

html,
body {
  height: 100%;
  background: var(--ec-field);
  color: var(--ec-text);
  font-family: var(--ec-font);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* Background image sits on its own layer so bg_darken can sit over it without
   a gradient — a flat ink plate at N% opacity, which survives sun. */
.ec-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-image: var(--ec-bg-image);
  background-size: cover;
  background-position: center;
}
.ec-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ec-ink);
  opacity: var(--ec-bg-darken);
}

.ec-hidden { display: none !important; }

/* ---------------------------------------------------------------- typography
   One condensed family, three weights of meaning: eyebrow (tracked, small),
   headline (heavy, tight), number (tabular). Nothing else. */

.ec-eyebrow {
  font-size: var(--ec-font-size-2, 1.1rem);
  letter-spacing: 0.26em;
  font-weight: 700;
  color: var(--ec-hot);
  text-transform: uppercase;
}

.ec-meta {
  font-size: var(--ec-font-size-2, 1.05rem);
  letter-spacing: 0.22em;
  font-weight: 700;
  color: var(--ec-dim);
  text-transform: uppercase;
}

.ec-num { font-variant-numeric: tabular-nums; font-weight: 900; }

/* ------------------------------------------------------------------- rails
   Tournament furniture, always on, identical across the four boards so an
   operator cutting between modules never sees the frame move. */

.ec-rail {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 8.4vmin;
  display: flex;
  align-items: center;
  gap: var(--ec-pad);
  padding: 0 var(--ec-pad);
  border-bottom: 0.5vmin solid var(--ec-line);
  background: var(--ec-field);
  z-index: 4;
}
.ec-rail .ec-mark {
  font-weight: 900;
  font-size: var(--ec-font-size-2, 3.6vmin);
  letter-spacing: 0.06em;
  line-height: 1;
  text-transform: uppercase;
}
.ec-rail .ec-sep { flex: 1; }
.ec-rail img { height: 5.4vmin; display: block; }
.ec-rail .ec-meta { font-size: var(--ec-font-size-2, 2.2vmin); }

/* --------------------------------------------------------------- meters
   A segmented bar, not a continuous fill: discrete lit blocks still read as
   a level once the sun has crushed the contrast between them. */

.ec-meter {
  display: flex;
  gap: 0.4vmin;
  padding: 0.5vmin;
  border: 0.5vmin solid var(--ec-rule);
  height: 3.6vmin;
}
.ec-meter i { flex: 1; background: var(--ec-tint-2); }
.ec-meter i.on { background: var(--ec-hot); }

/* --------------------------------------------------------------- buttons */

.ec-btn {
  font: inherit;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ec-text);
  background: var(--ec-surface);
  border: 0.2rem solid var(--ec-line);
  padding: 1rem 1.2rem;
  cursor: pointer;
}
.ec-btn:hover { background: var(--ec-field-2); }
.ec-btn--hot {
  background: var(--ec-hot);
  color: var(--ec-on-hot);
  border-color: var(--ec-hot);
}
.ec-btn[disabled] { background: var(--ec-field-2); color: var(--ec-dim); cursor: default; }

/* ------------------------------------------------------------- lockup
   Sponsor lockup, when the per-game JSON carries one. On its own line under
   the content, never over it and never over a face — the two placements a
   brand team rejects on sight. Clear space is half the mark height. */

.ec-lock {
  display: flex;
  align-items: center;
  gap: 1vmin;
  margin-top: 1.4vmin;
  padding-top: 1.2vmin;
  border-top: 0.18vmin solid var(--ec-line);
}
.ec-lock .by {
  font-size: 1.25vmin;
  letter-spacing: 0.24em;
  color: var(--ec-dim);
  font-weight: 700;
  text-transform: uppercase;
}
.ec-lock img { height: 2.6vmin; display: block; }

/* --------------------------------------------------------- leaderboards
   Shared by roar, chant and the settled prediction table. Solid blocks, hard
   edges, one accent on the leader. */

.ec-rows { display: flex; flex-direction: column; gap: 1.1vmin; }
.ec-row { display: flex; align-items: center; gap: 1.6vmin; height: 7.4vmin; }
.ec-row .pos {
  width: 5vmin;
  font-size: 3.4vmin;
  font-weight: 900;
  color: var(--ec-dim);
  text-align: right;
}
.ec-row canvas.flag,
.ec-row img.flag {
  width: 9vmin;
  height: 6vmin;
  flex: none;
  border: 0.4vmin solid var(--ec-keyline);
  display: block;
}
.ec-row .cd { width: 12vmin; font-size: 4.4vmin; font-weight: 900; letter-spacing: 0.06em; }
.ec-row .bar { flex: 1; height: 5.2vmin; background: var(--ec-tint-1); position: relative; }
.ec-row .bar i {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: var(--ec-hot);
  /* stepped, not smooth: a bar that slides is a bar that smears on LED */
  transition: width 0.4s steps(8);
}
.ec-row .tag {
  width: 20vmin;
  font-size: 1.9vmin;
  letter-spacing: 0.14em;
  color: var(--ec-dim);
  font-weight: 700;
}
.ec-row .val {
  width: 12vmin;
  text-align: right;
  font-size: 4vmin;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}
.ec-row.lead .bar i { background: var(--ec-rule); }
.ec-row.lead .val { color: var(--ec-hot); }

/* ------------------------------------------------------------ board shell
   Every jumbotron in the family shares this frame — rail on top, one column of
   content below — so an operator cutting between the four never sees the
   furniture move. */

.ec-board main {
  position: fixed;
  inset: 8.4vmin var(--ec-pad) var(--ec-pad);
  display: flex;
  flex-direction: column;
}

.ec-board h1 {
  font-size: var(--ec-font-size, 8vmin);
  font-weight: 900;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  line-height: 0.9;
  margin: 2vmin 0 1vmin;
}

.ec-board .ec-sub {
  font-size: var(--ec-font-size-2, 2.4vmin);
  letter-spacing: 0.26em;
  color: var(--ec-hot);
  font-weight: 700;
  margin-bottom: 2vmin;
  text-transform: uppercase;
}

.ec-empty {
  font-size: var(--ec-font-size-2, 2.2vmin);
  letter-spacing: 0.22em;
  color: var(--ec-dim);
  font-weight: 700;
  text-transform: uppercase;
}

/* ------------------------------------------------------------ fan shell
   The phone pages. Same tokens, sized in px rather than vmin: a phone is
   held at 30 cm and a wall is read at 60 m, and one scale cannot serve both. */

body.ec-fan {
  display: flex;
  flex-direction: column;
  overscroll-behavior: none;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}

/* The three bands of your flag frame the whole app — set by JS from the
   nation the fan picked, so the phone wears their colours all weekend. */
.ec-bands {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 6px;
  display: flex;
  z-index: 5;
}
.ec-bands i { flex: 1; background: var(--ec-dim); }
.ec-bands i:nth-child(1) { background: var(--ec-n1, var(--ec-dim)); }
.ec-bands i:nth-child(2) { background: var(--ec-n2, var(--ec-text)); }
.ec-bands i:nth-child(3) { background: var(--ec-n3, var(--ec-dim)); }
.ec-bands--bottom { top: auto; bottom: 0; }

.ec-fan header {
  padding: 22px 20px 10px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.ec-fan header canvas {
  width: 44px;
  height: 29px;
  border: 1px solid var(--ec-keyline);
  flex: none;
}
.ec-fan header .who {
  font-weight: 900;
  font-size: 22px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1;
}
.ec-fan header .who small {
  display: block;
  font-size: 11px;
  letter-spacing: 0.24em;
  color: var(--ec-dim);
  font-weight: 700;
  margin-top: 4px;
}
.ec-fan header .swap {
  margin-left: auto;
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--ec-dim);
  border: 1px solid var(--ec-line);
  padding: 8px 10px;
  background: none;
  cursor: pointer;
}

.ec-fan main { flex: 1; overflow: auto; padding: 8px 20px 28px; }

.ec-card {
  border: 1px solid var(--ec-line);
  padding: 20px;
  margin-bottom: 14px;
}
.ec-card .ec-eyebrow { font-size: var(--ec-font-size-2, 11px); margin-bottom: 10px; }
.ec-card h2 {
  font-size: var(--ec-font-size, 30px);
  font-weight: 900;
  letter-spacing: -0.01em;
  line-height: 0.95;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.ec-note { color: var(--ec-dim); font-size: var(--ec-font-size-2, 14px); line-height: 1.45; }

.ec-fan .ec-meter { height: 14px; border-width: 1px; gap: 2px; padding: 2px; margin: 14px 0; }

.ec-go {
  width: 100%;
  padding: 20px;
  background: var(--ec-hot);
  color: var(--ec-on-hot);
  border: 0;
  font: inherit;
  font-weight: 900;
  font-size: 20px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.ec-go[disabled] { background: var(--ec-field-2); color: var(--ec-dim); }
.ec-go--ghost { background: none; border: 1px solid var(--ec-line); color: var(--ec-text); }

.ec-huge { font-size: 64px; font-weight: 900; line-height: 0.9; font-variant-numeric: tabular-nums; }

.ec-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 10px 0;
  border-bottom: 1px solid var(--ec-line);
  font-size: 15px;
}
.ec-line b { font-weight: 900; letter-spacing: 0.1em; }
.ec-line .sc { font-variant-numeric: tabular-nums; color: var(--ec-hot); font-weight: 900; }

.ec-clock {
  font-size: 13px;
  letter-spacing: 0.2em;
  color: var(--ec-dim);
  font-weight: 700;
  text-transform: uppercase;
}

/* One beat of feedback on a tap, and only where motion is welcome. */
@media (prefers-reduced-motion: no-preference) {
  .ec-pulse { animation: ec-pulse 0.5s ease; }
}
@keyframes ec-pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.04); }
  100% { transform: scale(1); }
}

/* ------------------------------------------------------------------ join
   The QR that gets a phone into this game, plus the operator's one-line
   notice. Bottom-right on every board, at a size that scans at arm's length
   from the front of the crowd — the code is the only thing on this wall a
   camera has to resolve, so it stays full black on full white and is never
   themed. */

.ec-join {
  position: fixed;
  right: var(--ec-pad);
  top: 10vmin;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8vmin;
}
.ec-join-qr {
  width: 14vmin;
  height: 14vmin;
  /* Pure white, never themed: this is the one thing on the wall a phone
     camera has to resolve, and a tinted quiet zone is a code that will not
     scan. Same reason the code itself is drawn full black. */
  background: #FFFFFF;
  padding: 0.8vmin;
  line-height: 0;
}
.ec-join-qr img,
.ec-join-qr canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
}
.ec-join-copy {
  max-width: 18vmin;
  text-align: center;
  font-size: var(--ec-font-size-2, 1.6vmin);
  letter-spacing: 0.16em;
  font-weight: 700;
  color: var(--ec-dim);
  text-transform: uppercase;
  line-height: 1.3;
}

/* Boards that put their own furniture top-right move it out of the way rather
   than letting the two overlap. */
.ec-board .ec-roar-clock,
.ec-board .ec-count { right: calc(var(--ec-pad) + 17vmin); }

/* -------------------------------------------------------------- fan brand
   The mobile mark (intro.form_logo). Above the flag header, so the club is the
   first thing on the page and the fan's own nation the second. */

.ec-brandbar {
  display: flex;
  justify-content: center;
  padding: 14px 20px 0;
}
.ec-brandbar img {
  max-height: 44px;
  max-width: 60%;
  display: block;
}
.ec-brandbar img[hidden] { display: none; }

/* ------------------------------------------------------------------ rules
   Operator-written "how it works", HTML allowed. Sized as body copy, not as a
   headline: it is read once, at the QR, and never again. */

.ec-rules {
  color: var(--ec-dim);
  font-size: var(--ec-font-size-2, 14px);
  line-height: 1.5;
}
.ec-rules :is(h1, h2, h3) {
  color: var(--ec-text);
  font-size: 18px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.ec-rules p { margin-bottom: 10px; }
.ec-rules p:last-child { margin-bottom: 0; }
.ec-rules ul, .ec-rules ol { margin: 0 0 10px 18px; }
.ec-rules a { color: var(--ec-hot); }
