/* ══════════════════════════════════════════════════════════════════════
   THE COUTA BOWL — Queenscliff
   White ink only, cut with a single fine rule. Same hand as the Fortuna
   Villa titles — Cormorant Garamond over letterspaced Jost — but no gold,
   because this is a football ground, not a property.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  --ink:      #f7f6f2;
  --ink-dim:  rgba(247,246,242,.68);
  --ink-rule: rgba(247,246,242,.45);
  --shadow:   0 1px 3px rgba(0,0,0,.85), 0 2px 22px rgba(0,0,0,.45);
  --serif: 'Cormorant Garamond', 'Times New Roman', serif;
  --sans:  'Jost', 'Segoe UI', sans-serif;

  /* ── the world type's own hand ──────────────────────────────────────
     Anton for the hits, Barlow Condensed for anything carrying data —
     the faces the Queenscliff build was designed in, kept so a cut
     authored there opens here looking like itself. The editor offers
     the serif and the sans above as well, so this piece's own
     typography is one dropdown away.
     ────────────────────────────────────────────────────────────────── */
  --display: 'Anton', 'Arial Narrow', sans-serif;
  --deck:    'Barlow Condensed', 'Arial Narrow', sans-serif;

  /* Flat type on grass needs a hard edge and a wide soft shadow under
     it, or it dissolves into the mowing bands. */
  --turf-shadow:
     0 0.03em 0.06em rgba(0,0,0,.95),
     0 0.08em 0.30em rgba(0,0,0,.75),
     0 0.20em 0.90em rgba(0,0,0,.55);
  --sky-shadow:
     0 0.02em 0.05em rgba(0,0,0,.9),
     0 0.10em 0.45em rgba(0,0,0,.6);
}

/* the engine's own chrome (timeline, buttons, branding) has no place here */
#ui { display: none !important; }

/* ── THE HOLD ─────────────────────────────────────────────────────────
   The rule above removes the engine's loading UI; this is what stands in
   its place, and it is the only one on the page. It covers the boot,
   carries the engine's real byte progress on a single hairline, and is
   taken off the picture — and out of the document — on the first sorted
   frame. Above everything of ours: #ct-stage is 20, #cb-title 30,
   #cb-track 50, #pv-hud 400. Deliberately BELOW the settings-failure
   banner (100001), which must stay legible through the curtain.
   ─────────────────────────────────────────────────────────────────── */
#cb-hold {
  position: fixed; inset: 0; z-index: 1000;
  background: #0b0e11;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  color: var(--ink);
  transition: opacity .55s ease;
}
#cb-hold.gone { opacity: 0; pointer-events: none; }
/* Anton, in white — the same face the titles on the field are set in, so
   the wait belongs to the piece instead of announcing a different one.
   The name went: it is the first thing the promo itself says a moment
   later, and saying it twice made the curtain look like the title card. */
#cb-hold-mark {
  font: 400 clamp(26px, 6.4vw, 48px)/1 'Anton', var(--sans), sans-serif;
  letter-spacing: .30em; text-indent: .30em;      /* tracking, re-centred */
  color: #fff; text-align: center;
}
/* A hairline was right under a light serif; under Anton it looked like a
   thread beside a brick. Four pixels carries the same weight as the type,
   and the whole group — word, bar, number — now reads as one object. */
/* ONE MEASURE. The rule used to be a 300px dash sitting over instruction
   blocks that spanned the better part of a thousand — two layouts on one
   screen, neither agreeing with the other. It now runs the same width as
   the pair below it, so the blocks land exactly on its two ends and the
   whole thing hangs off a single line. That is what makes it read as
   composed rather than as three things that happen to be stacked. */
#cb-hold-rail {
  margin-top: 32px;
  width: min(980px, 88vw); height: 4px;
  background: rgba(255,255,255,.18);
}
#cb-hold-bar {
  width: 0%; height: 100%;
  background: #fff;                                /* the same white as the word */
  transition: width .25s linear;
}
/* Flush to the end of the rule, not centred under it. A small centred
   number beneath a full-width line has nothing to hold on to and reads as
   an orphan; sitting on the right end it terminates the rule the bar is
   filling, and it is the only element on the screen that changes, so it
   earns a position of its own rather than a place in the middle. */
#cb-hold-pc {
  width: min(980px, 88vw);
  margin-top: 14px;
  font: 400 clamp(13px, 1.9vw, 16px)/1 'Anton', var(--sans), sans-serif;
  letter-spacing: .28em;
  color: rgba(255,255,255,.72);
  text-align: right;
}

