/* The opening: a pinned map stage with the season's panels scrolling over it.
   Without JavaScript it is the title, the dek and a plain list of the eight races. */

/* Static: title as the article hero, then the season as a list. */
.mh { width: min(var(--figure-width), calc(100% - 2 * var(--gutter) - var(--spine-room))); margin-inline: auto; }
.mh-stage, .mh-frame, .mh-credit, .mh-end-more { display: none; }
.mh-races { margin-top: 56px; border-top: 1px solid var(--line); }
.mh-race .mh-text { display: grid; grid-template-columns: 7em 8em minmax(0, 1fr); gap: 4px 16px; align-items: baseline; padding: 12px 0; border-bottom: 1px solid var(--line); }
.mh-date { font-size: 14px; color: var(--muted); }
.mh-city { font-family: var(--display); font-size: 22px; letter-spacing: -.02em; }
.mh-status { font-size: 15px; line-height: 1.5; color: var(--muted); }
.mh-status b { font-weight: 500; color: var(--ink); }
.mh-status.is-next b { color: var(--accent); }
.mh-end .mh-card { margin-top: 20px; font-size: 15px; color: var(--muted); }
.mh-end-line { font-family: var(--display); font-size: 22px; color: var(--ink); }
.mh-end-link { margin-top: 6px; }
@media (max-width: 599px) { .mh-race .mh-text { grid-template-columns: 6.5em minmax(0, 1fr); } .mh-status { grid-column: 1 / -1; } }

