/* ============================================================
   INTERSTITIALS
   ============================================================
   Every screen between the player and the next lap: splash, the first-run
   lesson, promotion, credits. They share one container and one motion
   language, because the thing that makes a game feel built rather than
   assembled is that every screen arrives the same way.

   THE MOTION LANGUAGE — four moves, and nothing else:

     rise    content enters 14px low and transparent, 260ms. Staggered down
             the screen so the eye is led rather than flooded.
     draw    hairlines scale in from the left, 320ms. The 1px rule is the
             brand; animating it costs nothing and reads as precision.
     roll    hero numerals count up. Tabular figures, so nothing reflows.
     sweep   a band of tier colour crosses the screen. RESERVED for
             promotion — it is the one thing the player sees three times in
             a career, and it must not be diluted by using it anywhere else.

   Exits hand off atomically after the destination is prepared. Only content
   enters with motion; the opaque screen never reveals a stale page beneath it.

   Nothing here BLOCKS. Every screen is fully interactive from frame one, and
   .settled short-circuits every animation to its end state, so a player who
   taps immediately is never waiting on a transition they did not ask for. */

#screen {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
#screen[hidden] { display: none; }

/* ---- the four moves ---- */

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes draw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes sweep {
  from { transform: translateY(101%); }
  to   { transform: translateY(-101%); }
}

.rise { animation: rise 260ms cubic-bezier(.2,.7,.2,1) both; }
.rule {
  height: 1px; background: var(--panel-edge); transform-origin: left center;
  animation: draw 320ms cubic-bezier(.2,.7,.2,1) both;
}

/* A tap settles everything immediately. Duration zero rather than removing
   the animation, so elements land on their end state instead of snapping
   back to the unanimated one. */
.settled .rise,
.settled .rule { animation-duration: 0s; }

/* ---- shared furniture ---- */