/* ── THE INSTRUCTIONS ──────────────────────────────────────────
   Display size, broken two words to the line, and thrown to the two outer
   edges — the split-title layout, which is what big type has been doing
   for a while now and what makes a waiting screen look composed rather
   than patient.

   TRACKING IS THE WHOLE TRICK. The word LOADING above is letter-spaced
   wide because it is one word doing one job. These are four words each
   and they have to stack into a BLOCK: set them at the same open tracking
   and each line becomes a long thin ribbon, the two lines of a pair never
   line up, and there is nothing square about it. Pulled almost to zero
   they build a solid mass with a flush left edge, the two lines nearly
   the same length, and the pair reads as one object. Tight leading (.98)
   does the same job vertically — the two lines have to touch to be a
   block. Wide-tracked label over tight-set display is a deliberate pair,
   not an inconsistency.

   THE COLOUR CARRIES THE GRAMMAR, so the break can fall anywhere:
     blue   the gesture      — the thing the hand does
     white  the connective   — structure, deliberately quiet
     yellow the result       — what the gesture gets you
   Both are read straight off the titles on the field, so the curtain is
   already speaking in the promo's colours before the promo starts. */
/* SIDE BY SIDE WHILE THERE IS ROOM, STACKED WHEN THERE IS NOT. The pair
   needs 278px and a 320px phone gives the box 282 — three pixels of margin,
   which is not a layout, it is a coincidence. And the blocks are nowrap, so
   losing that race does not wrap them, it pushes the PAGE sideways and
   drags every fixed layer with it. flex-wrap turns the failure into a
   stack: the first block keeps the left edge, the second is carried to the
   right by an auto margin, the shape still reads, and nothing overflows. */
#cb-hold-tips {
  margin-top: 54px;
  width: min(980px, 88vw);
  display: flex; flex-wrap: wrap;
  justify-content: space-between; align-items: flex-start;
  column-gap: 22px; row-gap: 20px;
}
.cb-tip.cb-right { margin-left: auto; }
.cb-tip {
  display: flex; flex-direction: column;
  font: 400 clamp(26px, 6.4vw, 48px)/.98 'Anton', var(--sans), sans-serif;
  letter-spacing: .015em;
  text-align: left;
}
.cb-tip.cb-right { text-align: right; }
.cb-tip span { display: block; white-space: nowrap; }
.cb-tip i { font-style: normal; }
.cb-b { color: #2997ff; }      /* the titles' blue  */
.cb-w { color: #ffffff; }
.cb-y { color: #ffb81c; }      /* the titles' gold  */

/* ── THE BROWSER DOES NOT GET THE GESTURES ───────────────────────────
   This used to live in the stylesheet promo-hud.js INJECTS, which does not
   exist until the viewer has booted — so for the whole of the loading
   screen the page was defenceless. A pinch there and iOS zooms the page
   itself, and Safari REMEMBERS that zoom for the site: every visit
   afterwards opens zoomed, the fixed layers render at layout size inside a
   smaller visual viewport, and the type lands nowhere near the ground it
   is pinned to. It reads as a 3-D alignment bug and is nothing of the
   kind. In a stylesheet it is live on the first paint instead.
   ──────────────────────────────────────────────────────────────── */
/* ── THE BEGIN BUTTON ────────────────────────────────────────────
   Over the held first frame, not over a black screen — the picture is
   already the sell, and this is only the way in. Wireframe rather than a
   solid disc so the scan reads straight through it, and the line beneath
   is in the curtain's own three colours so the two screens are plainly
   the same piece of design. Sits under the settings-failure banner and
   over everything else of ours. */
#cb-begin {
  position: fixed; inset: 0; z-index: 900;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 26px;
  opacity: 0; pointer-events: none;
  transition: opacity .5s ease;
}
#cb-begin.show { opacity: 1; pointer-events: auto; }
#cb-begin-btn {
  appearance: none; -webkit-appearance: none;
  background: none; border: 0; padding: 0; cursor: pointer;
  width: clamp(76px, 19vw, 108px); height: clamp(76px, 19vw, 108px);
  filter: drop-shadow(0 2px 14px rgba(0,0,0,.6));
  transition: transform .18s ease;
}
#cb-begin-btn:active { transform: scale(.94); }
#cb-begin-btn svg { width: 100%; height: 100%; display: block; }
#cb-begin-btn circle { fill: rgba(0,0,0,.22); stroke: #fff; stroke-width: 3.5; }
#cb-begin-btn path { fill: #fff; }
#cb-begin-say {
  font: 400 clamp(15px, 3.6vw, 20px)/1 "Anton", var(--sans), sans-serif;
  letter-spacing: .28em; text-indent: .28em;
  text-shadow: 0 1px 10px rgba(0,0,0,.75);
}
#cb-begin-say i { font-style: normal; }