/* Interactive: stage and panels share one grid cell; the stage sticks under the top bar. */
#opening.is-interactive { padding: 0; }
.is-interactive .mh { --band: 44px; --slot: calc(100svh - var(--pin)); display: grid; width: 100%; }
.is-interactive .mh > * { grid-area: 1 / 1; }
/* Water and land sampled from Apple's MutedStandard, so the drawn world and the map read as one. */
.mh { --mh-water: #bde8f9; --mh-land: #deedcb; }
.is-interactive .mh-stage { display: block; position: sticky; top: var(--pin); align-self: start; height: var(--slot);
  overflow: hidden; background: var(--mh-water); }
.mh-under, .mh-map, .mh-draw, .mh-shield { position: absolute; inset: 0; }
.mh-under { display: none; width: 100%; height: 100%; }
.mh.is-porthole .mh-under { display: block; }
/* The map holds a rest; in flight the script carries its drawing (tiles, then the course marks) to
   the camera with --mh-tf. Apple's logo and legal link (MapKit's controls, beside them) are never
   scaled, masked or moved; only the cover hides them, in flight. */
.mh-map :is(canvas, .mk-annotation-container) { transform: var(--mh-tf, none); transform-origin: 0 0; }
/* While it is smaller than the stage the map shows through a soft porthole (custom properties set per
   frame); only the tiles, since the marks' layer has no height to mask. Solid to CORE (hero.js, 40%) of
   the radius, then a smoothstep feather, so no ring at its edge. */
.mh.is-porthole .mh-map canvas {
  --mh-port: radial-gradient(circle var(--mr) at var(--mx) var(--my), #000 40%, rgb(0 0 0 / .84) 55%, rgb(0 0 0 / .5) 70%, rgb(0 0 0 / .16) 85%, transparent),
    linear-gradient(90deg, transparent, #000 var(--me), #000 calc(100% - var(--me)), transparent),
    linear-gradient(transparent, #000 var(--me), #000 calc(100% - var(--me)), transparent);
  -webkit-mask-image: var(--mh-port); mask-image: var(--mh-port);
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
/* The drawn world (land on water) shows first, covers the map mid-flight and where MapKit can't zoom
   out far enough; the script sets its opacity. In flight it may hide the band (Apple's logo and
   legal link) too; at every rest it stops above it. */
.mh-draw { width: 100%; height: 100%; background: var(--mh-water); }
/* Its layers: land, the city's streets, the course marks. Each city's streets are one element the
   compositor moves and scales (hero.js drawnRenderer), rasterised once at its rest scale. */
.mh-draw > svg, .mh-streets { position: absolute; inset: 0; width: 100%; height: 100%; }
.mh-streets { overflow: hidden; }
.mh-streets-city { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform, opacity; }
.mh.is-apple:not(.is-transit) .mh-draw { clip-path: inset(0 0 var(--band) 0); }
/* Takes wheel and touch so the page scrolls, never the map; at rest Apple's logo and legal link stay reachable in the band. */
.mh-shield { bottom: var(--band); }

.mh-land { fill: var(--mh-land); fill-rule: evenodd; }
/* City detail (OpenStreetMap), in Apple's muted palette; lines keep their width as the map scales. */
.mh { --mh-urban: #eaebe1; --mh-park: #c9e5b0; --mh-road: #fff; --mh-casing: #d8d1c4; --mh-major: #fdf0cf; --mh-major-casing: #e2c99a; --mh-rail: #b4b1aa; }
.mh-c-sea, .mh-c-water { fill: var(--mh-water); }
.mh-c-land { fill: var(--mh-land); fill-rule: evenodd; }
.mh-c-urban { fill: var(--mh-urban); }
.mh-c-park { fill: var(--mh-park); }
.mh-c-buildings { fill: var(--mh-casing); }
/* Widths are in CSS px at the rest scale: --px is the user units per px, set by hero.js when a
   city's layer is sized (a static layer, so no per-frame vector-effect work). */
[class^="mh-c-road"], .mh-c-rail { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.mh-c-rail { stroke: var(--mh-rail); stroke-width: calc(var(--px, 1) * 1px); }
.mh-c-road.is-minor { stroke: var(--mh-road); stroke-width: calc(var(--px, 1) * 1.2px); }
.mh-c-road.is-mid { stroke: var(--mh-road); stroke-width: calc(var(--px, 1) * 2px); }
.mh-c-road.is-major { stroke: var(--mh-major); stroke-width: calc(var(--px, 1) * 3px); }
.mh-c-road.is-casing { stroke: var(--mh-casing); }
.mh-c-road.is-major.is-casing { stroke: var(--mh-major-casing); }
.mh-c-road.is-minor.is-casing { stroke-width: calc(var(--px, 1) * 2.5px); }
.mh-c-road.is-mid.is-casing { stroke-width: calc(var(--px, 1) * 3.3px); }
.mh-c-road.is-major.is-casing { stroke-width: calc(var(--px, 1) * 4.3px); }
.mh-line { fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; }
.mh-start { fill: var(--paper); stroke: var(--ink); stroke-width: 2; }
.mh-finish { fill: var(--accent); stroke: var(--paper); stroke-width: 2; }
.mh-dot { fill: var(--ink); }
.mh-label { font: 500 12px/1 var(--reading); fill: var(--muted); paint-order: stroke; stroke: var(--paper); stroke-width: 4px; stroke-linejoin: round; }
.mh-dot.is-active { fill: var(--accent); }
/* The same marks as MapKit annotations. */
.mh-pin { width: 14px; height: 14px; border-radius: 50%; box-sizing: border-box; }
.mh-pin.is-start { background: #fff; border: 2px solid var(--ink); }
.mh-pin.is-finish { background: var(--accent); border: 2px solid #fff; }
.mh-pin.is-dot { width: 9px; height: 9px; margin: 2.5px; background: #fff; border: 2px solid var(--ink); }
.mh-pin.is-dot.is-active { background: var(--accent); border-color: #fff; }

.is-interactive .mh-steps { position: relative; z-index: 1; pointer-events: none; }
.is-interactive .mh-races { margin: 0; border: 0; }
.is-interactive .mh-slot { height: var(--slot); display: flex; align-items: center;
  padding: 32px var(--gutter) calc(var(--band) + 24px) calc(var(--gutter) + var(--spine-room)); }
.is-interactive .mh-card { pointer-events: auto; width: min(420px, 100%); padding: clamp(24px, 2.6vw, 36px);
  background: var(--paper); border: 1px solid var(--line); box-shadow: 0 1px 2px rgba(24, 33, 38, .04), 0 18px 48px rgba(24, 33, 38, .08); }
.is-interactive .mh-race .mh-text { display: block; padding: 0; border: 0; }
.is-interactive .mh-city { margin-top: 14px; font-size: clamp(48px, 5.4vw, 80px); line-height: .98; letter-spacing: -.045em; will-change: transform; }
.is-interactive .mh-status { margin-top: 22px; font-size: 16px; }
.is-interactive .mh-frame { display: block; margin-top: 24px; aspect-ratio: 4 / 3; overflow: hidden; background: var(--soft); }
.mh-img { display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(1.14); will-change: transform; }
.is-interactive .mh-credit { display: block; margin-top: 12px; font-size: 12px; line-height: 1.5; color: var(--muted); }
.mh-credit a { color: var(--muted); }

/* The world views rest their card low, under the cities (over the Southern Ocean on Apple's map). */
.is-interactive :is(.mh-open, .mh-end) { align-items: flex-end; }
.is-interactive .mh-open .mh-card { width: min(560px, 100%); }
.is-interactive .mh-open h1 { font-size: clamp(56px, 7.4vw, 112px); will-change: transform; }
.is-interactive .mh-open .asof { margin-top: 20px; }
.is-interactive .mh-open .dek { margin-top: 24px; max-width: 32ch; font-size: clamp(18px, 1.6vw, 21px); }
.is-interactive .mh-end .mh-card { margin: 0; }
.is-interactive .mh-end-line { font-size: clamp(32px, 3.4vw, 44px); line-height: 1.1; letter-spacing: -.035em; text-wrap: balance; }
.is-interactive .mh-end-more { display: block; margin-top: 16px; font-size: 16px; line-height: 1.55; }
.is-interactive .mh-end-link { margin-top: 20px; font-size: 16px; }
.mh-end-link a { color: var(--ink); text-decoration-color: var(--accent); text-decoration-thickness: 2px; }

/* Narrow: the panel rests low, clear of the band, and the map frames the course above it. */
@media (max-width: 899px) {
  .is-interactive .mh-slot { align-items: flex-end; padding: 16px var(--gutter) calc(var(--band) + 16px); }
  .is-interactive .mh-card { width: 100%; }
  .is-interactive .mh-race .mh-card { display: grid; grid-template-columns: minmax(0, 1fr) 104px; column-gap: 16px; padding: 20px; }
  .is-interactive .mh-race .mh-frame { margin: 4px 0 0; align-self: start; }
  .is-interactive .mh-race .mh-credit { grid-column: 1 / -1; }
  .is-interactive .mh-city { font-size: clamp(40px, 11vw, 56px); }
  .is-interactive .mh-status { margin-top: 18px; font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .mh-img { transform: none; }
}