.sc-pad { padding: calc(env(safe-area-inset-top) + 22px) 22px calc(env(safe-area-inset-bottom) + 22px); }
.sc-grow { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.sc-kicker {
  font-size: 12px; letter-spacing: 3.5px; text-transform: uppercase;
  color: var(--dim);
}
.sc-title {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: 46px; line-height: .96; letter-spacing: 1.5px;
}
.sc-body { font-size: 15px; line-height: 1.55; color: #a6a6ae; }

.sc-actions { display: flex; gap: 1px; background: var(--panel-edge); margin-top: 26px; }
.sc-btn {
  flex: 1; padding: 16px 10px; border: 0; cursor: pointer;
  background: var(--panel); color: var(--text);
  font-family: var(--display); font-size: 19px; font-weight: 600;
  letter-spacing: 2.5px; text-transform: uppercase;
}
.sc-btn.solid { background: var(--text); color: #08080c; }
.sc-btn:active { opacity: .7; }

/* ---- 1. splash ---- */
/* Also the native launch image: the same markup is screenshotted at build
   time, so what the player sees while the WebView boots is the real screen
   rather than an approximation of it that drifts. */

.splash { align-items: flex-start; justify-content: flex-end; }
.splash .mark {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: 62px; line-height: .88; letter-spacing: 1px;
}
.splash .tag { margin-top: 12px; font-size: 14px; letter-spacing: 2.5px; color: var(--dim); text-transform: uppercase; }
.splash .bars { display: flex; gap: 3px; margin: 26px 0 8px; }
.splash .bars i { height: 3px; flex: 1; background: var(--panel-edge); transform-origin: left; animation: draw 500ms cubic-bezier(.2,.7,.2,1) both; }
.splash .bars i.lit { background: var(--purple); }

/* ---- 2. first-run lesson ---- */

.beat { display: flex; gap: 16px; align-items: flex-start; padding: 20px 0; }
.beat .n {
  font-family: var(--display); font-size: 30px; font-weight: 700;
  color: var(--dim); min-width: 34px; line-height: 1;
}
/* Spans, so they need telling they are blocks — as inline elements the
   heading and its explanation ran together into one paragraph. */
.beat > span { display: block; }
.beat .h { display: block; font-family: var(--display); font-size: 25px; font-weight: 600; letter-spacing: 1.5px; text-transform: uppercase; }
.beat .d { display: block; font-size: 14px; color: #9a9aa2; line-height: 1.5; margin-top: 4px; }
.beat .d b { color: var(--text); font-weight: 600; }

/* The braking zone, drawn the way the road draws it, so the first time the
   player sees this gradient is not mid-corner at 300 km/h. */
.zone { height: 16px; margin-top: 10px; display: flex; }
.zone i { flex: 1; }
.zone .early { background: linear-gradient(90deg, rgba(255,68,28,.65), rgba(255,213,0,.5)); }
.zone .good  { background: rgba(23,201,100,.8); flex: 0 0 22%; }
.zone .late  { background: linear-gradient(90deg, rgba(255,213,0,.5), rgba(255,68,28,.65)); }

/* ---- 6. promotion ---- */
/* The sweep is the whole point. It is a band of the new tier's colour
   crossing the full screen behind the type, once, and it appears nowhere
   else in the game. */

.promo { position: relative; overflow: hidden; justify-content: center; }
.promo .band {
  position: absolute; left: 0; right: 0; height: 46%;
  background: linear-gradient(180deg, transparent, var(--tier-col), transparent);
  opacity: .22; pointer-events: none;
  animation: sweep 1100ms cubic-bezier(.35,.1,.2,1) both 120ms;
}
.promo .from {
  font-family: var(--display); font-size: 21px; font-weight: 600;
  letter-spacing: 3px; color: var(--dim); text-transform: uppercase;
}
.promo .to {
  font-family: var(--display); font-size: 68px; font-weight: 700;
  text-transform: uppercase; color: var(--tier-col);
  letter-spacing: 2px; line-height: 1;
  animation: spread 780ms cubic-bezier(.2,.7,.2,1) both 200ms;
}
/* Letter-spacing is animated here and nowhere else, so the promotion reads as
   a different KIND of event rather than a louder version of a result. */
@keyframes spread {
  from { opacity: 0; letter-spacing: -2px; }
  to   { opacity: 1; letter-spacing: 9px; }
}
#screen.settled .promo .to,
#screen.settled .promo .band { animation-duration: 0s; }

.promo .stat { display: flex; justify-content: space-between; padding: 13px 0; }
.promo .stat .k { font-size: 13px; letter-spacing: 2px; text-transform: uppercase; color: var(--dim); }
.promo .stat .v { font-family: var(--display); font-size: 25px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---- 7. credits and licences ---- */

.cred h3 {
  font-family: var(--display); font-size: 15px; font-weight: 600;
  letter-spacing: 3px; text-transform: uppercase; color: var(--dim);
  margin: 26px 0 8px;
}
.cred p { font-size: 14px; line-height: 1.6; color: #a6a6ae; margin-bottom: 8px; }
.cred a { color: var(--purple); text-decoration: none; overflow-wrap: anywhere; }
.cred .lic {
  font-family: var(--mono); font-size: 11px; line-height: 1.55; color: #7a7a84;
  background: var(--panel); border: 1px solid var(--panel-edge);
  padding: 12px; margin-top: 6px; white-space: pre-wrap;
  user-select: text; -webkit-user-select: text;
}
.cred .who { display: flex; justify-content: space-between; padding: 9px 0; font-size: 14px; }
.cred .who span:last-child { color: var(--dim); }

/* ---- shared header ---- */
/* Giugiaro's one structural idea, and the best thing in the set: the same bar
   on every screen, monogram and wordmark on the left, where-you-are on the
   right. It is what stops seven screens reading as seven apps. */

.sc-head {
  display: flex; align-items: center; gap: 10px;
  padding: calc(env(safe-area-inset-top) + 14px) 24px 13px;
  border-bottom: 1px solid var(--panel-edge);
}
.sc-head .bp {
  font-family: var(--display); font-weight: 700; font-size: 15px;
  letter-spacing: 1px; border: 1px solid var(--panel-edge);
  padding: 2px 6px; line-height: 1.15;
}
.sc-head .wm {
  font-family: var(--display); font-weight: 600; font-size: 13px;
  letter-spacing: 2.5px; text-transform: uppercase; color: #b9b9c2;
}
.sc-head .where {
  margin-left: auto; font-size: 11px; letter-spacing: 2.5px;
  text-transform: uppercase; color: var(--dim);
}

/* 24px inset everywhere, per the shared grid on the sheet. */
.sc-pad { padding: 22px 24px calc(env(safe-area-inset-bottom) + 22px); }

/* ---- splash motif ---- */
/* A braking trace: the line the car takes through a corner, with the racing
   line picked out. It is the one illustrative mark in the whole app. */

.splash { align-items: stretch; justify-content: center; text-align: center; }
.splash .mark { font-size: 58px; }
.splash .trace { width: 100%; height: 120px; margin-top: 30px; }
.splash .trace path { fill: none; stroke-linecap: round; }
.splash .trace .edge { stroke: #3a3a42; stroke-width: 2; }
.splash .trace .line {
  stroke: var(--purple); stroke-width: 2.5;
  stroke-dasharray: 340; stroke-dashoffset: 340;
  animation: trace 1400ms cubic-bezier(.3,.6,.2,1) both 260ms;
}
@keyframes trace { to { stroke-dashoffset: 0; } }
#screen.settled .splash .trace .line { animation-duration: 0s; }
.splash .foot {
  margin-top: 26px; font-size: 11px; letter-spacing: 3.5px;
  text-transform: uppercase; color: #4a4a52;
}

/* ---- promotion badge ---- */
/* Three stacked chevrons in the new tier's colour, which is as close to a
   trophy as a game this austere should get. */

.promo .badge { display: flex; flex-direction: column; align-items: center; gap: 5px; margin-bottom: 4px; }
.promo .badge i {
  display: block; width: 46px; height: 15px; background: var(--tier-col);
  clip-path: polygon(50% 0, 100% 100%, 76% 100%, 50% 42%, 24% 100%, 0 100%);
  animation: rise 320ms cubic-bezier(.2,.7,.2,1) both;
}
.promo .badge i:nth-child(1) { animation-delay: 240ms; opacity: .45; }
.promo .badge i:nth-child(2) { animation-delay: 330ms; opacity: .72; }
.promo .badge i:nth-child(3) { animation-delay: 420ms; }
#screen.settled .promo .badge i { animation-duration: 0s; }

.promo .split { display: flex; gap: 1px; background: var(--panel-edge); margin-top: 18px; }
.promo .split > div { flex: 1; background: var(--bg); padding: 14px 4px; text-align: center; }
.promo .split .k { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--dim); }
.promo .split .v {
  font-family: var(--display); font-size: 34px; font-weight: 700;
  font-variant-numeric: tabular-nums; margin-top: 2px;
}

/* ---- 4 & 5. race result ---- */
/* The verdict first, then the number, then the evidence. The old screen led
   with a list of seven corner scores and put the finishing position at the
   bottom, which buried the only line the player actually came for. */

/* Scoped to :not(.hidden), not !important: an !important display here beat
   the shared `#results.hidden { display: none }` rule, so the results screen
   stayed laid out over the whole app while invisible and ate every tap. */
/* IT HAS TO SCROLL. #results is `position: fixed; inset: 0` with no overflow,
   so everything past the fold was simply unreachable — including the buttons
   that leave the screen. It survived because the tests drive Monza, which has
   six corners; Baku has eleven, and adding the classification put every
   circuit over the fold. A results screen you cannot leave is a dead end, so
   this is load-bearing rather than cosmetic. */
#results:not(.hidden) {
  padding: 0; display: block;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* Fades up over a car that is still running — the race does not cut at the
     line, it is covered. Matched to FINISH_ROLL in index.html. */
  animation: resultsIn 620ms ease both;
}
@keyframes resultsIn { from { opacity: 0; } to { opacity: 1; } }
#results .res-body { padding: 26px 24px calc(env(safe-area-inset-bottom) + 24px); }

/* The podium badge, in the top right the score was leaving empty. Absolute, so
   it costs the verdict and the score no room — they are still the left column
   of the screen and this sits beside them. */
#results .podium-badge {
  position: absolute; top: 18px; right: 16px;
  width: 104px; height: 122px; pointer-events: none;
  animation: rise 420ms cubic-bezier(.2, .7, .3, 1) both;
  animation-delay: 160ms;
}
/* The wreath's own box. The artwork is 440 x 423, so at 104 wide it is 100
   tall — stated rather than left to `contain`, because everything below is
   positioned against this box and it must not change shape with the label. */
#results .podium-badge .laurel {
  position: absolute; left: 0; top: 0; width: 104px; height: 100px;
  background: var(--pod); opacity: .88;
  -webkit-mask: url(../assets/ui/laurel.png) no-repeat center / 100% 100%;
  mask: url(../assets/ui/laurel.png) no-repeat center / 100% 100%;
}
/* Centred on the HOLE, not on the artwork. The wreath is open at the top and
   tied at the bottom, so its ink sits lower than its opening does: the
   interior centroid is 43% of the way down, and centring the numeral in the
   box instead puts it 7px low, sitting on the ribbon. That 43% is measured
   off the alpha channel, so it moves if the artwork is ever redrawn. */
#results .podium-badge .pos {
  position: absolute; left: 0; top: 0; width: 104px; height: 86px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: 46px; font-weight: 700;
  line-height: 1; color: var(--pod);
}
#results .podium-badge .lab {
  position: absolute; left: 0; right: 0; bottom: 0;
  text-align: center;
  font-family: var(--display); font-size: 11px; font-weight: 600;
  letter-spacing: 2.2px; color: var(--pod); opacity: .75;
}
/* res-body is the positioning context; without this the badge would hang off
   the scroll container and float over the rows as the screen scrolls. */
#results .res-body { position: relative; }

#results .verdict {
  font-family: var(--display); font-size: 27px; font-weight: 700;
  letter-spacing: 3px; text-transform: uppercase; color: #9a9aa2;
}
#results .verdict.good { color: var(--green); }
#results .verdict.bad { color: var(--orange); }