html, body {
  touch-action: none;
  overscroll-behavior: none;
  overflow-x: hidden;              /* nothing may push the page sideways */
  max-width: 100%;
}
#application-canvas { cursor: grab; }
#application-canvas:active { cursor: grabbing; }

/* ── the name ─────────────────────────────────────────────────────────
   Anchored in 3-D above the ground at the start and the end, and pinned as
   a flat heading across the top in between — couta.js drives the whole
   move, position, size and opacity together, from the flight clock.

   font-size is set here so the glass beneath can be sized in `em` and
   therefore scale with the type as it travels.
   ─────────────────────────────────────────────────────────────────── */
#cb-title {
  position: fixed; left: 0; top: 0;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
  z-index: 30;
  color: var(--ink);
  text-shadow: var(--shadow);
  font-size: var(--cb-title-size, 44px);
  will-change: transform, opacity;
}

/* ── the glass under the name ─────────────────────────────────────────
   White type over a sunlit scan was getting lost — losing it against the
   beach and the roofs. This is a pane of tinted glass rather than a box:
   it darkens and slightly blurs what is behind the words, and BOTH the
   tint and the blur are faded out by the mask, so there is no edge
   anywhere. A hard-edged panel would read as a caption bar and wreck the
   thing entirely.

   Sized in `em`, so it grows and shrinks with the type on the way up to
   the top of the frame and back.
   ─────────────────────────────────────────────────────────────────── */
#cb-title .cb-glass {
  position: absolute; left: 50%; top: 50%;
  width: calc(100% + 3.2em); height: calc(100% + 1.6em);
  transform: translate(-50%, -50%);
  z-index: -1; pointer-events: none;
  background: radial-gradient(ellipse at center,
    rgba(4,9,14,.50) 0%, rgba(4,9,14,.42) 40%,
    rgba(4,9,14,.20) 66%, rgba(4,9,14,0) 84%);
  backdrop-filter: blur(3px) saturate(.90) brightness(.80);
  -webkit-backdrop-filter: blur(3px) saturate(.90) brightness(.80);
  -webkit-mask-image: radial-gradient(ellipse at center,
    #000 0%, #000 48%, rgba(0,0,0,.55) 68%, transparent 84%);
  mask-image: radial-gradient(ellipse at center,
    #000 0%, #000 48%, rgba(0,0,0,.55) 68%, transparent 84%);
}
#cb-title .cb-t1 {
  display: block;
  font: 500 var(--cb-title-size, 44px)/1.05 var(--serif);
  letter-spacing: .34em;
  margin-right: -.34em;            /* optically recentre the tracking */
}
#cb-title .cb-t2 {
  display: block;
  /* .60 of the hero, not .30 — the place name now carries real weight
     rather than sitting under it as a caption */
  font: 300 calc(var(--cb-title-size, 44px) * .60)/1.3 var(--sans);
  letter-spacing: .40em;
  margin-right: -.40em;
  color: var(--ink-dim);
  margin-top: .30em;
}
#cb-title .cb-rule {
  width: 42%; height: 1px; margin: .55em auto 0;
  background: linear-gradient(90deg, transparent, var(--ink-rule), transparent);
}

/* ── a quiet hint, gone at the first touch ─────────────────────────── */
#cb-hint {
  position: fixed; left: 50%; bottom: 12vh; transform: translateX(-50%);
  z-index: 40;
  font: 300 22px/1 var(--sans); letter-spacing: .34em; text-indent: .34em;
  color: var(--ink-dim); text-shadow: var(--shadow);
  pointer-events: none; white-space: nowrap;
  opacity: 1; transition: opacity 1.6s ease;
}
#cb-hint.bye { opacity: 0; }

/* ── the engine's navigation cursor ─────────────────────────────────
   Belt and braces: couta.js calls navCursor.destroy(), which removes this
   outright. If a future engine build drops that method, the class gets
   added instead — and !important is required, because the engine writes
   `display` inline whenever it wants to show a ring.
   ─────────────────────────────────────────────────────────────────── */
.cb-killed { display: none !important; }