/* Which circuit, at which tier. The rewrite dropped this from the win screen
   while keeping it on the DNF one, so a finished lap no longer said what it
   had been run at — and a ROOKIE 121 is not the achievement an ELITE 121 is. */
#results .subhead {
  font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase;
  color: var(--dim); margin-top: 5px;
}
#results .hero { font-size: 78px; margin: 6px 0 0; }
#results .hero.dnf { color: var(--orange); }
#results .finish { font-size: 26px; }
#results .finish.good { color: var(--green); }

#results .dnf-note {
  margin-top: 14px; font-size: 14px; color: var(--dim); font-style: italic;
}

#results .ends { display: flex; gap: 1px; background: var(--panel-edge); margin-top: 24px; }
#results .ends button {
  flex: 1; padding: 16px 8px; border: 0; cursor: pointer;
  background: var(--panel); color: var(--text);
  font-family: var(--display); font-size: 18px; font-weight: 600;
  letter-spacing: 2px; text-transform: uppercase;
}
#results .ends .solid { background: var(--text); color: #08080c; }
#results .ends .solid.warn { background: var(--orange); color: #0b0603; }
#results .ends button:active { opacity: .7; }

.promo .arrow {
  text-align: center; font-size: 26px; line-height: 1;
  color: var(--tier-col); margin: 2px 0 -2px;
}