/* ── the transport ────────────────────────────────────────────────────
   A white line that fills as the flight runs, and a dot showing where it
   has got to. Nothing else — familiar enough to read instantly because
   every player has one, but with no numerals sitting on the picture.

   The times only exist while a hand is on it: the reading rides above the
   dot, and the two ends of the run sit under either end of the line so you
   can see how far there is to drag in each direction.
   ─────────────────────────────────────────────────────────────────── */
#cb-bar {
  position: fixed; left: 50%; bottom: 4.6vh; transform: translateX(-50%);
  z-index: 50;
  width: min(560px, 74vw);
  color: var(--ink); text-shadow: var(--shadow);
  font: 300 12px/1 var(--sans); letter-spacing: .18em;
  user-select: none; -webkit-user-select: none;
}

#cb-track {
  position: relative; height: 40px; cursor: pointer;
  touch-action: none;              /* we own the gesture, not the browser */
}
#cb-track:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

#cb-rail, #cb-fill {
  position: absolute; top: 50%; left: 0; height: 2px; margin-top: -1px;
  border-radius: 2px; pointer-events: none;
}
#cb-rail { width: 100%; background: rgba(247,246,242,.30); }
#cb-fill { width: 0; background: var(--ink); }

#cb-knob {
  position: absolute; top: 50%; left: 0;
  width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px;
  border-radius: 50%; background: var(--ink);
  box-shadow: 0 1px 5px rgba(0,0,0,.55);
  transition: transform .18s ease; pointer-events: none;
}
#cb-track:hover #cb-knob { transform: scale(1.25); }
#cb-bar.scrubbing #cb-knob { transform: scale(1.5); }

/* the numerals: absent until a hand is on the line */
#cb-now, #cb-t0, #cb-tend {
  position: absolute; pointer-events: none; white-space: nowrap;
  opacity: 0; transition: opacity .28s ease;
}
#cb-bar.live #cb-now, #cb-bar.live #cb-t0, #cb-bar.live #cb-tend { opacity: 1; }

#cb-now {
  left: 0; bottom: calc(50% + 13px); transform: translateX(-50%);
  font-size: 13px; letter-spacing: .12em;
}
#cb-t0, #cb-tend {
  top: calc(50% + 12px); font-size: 11px; color: var(--ink-dim);
}
#cb-t0 { left: 0; }
#cb-tend { right: 0; }

/* ── full screen ──────────────────────────────────────────────────── */
/* top right, not bottom right: at 84vw the transport reaches almost the
   full width of a phone and a bottom-corner button lands on top of it */
#cb-fs {
  position: fixed; right: 3.2vw; top: 3.2vh;
  z-index: 50; width: 38px; height: 38px; padding: 0;
  background: rgba(12,14,16,.38);
  border: 1px solid rgba(247,246,242,.22); border-radius: 9px;
  cursor: pointer; opacity: .72;
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  transition: opacity .25s ease, background .25s ease, border-color .25s ease;
}
#cb-fs:hover { opacity: 1; background: rgba(12,14,16,.6); border-color: rgba(247,246,242,.44); }
#cb-fs:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
/* four corner brackets, drawn with two gradients so there is no icon file */
#cb-fs::before, #cb-fs::after {
  content: ''; position: absolute; width: 13px; height: 13px;
  border: 2px solid var(--ink);
}
#cb-fs::before { top: 9px; left: 9px; border-right: 0; border-bottom: 0; }
#cb-fs::after  { right: 9px; bottom: 9px; border-left: 0; border-top: 0; }
#cb-fs.on::before { top: 9px; left: 9px; border: 2px solid var(--ink);
                    border-left: 0; border-top: 0; }
#cb-fs.on::after  { right: 9px; bottom: 9px; border: 2px solid var(--ink);
                    border-right: 0; border-bottom: 0; }

/* ══════════════════════════════════════════════════════════════════════
   THE WORLD TYPE
   Every piece of type lives on the stage below. The container carries the
   perspective — rewritten every frame by couta.js from the same focal
   length the matrices use — and each child gets a full matrix3d, so type
   really foreshortens into the ground plane rather than being drawn flat
   over it.

   The pixel sizes here are for MEASUREMENT only: the world transform
   rescales everything by `w`, the item's width in scene units. Keep them
   large or the glyphs go soft when they are scaled up.
   ══════════════════════════════════════════════════════════════════════ */