/* ---- 8. pause ---- */

.countin {
  font-family: var(--display); font-size: 120px; font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1;
  animation: rise 200ms cubic-bezier(.2,.7,.2,1) both;
}

/* The credits run long, so their body sets its own measure rather than
   inheriting the size the other screens use for two sentences. */
.cred p { font-size: 13px; }
.cred .who { font-size: 13px; }

/* ---- 9 & 10. season standings ---- */

.sc-title .of { font-size: 26px; color: var(--dim); font-weight: 600; }
.sc-body b.short { color: var(--yellow); font-weight: 600; }
.sc-body b.done { color: var(--green); font-weight: 600; }

/* The gate, drawn as a bar with the threshold marked on it. A number alone
   ("240 needed") does not say whether that is nearly there or nowhere near. */
.gate {
  position: relative; height: 8px; margin-top: 16px;
  background: var(--panel); border: 1px solid var(--panel-edge);
}
.gate i { position: absolute; inset: 0 auto 0 0; background: var(--purple); }
.gate .mark {
  position: absolute; right: 0; top: 12px;
  font-size: 11px; letter-spacing: 1.5px; color: var(--dim);
  font-variant-numeric: tabular-nums;
}

.st-table { border-top: 1px solid var(--panel-edge); }
.st-row {
  display: grid; grid-template-columns: 34px 1fr 64px 62px;
  align-items: center; gap: 8px; padding: 9px 0;
  border-bottom: 1px solid var(--panel-edge);
}
.st-row.todo { opacity: .38; }
.st-row .rnd { font-size: 11px; color: var(--dim); font-variant-numeric: tabular-nums; }
.st-row .nm {
  font-family: var(--display); font-size: 17px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.st-row .bar { height: 5px; background: #17171d; }
.st-row .bar i { display: block; height: 100%; background: #6a6a72; }
.st-row .bar i.win { background: var(--green); }
.st-row .pts { text-align: right; font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums; }
.st-row .pts b { color: var(--text); font-weight: 600; margin-left: 6px; }

.st-h {
  font-family: var(--display); font-size: 15px; font-weight: 600;
  letter-spacing: 3px; text-transform: uppercase; color: var(--dim);
  margin: 24px 0 8px;
}

/* ---- the drivers' championship ----
   Twenty-two rows, so this is the tightest table in the app. The three-letter
   code does the identifying on a narrow screen and the full name is allowed to
   ellipsis behind it; a driver is findable by code alone, which is the whole
   reason motorsport has them. */
/* The one text field in the game. Sized like the titles around it so it reads
   as part of the screen rather than as a form dropped into one. */
.sc-input {
  width: 100%; margin-top: 18px; padding: 16px 12px;
  background: var(--panel); border: 1px solid var(--panel-edge); color: var(--text);
  font-family: var(--display); font-size: 26px; font-weight: 600;
  letter-spacing: 2px; text-transform: uppercase; text-align: center;
}
.sc-input::placeholder { color: var(--dim); }
.sc-input:focus { outline: none; border-color: var(--purple); }

/* Ten liveries, two rows of five. Square and large enough to be a thumb
   target — the colour IS the label, so there is nothing else to read. */
.sw-row {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 8px; margin-top: 10px;
}
.sw {
  aspect-ratio: 1; width: 100%; padding: 0; cursor: pointer;
  background: var(--sw); border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .35);
}
/* The selected one is called out with a ring OUTSIDE the colour, so the
   swatch never has to give up any of itself to show it is chosen. */
.sw.on { border-color: var(--text); outline: 2px solid var(--bg); outline-offset: -4px; }
.sw:active { transform: scale(.94); }

.dr-table { border-top: 1px solid var(--panel-edge); }
.dr-row {
  display: grid; grid-template-columns: 28px 36px 1fr 30px;
  align-items: center; gap: 8px; padding: 7px 0;
  border-bottom: 1px solid var(--panel-edge);
  font-size: 14px; color: #b8bcc4;
}
.dr-row .pos { font-size: 11px; color: var(--dim); font-variant-numeric: tabular-nums; }
.dr-row .code { font-family: var(--mono); font-size: 11px; letter-spacing: 1px; color: var(--dim); }
.dr-row .dn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dr-row .pt { text-align: right; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
/* The player's row is the one the eye is looking for, every time. */
.dr-row.you { color: var(--text); }
.dr-row.you .dn { font-weight: 600; }
.dr-row.you .pos, .dr-row.you .code { color: var(--purple); }
.dr-row.you .pt { color: var(--purple); }
.dr-row .w { color: var(--dim); font-size: 11px; margin-left: 6px; }

/* Starting the season again. Deliberately quiet and deliberately at the
   bottom: it deletes a season's results, so it should never be the thing a
   thumb finds first. */
.st-reset {
  width: 100%; margin-top: 18px; padding: 13px; cursor: pointer;
  background: none; border: 1px solid var(--panel-edge); color: var(--dim);
  font-family: var(--display); font-size: 13px; font-weight: 600;
  letter-spacing: 2.5px; text-transform: uppercase;
}
.st-reset:active { background: #1d1d25; }
.st-reset.arm { color: var(--orange); border-color: var(--orange); }

/* A row that is also the way back into that race. */
.st-gain {
  display: grid; grid-template-columns: 1fr auto 52px;
  align-items: center; gap: 10px; cursor: pointer;
  padding: 12px; margin-bottom: 1px;
  background: var(--panel); border: 1px solid var(--panel-edge);
}
.st-gain:active { background: #1d1d25; }
.st-gain .nm {
  font-family: var(--display); font-size: 19px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
}
.st-gain .was { font-size: 12px; color: var(--dim); }
.st-gain .up {
  text-align: right; font-family: var(--display); font-size: 22px;
  font-weight: 700; color: var(--green); font-variant-numeric: tabular-nums;
}

/* The one-line season state on the result screen: how it is going, after
   every race, without a tap. */
#results .season-line {
  margin-top: 14px; padding: 11px 0;
  border-top: 1px solid var(--panel-edge); border-bottom: 1px solid var(--panel-edge);
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--dim);
}
#results .season-line b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
#results .season-line .link { color: var(--purple); }