#ct-stage {
  position: fixed; inset: 0;
  z-index: 20;                       /* over the scan, under the name    */
  pointer-events: none;
  transform-style: preserve-3d;
  perspective-origin: 50% 50%;
  overflow: hidden;
}
.ct-w {
  position: absolute; left: 0; top: 0;
  transform-origin: 0 0;
  white-space: nowrap;
  will-change: transform, opacity;
  /* The quad is turned round in JS when the camera goes behind a standing
     title, so what is presented is always its front — this must not also
     be culled by the browser, or the two mechanisms fight and the sign
     blinks out at the crossover. */
  backface-visibility: visible;
}

/* ── painted on the turf ──────────────────────────────────────────── */
.ct-hit {
  font: 400 200px/0.86 var(--display);
  letter-spacing: -0.005em;
  color: #ffffff;
  text-shadow: var(--turf-shadow);
  text-transform: uppercase;
}
.ct-hit .l2 { display: block; }

.ct-deck {
  font: 600 110px/1.05 var(--deck);
  letter-spacing: 0.14em;
  color: #ffffff;
  text-shadow: var(--turf-shadow);
  text-transform: uppercase;
}

/* the same hand as the pinned name, for anything that wants to belong to
   this piece rather than to a football promo */
.ct-serif {
  font: 500 180px/1.05 var(--serif);
  letter-spacing: 0.30em;
  color: var(--ink);
  text-shadow: var(--turf-shadow);
  text-transform: uppercase;
}

/* a plain rule, for hanging a page off */
.ct-seam {
  width: 1500px; height: 9px;
  background: rgba(255,255,255,.9);
  box-shadow: 0 2px 18px rgba(0,0,0,.7);
}

/* ── boards standing round the boundary ──────────────────────────────
   Solid panels with a coloured cap rail, so they read as the perimeter
   hoardings at a real ground rather than as floating text. Standing type
   fades out as it turns away, so a board seen from behind — which reads
   as its own mirror image — is simply not there. Set `twoSided` on
   anything meant to be read from both sides.
   ─────────────────────────────────────────────────────────────────── */
.ct-board {
  font: 400 130px/0.94 var(--display);
  text-transform: uppercase;
  color: #ffffff;
  background: rgba(8,10,12,.86);
  border-top: 9px solid #ffffff;
  padding: 0.26em 0.42em 0.30em;
  text-shadow: none;
  box-shadow: 0 18px 60px rgba(0,0,0,.55);
}
.ct-board .l2 { display: block; }
.ct-board.data {
  font: 600 92px/1.15 var(--deck);
  letter-spacing: 0.14em;
  color: #f2f4f3;
}

/* a plate out on the grass — a name with a line under it */
.ct-name {
  font: 400 120px/0.95 var(--display);
  color: #ffffff;
  text-transform: uppercase;
  text-shadow: var(--sky-shadow);
}
.ct-name em {
  display: block;
  font: 600 44px/1.3 var(--deck);
  font-style: normal;
  letter-spacing: 0.22em;
  color: var(--ink-dim);
}

/* a picture brought in through the editor. `display: block` because an
   inline image is sat on a text baseline and carries a few pixels of
   phantom descender, which the measure then bakes into the world height. */
.ct-img img, .ct-w img { display: block; max-width: 1600px; height: auto; }
.ct-broken { outline: 2px dashed rgba(255,90,90,.7); }

/* calibration marks for fitting the oval (?calib) */
.ct-dot {
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border-radius: 50%;
  background: #ff2d55;
  box-shadow: 0 0 0 3px rgba(0,0,0,.6);
}
.ct-dot.axis { background: #00e5ff; }

/* ── edit mode ────────────────────────────────────────────────────────
   The presentation's own furniture has no business being on screen while
   type is being placed — the pinned name sits exactly where a headline
   wants to go, and the transport is a 74vw target across the bottom of
   the frame that swallows every drag meant for the grass.
   ─────────────────────────────────────────────────────────────────── */
body.cb-edit #cb-title,
body.cb-edit #cb-hint,
body.cb-edit #cb-bar,
body.cb-edit #cb-fs { display: none !important; }
body.cb-edit #application-canvas { cursor: default; }

/* ── small screens ─────────────────────────────────────────────────── */
@media (max-width: 720px) {
  #cb-hint { font-size: 19px; letter-spacing: .26em; text-indent: .26em;
             white-space: normal; text-align: center; width: 88vw; line-height: 1.5; }
  #cb-bar  { bottom: 3.6vh; width: 84vw; }
  #cb-fs   { top: 2.4vh; right: 4vw; width: 34px; height: 34px; }
}
