/* =============================================================
   SkiAllDay — landing page
   Loaded after resort.css, which owns every token, the top bar,
   the footer, the section rhythm and the theme switch. Nothing
   here redefines a colour or a typeface; it adds the handful of
   components only the landing page has.
   ============================================================= */

/* ---------- hero ---------- */

/* .rhero carries the scene, the scrim and the isolation context. This is the
   same hero a resort gets, with room for a headline that is a sentence rather
   than a place name, and for the two buttons under it. */
.rhero--home .rhero-inner {
  padding-bottom: clamp(140px, 15vw, 220px);
  max-width: 1180px;
}

/* A resort hero carries a name and a line under it, so the vertical wash in
   resort.css is enough. This one carries a headline, a paragraph, two buttons
   and a key, and the route drawn down the range has to stay readable beside all
   of it — so above 860px the text is a column on the left and the wash goes
   with it, leaving the right of the range, and the route on it, unwashed.
   Below that there is no wash at all: resort.css drops the scene to a band at
   the foot of every hero, and the text sits on plain paper. */
.rhero--home {
  --paper-rgb: 247, 244, 238;
}
@media (min-width: 860px) {
  .rhero--home {
    --hero-scrim:
      linear-gradient(96deg,
        rgba(var(--paper-rgb), .97) 0%, rgba(var(--paper-rgb), .95) 30%,
        rgba(var(--paper-rgb), .62) 48%, rgba(var(--paper-rgb), .12) 64%,
        rgba(var(--paper-rgb), 0) 74%),
      linear-gradient(180deg,
        rgba(var(--paper-rgb), .75) 0%, rgba(var(--paper-rgb), .25) 12%,
        rgba(var(--paper-rgb), 0) 26%);
  }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .rhero--home { --paper-rgb: 9, 13, 20; }
}
:root[data-theme='dark'] .rhero--home { --paper-rgb: 9, 13, 20; }

.hero-kicker {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 26px; color: var(--hero-soft);
}
.hero-kicker span { white-space: nowrap; }
.hero-kicker .dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .6; }


.hero-line {
  display: block; font-size: clamp(2.5rem, 8.4vw, 5.25rem);
  line-height: 0.98; letter-spacing: -0.035em;
}

.hero-lede {
  font-family: var(--sans); font-size: clamp(1rem, 1.6vw, 1.125rem); line-height: 1.6;
  color: var(--hero-soft); max-width: 46ch; margin: 24px 0 0;
}
.hero-lede strong { color: var(--hero-ink); font-weight: 600; }

.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 18px; margin: 32px 0 0; }

.rhero--home .btn-solid, .rhero--home .btn-ghost {
  display: inline-block; padding: 13px 26px; text-decoration: none;
  font-family: var(--sans); font-size: 0.9375rem; font-weight: 600; white-space: nowrap;
  border: 1px solid var(--hero-ink); transition: background .15s, color .15s;
}
.rhero--home .btn-solid { background: var(--hero-ink); color: var(--paper); }
.rhero--home .btn-solid:hover { background: transparent; color: var(--hero-ink); }
.rhero--home .btn-ghost { background: transparent; color: var(--hero-ink); border-color: color-mix(in srgb, var(--hero-ink) 34%, transparent); }
.rhero--home .btn-ghost:hover { border-color: var(--hero-ink); }

/* The stat bar is the resort component; only the linked chip is new. */
.resort .chip a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--rule-strong); }
.resort .chip a:hover { border-bottom-color: var(--ink); }

/* ---------- the route drawn across the range ---------- */

/* Lift up, piste down, graded blue to black — the one thing the app does,
   drawn onto the page's own mountain rather than described beside it. The
   geometry comes from the same ridgeline the voxel generator produced, so the
   line lands on terrain instead of floating over it. */

/* These do not follow the theme. The rest of the page sits on paper, which
   inverts in dark mode; this route sits on snow, which does not — the voxel
   snow is near-white under both themes. Reading the theme tokens here rendered
   a dark-mode black run in the light grey the resort pages use for one, on top
   of a white snowfield, which is no colour at all. The route keeps the
   on-snow palette in both, exactly as the share card does. */
.rhero--home {
  --rt-casing: #ffffff;
  --rt-ink: #16202c;
}

.rt-casing { fill: none; stroke: var(--rt-casing); stroke-width: 14; stroke-linecap: round; stroke-linejoin: round; }
.rt-seg { fill: none; stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; }
.rt-seg--blue  { stroke: #2f6db3; }
.rt-seg--red   { stroke: #b8382b; }
.rt-seg--black { stroke: #23252a; }

.rt-lift { fill: none; stroke: var(--rt-ink); stroke-width: 3; }
.rt-pylon { stroke: var(--rt-ink); stroke-width: 3; stroke-linecap: round; }
.rt-station { fill: var(--rt-casing); stroke: var(--rt-ink); stroke-width: 3; }
.rt-node { fill: var(--rt-casing); stroke: #23252a; stroke-width: 3; }

/* Drawn on, in the order you would ride it: up the lift first, then down. */
.rt-draw {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: rt-draw 1s cubic-bezier(.4, .1, .2, 1) forwards;
  animation-delay: var(--d, 0s);
}
.rt-pop { opacity: 0; animation: rt-pop .45s ease-out forwards; animation-delay: var(--d, 0s); }

@keyframes rt-draw { to { stroke-dashoffset: 0; } }
@keyframes rt-pop { to { opacity: 1; } }

/* resort.css switches every animation off for a reader who asked for less
   motion, which would leave these dashed to nothing. Land them finished. */
@media (prefers-reduced-motion: reduce) {
  .rt-draw { stroke-dashoffset: 0; }
  .rt-pop { opacity: 1; }
}

/* A key, so the line reads as a diagram rather than as a squiggle. */
.hero-key {
  display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 30px 0 0; padding: 0; list-style: none;
  font-family: var(--sans); font-size: 0.6875rem; font-weight: 600;
  letter-spacing: .11em; text-transform: uppercase; color: var(--hero-soft);
}
.hero-key li { display: flex; align-items: center; gap: 8px; }
.hero-key i { width: 16px; height: 3px; flex: none; }
.hero-key .k-lift { height: 0; border-top: 2px solid currentColor; }
/* Same fixed on-snow palette as the line it keys. */
.hero-key .k-blue { background: #2f6db3; }
.hero-key .k-red { background: #b8382b; }
.hero-key .k-black { background: #23252a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hero-key .k-black { background: #4a5260; }
}
:root[data-theme='dark'] .hero-key .k-black { background: #4a5260; }

/* ---------- hero additions ---------- */

/* The second line answers the first, in the italic a resort hero gives its
   subtitle. */
.hero-line--alt {
  font-style: italic; color: var(--hero-soft);
  font-size: clamp(2rem, 6.6vw, 4.2rem); margin-top: 0.06em;
}

/* The one instruction on the page, set like the key it sits in. */
.hero-key .hero-cue { color: var(--hero-ink); margin-left: 8px; }
.hero-key .k-cue {
  width: 2px; height: 14px; background: currentColor;
  transform-origin: top; animation: cue 1.8s cubic-bezier(.5, 0, .3, 1) infinite;
}
@keyframes cue {
  0% { transform: scaleY(0); opacity: 1; }
  55% { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1) translateY(6px); opacity: 0; }
}

/* ---------- the descent ---------- */

/* Below the hero the document is one run, top station to village. Every
   section is laid out as a text column plus a corridor — the space a resort
   guide gives its rail — and the corridor swaps sides from one section to the
   next, so the line home.js draws through it crosses the page at every break.
   The piste signs in the corridors are the rail: same data-rail hooks, same
   scrollspy. */
.descent {
  --corridor: 240px;
  --corridor-gap: 48px;
  position: relative; max-width: 1180px; margin: 0 auto; padding: 0 var(--gutter);
}
.doc--descent { position: relative; z-index: 1; padding-bottom: 120px; }
.doc--descent .sec { padding: clamp(60px, 8vw, 104px) 0; }
.doc--descent .sec:first-child { border-top: 0; }
/* The number lives on the sign now; above the title it would say it twice. */
.doc--descent .sec-title::before { display: none; }

.run { display: grid; column-gap: var(--corridor-gap); }
.run--r { grid-template-columns: minmax(0, 1fr) var(--corridor); }
.run--l { grid-template-columns: var(--corridor) minmax(0, 1fr); }
.run--r .run-body { grid-column: 1; grid-row: 1; }
.run--r .run-gate { grid-column: 2; grid-row: 1; }
.run--l .run-gate { grid-column: 1; grid-row: 1; }
.run--l .run-body { grid-column: 2; grid-row: 1; }
.run-body { min-width: 0; }
.run-gate { position: relative; min-width: 0; }

/* The sign sits 84px in from the corridor's inner edge, which is the widest a
   carving turn swings either side of it; the name and grade take the outer
   side, where the line never goes. */
.resort .gate {
  position: absolute; top: 4px; display: flex; align-items: center; gap: 14px;
  color: inherit; text-decoration: none;
}
.run--r .gate { left: 68px; right: 0; }
.run--l .gate { right: 68px; left: 0; flex-direction: row-reverse; text-align: right; }

/* A European piste sign: a square in the run's colour carrying its number.
   Hollow until the run is unlocked — read, not merely scrolled past — exactly
   as a run you have not skied stays grey in the app. */
.gate-sign {
  flex: none; width: 32px; height: 32px; display: grid; place-items: center;
  font-family: var(--sans); font-size: 0.8125rem; font-weight: 700; line-height: 1;
  color: var(--ink-soft); background: var(--paper);
  border: 1.5px solid var(--rule-strong); border-radius: 3px;
  transition: background-color .35s, border-color .35s, color .35s;
}
.gate--blue { --g: var(--piste-blue); }
.gate--red { --g: var(--piste-red); }
.gate--black { --g: var(--piste-black); }
.gate.is-unlocked .gate-sign { background: var(--g); border-color: var(--g); color: var(--paper); }
.gate.is-fresh .gate-sign { animation: gate-pop .6s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes gate-pop { 0% { transform: scale(.7); } 100% { transform: scale(1); } }

.gate-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; font-family: var(--sans); }
.gate-name { font-size: 0.8125rem; font-weight: 600; color: var(--ink-mid); white-space: nowrap; }
.gate-meta {
  display: flex; gap: 6px; font-size: 0.625rem; font-weight: 600;
  letter-spacing: .11em; text-transform: uppercase; color: var(--ink-soft); white-space: nowrap;
}
.run--l .gate-meta { justify-content: flex-end; }
.gate-alt:not(:empty)::before { content: '·'; margin-right: 6px; }
.gate:hover .gate-name, .gate.is-current .gate-name { color: var(--ink); }

/* ---------- the line ---------- */

/* The SVG is built by home.js and sits under the document: text and plates
   paint over it, so it only shows in the corridors and across the section
   breaks, where nothing else is. */
.dl {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none; overflow: visible;
}
/* The route still to ski, drawn the way a planned route is: a dotted hairline. */
.dl-ahead {
  fill: none; stroke: var(--rule-strong); stroke-width: 1.5;
  stroke-dasharray: 1 7; stroke-linecap: round;
}
.dl-casing { fill: none; stroke: var(--paper); stroke-width: 11; stroke-linecap: round; stroke-linejoin: round; }
.dl-run { fill: none; stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round; }
.dl-run--blue { stroke: var(--piste-blue); }
.dl-run--red { stroke: var(--piste-red); }
.dl-run--black { stroke: var(--piste-black); }
.dl-station { fill: var(--paper); stroke: var(--ink); stroke-width: 2.5; }
.dl-label {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: .11em; text-transform: uppercase; fill: var(--ink-soft);
}
.dl-label tspan.dl-label-v { fill: var(--ink); }

/* The reader, as the position puck the app draws on a replay. */
.dl-puck-core { fill: var(--ink); stroke: var(--paper); stroke-width: 3; }
.dl-puck-halo { fill: none; stroke: var(--ink); stroke-width: 1.5; opacity: 0; transform-box: fill-box; transform-origin: center; animation: halo 2s ease-out infinite; }
@keyframes halo { 0% { transform: scale(.6); opacity: .45; } 100% { transform: scale(2.2); opacity: 0; } }
.dl-puck { transition: opacity .3s; }
.dl-puck.is-lift .dl-puck-core { fill: var(--paper); stroke: var(--ink); }

/* Speed and altitude beside the puck, the way the app labels a replay. */
.dl-chip {
  position: absolute; top: 0; left: 0; z-index: 3; pointer-events: none;
  padding: 7px 12px 8px; white-space: nowrap; font-family: var(--sans);
  background: color-mix(in srgb, var(--paper-raised) 90%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--rule); will-change: transform;
  opacity: 0; transition: opacity .3s;
}
.dl-chip.is-on { opacity: 1; }
.dl-chip-speed { font-size: 1.125rem; font-weight: 600; line-height: 1.1; color: var(--ink); }
.dl-chip-speed .unit { font-size: 0.62em; }
.dl-chip-sub {
  display: flex; align-items: center; gap: 6px; margin-top: 2px;
  font-size: 0.625rem; font-weight: 600; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-soft);
}
.dl-chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--g, var(--ink-soft)); flex: none; }
.dl-chip[data-grade='blue'] { --g: var(--piste-blue); }
.dl-chip[data-grade='red'] { --g: var(--piste-red); }
.dl-chip[data-grade='black'] { --g: var(--piste-black); }
.dl-chip.is-lift .dl-chip-dot { border-radius: 0; height: 2px; width: 10px; background: var(--ink); }

/* A reader who asked for less motion gets the whole line, drawn, and no puck
   chasing their scroll. */
@media (prefers-reduced-motion: reduce) {
  .dl-puck, .dl-chip { display: none; }
}
@media print { .dl, .dl-chip { display: none; } }

/* ---------- devices ---------- */

/* The screens sit in the iPhone frame the App Store artwork is built from,
   turned in real 3D: a resting angle per phone, plus a few degrees either way
   as it travels through the viewport (home.js sets --p from -1 to 1). Two
   titanium layers behind the frame become its side once it turns. Labels float
   in front of the glass, in the language the app labels a replay with.

   The screen box is the frame's transparent window: 52,50 and 873x1900 of a
   977x2000 frame, with a 146px corner. */
.stage {
  display: flex; align-items: flex-start; justify-content: center;
  perspective: 1500px; margin: 46px 0 0; padding: 18px 0 34px;
}
.stage--three .phone { width: min(31%, 232px); }
.stage--three .phone:nth-child(2) { z-index: 2; margin: -22px -10px 0; }
.stage--pair { justify-content: flex-start; gap: 64px; padding-left: 72px; }
.stage--pair .phone { width: min(40%, 248px); }
.stage--pair .phone:nth-child(2) { margin-top: 64px; }

.phone { position: relative; margin: 0; flex: none; }
/* Where it stands: a soft pool on the paper, not a drop shadow on the glass. */
.phone::after {
  content: ''; position: absolute; left: 12%; right: 12%; bottom: -26px; height: 30px; z-index: -1;
  background: radial-gradient(closest-side, rgba(20, 24, 30, .24), transparent); pointer-events: none;
}
.phone-body {
  --p: 0;
  position: relative; aspect-ratio: 640 / 1310; transform-style: preserve-3d;
  transform: rotateY(calc((var(--ry0) + var(--p) * -9) * 1deg)) rotateX(calc(var(--p) * 4deg));
  will-change: transform;
}
.phone-edge {
  position: absolute; inset: 0.3% 0.5%; border-radius: 20.3% / 9.9%;
  background: linear-gradient(90deg, #6a6e75, #2a2d32 18%, #1b1d21 82%, #62666d);
  transform: translateZ(-7px);
}
.phone-edge--far { transform: translateZ(-14px); filter: brightness(.6); }
.phone-screen {
  position: absolute; left: 5.322%; top: 2.5%; width: 89.355%; height: 95%;
  border-radius: 16.72% / 7.684%; overflow: hidden; background: #0d1117;
  container-type: inline-size;
}
.phone-media {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 50% 0;
}
/* The story is 9:16 and the screen is taller, so it is letterboxed in its own
   navy rather than cropped through its figures. */
.phone-media--story { object-fit: contain; background: linear-gradient(180deg, #141f33, #0a121d); }
.phone-media--story.is-auto { cursor: pointer; }
.phone-frame {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  pointer-events: none; transform: translateZ(1px);
}
/* The clean 9:41 bar, over the blur lib/app-shots.mjs left where the
   recorded one was. Sized in container units so it scales with the phone. */
.phone-sb { position: absolute; inset: 0 0 auto; height: 12cqw; color: #0b0b0f; pointer-events: none; }
.phone--dark .phone-sb { color: #fff; }
.phone-sb span {
  position: absolute; left: 11.9%; top: 5.64cqw; transform: translateY(-50%);
  font: 650 5.04cqw/1 -apple-system, 'SF Pro Text', var(--sans); letter-spacing: -0.01em;
}
.phone-sb svg { position: absolute; right: 8.5%; top: 5.7cqw; transform: translateY(-50%); width: 21.8%; height: 4.4cqw; fill: currentColor; }
.phone-rec { position: absolute; left: 27%; width: 44.4%; top: 2.5cqw; height: 9.8cqw; border-radius: 999px; background: #000; }

.callout {
  position: absolute; margin: 0; z-index: 3; transform: translateZ(48px);
  display: flex; flex-direction: column; gap: 1px; padding: 8px 13px 9px;
  background: color-mix(in srgb, var(--paper-raised) 92%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--rule); font-family: var(--sans); white-space: nowrap;
}
.callout--r { left: 72%; }
.callout--l { right: 72%; }
/* On the glass, where a label beside the phone would land on neighbouring text. */
.callout--in { left: 14%; }
.callout b { font-size: 0.9375rem; font-weight: 600; line-height: 1.2; color: var(--ink); }
.callout span {
  font-size: 0.625rem; font-weight: 600; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-soft);
}
.callout:has(.callout-dot) { padding-left: 28px; }
.callout-dot { position: absolute; left: 12px; top: 13px; width: 8px; height: 8px; border-radius: 50%; }
.callout-dot--blue { background: var(--piste-blue); }
.callout-dot--red { background: var(--piste-red); }
.callout-dot--black { background: var(--piste-black); }

/* Watch: a case drawn round the face, and a crown. */
.devices { margin: 40px 0 0; }
.watches {
  display: grid; grid-template-columns: repeat(3, minmax(0, 160px)); gap: 26px;
  perspective: 1200px;
}
.watch { margin: 0; min-width: 0; }
.watch-case {
  --p: 0;
  position: relative; padding: 8%; border-radius: 31% / 27%;
  background: linear-gradient(150deg, #5a5e65, #1e2024 40%, #2b2e33 75%, #50545b);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14);
  transform: rotateY(calc((var(--ry0) + var(--p) * -10) * 1deg));
}
.watch-case::after {
  content: ''; position: absolute; right: -3.5%; top: 26%; width: 5%; height: 15%;
  border-radius: 2px; background: linear-gradient(90deg, #2b2e33, #777b82);
}
.watch-case img { display: block; width: 100%; height: auto; border-radius: 24% / 20%; background: #000; }
.watch figcaption { padding: 12px 2px 0; font-family: var(--sans); font-size: 0.78rem; line-height: 1.45; color: var(--ink-mid); }
.shot-label {
  display: block; font-size: 0.625rem; font-weight: 600;
  letter-spacing: .11em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 3px;
}

/* iPad: a bezel and a hairline edge, turned like the phones. */
.tablet { margin: 52px 0 0; max-width: 480px; perspective: 1600px; }
.tablet-body {
  --p: 0;
  padding: 3.4%; border-radius: 6.6% / 5%; background: #0b0c0e;
  box-shadow: 0 0 0 1.5px #44474d, 0 0 0 3px #1c1e22;
  transform: rotateY(calc((var(--ry0) + var(--p) * -8) * 1deg)) rotateX(calc(var(--p) * 5deg));
}
.tablet-body img { display: block; width: 100%; height: auto; border-radius: 3.4% / 2.6%; }

.aside-note {
  margin: 28px 0 0; padding: 2px 0 2px 14px; max-width: 54ch;
  border-left: 2px solid var(--rule-strong);
  font-family: var(--sans); font-size: 0.875rem; line-height: 1.55; color: var(--ink-mid);
}
.cov-guides { margin-top: 30px; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .phone::after { background: radial-gradient(closest-side, rgba(0, 0, 0, .6), transparent); }
}
:root[data-theme='dark'] .phone::after { background: radial-gradient(closest-side, rgba(0, 0, 0, .6), transparent); }

/* ---------- difficulty limits ---------- */

.level-split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 250px);
  gap: 40px; align-items: start; margin-top: 30px;
}
.ladder { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.ladder-step {
  display: grid; grid-template-columns: 96px 112px minmax(0, 1fr); gap: 4px 14px;
  align-items: baseline; padding: 15px 0; border-bottom: 1px solid var(--rule);
  font-family: var(--sans); font-size: 0.875rem; line-height: 1.45; color: var(--ink-mid);
}
.ladder-step b { color: var(--ink); font-weight: 600; }
.ladder-marks { display: flex; gap: 3px; align-self: center; }
.ladder-mark { width: 16px; height: 4px; flex: none; }
.ladder-mark--blue { background: var(--piste-blue); }
.ladder-mark--red { background: var(--piste-red); }
.ladder-mark--black { background: var(--piste-black); }
/* A ski route is drawn dashed on the map, a touring line dotted. */
.ladder-mark--route { background: repeating-linear-gradient(90deg, var(--piste-red) 0 5px, transparent 5px 8px); }
.ladder-mark--all { background: repeating-linear-gradient(90deg, var(--ink-mid) 0 2px, transparent 2px 5px); }
.level-split .phone { width: min(100%, 230px); justify-self: center; }

/* ---------- the village ---------- */

/* Where the line ends: the closing call to action, on the same inverted block
   the resort pages close on, and — once the script has watched the reader come
   down the page — the same summary the app shows at the end of a day. */
.finale {
  background: var(--ink); color: var(--paper);
  padding: clamp(56px, 8vw, 100px) var(--gutter) clamp(52px, 7vw, 88px);
  --fp-soft: color-mix(in srgb, var(--paper) 62%, transparent);
  --fp-rule: color-mix(in srgb, var(--paper) 18%, transparent);
}
.finale-inner { max-width: 1180px; margin: 0 auto; }
.finale-kicker {
  margin: 0; font-family: var(--sans); font-size: 0.6875rem; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--fp-soft);
}
.finale h2 {
  margin: 12px 0 14px; font-family: var(--serif); font-weight: 400;
  font-size: clamp(2rem, 5.2vw, 3.5rem); line-height: 1.05; letter-spacing: -0.025em;
}
.finale-lede { margin: 0; max-width: 54ch; font-size: 1.0625rem; color: var(--fp-soft); }

.finale-day {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 30px 48px; align-items: center;
  margin: 38px 0 0; padding: 30px 0; border-top: 1px solid var(--fp-rule); border-bottom: 1px solid var(--fp-rule);
}
.finale-day[hidden] { display: none; }
.finale-ring { display: flex; align-items: center; gap: 20px; }
.finale-ring svg { width: 112px; height: 112px; transform: rotate(-90deg); flex: none; }
.ring-track, .ring-fill { fill: none; stroke-width: 7; }
.ring-track { stroke: var(--fp-rule); }
.ring-fill { stroke: var(--paper); stroke-linecap: round; stroke-dasharray: 0 100; transition: stroke-dasharray 1.4s cubic-bezier(.3, .1, .2, 1); }
.finale-ring p { margin: 0; display: flex; flex-direction: column; font-family: var(--sans); font-size: 0.875rem; color: var(--fp-soft); line-height: 1.35; }
.finale-ring b { font-size: 2rem; font-weight: 600; color: var(--paper); line-height: 1.1; }
.finale-was { font-size: 0.75rem; }

.finale-new { margin: 0 0 12px; font-family: var(--sans); font-size: 1.125rem; color: var(--fp-soft); }
.finale-new b { font-size: 1.5rem; color: var(--paper); font-weight: 600; }
.finale-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.finale-chips li {
  display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px 5px 9px;
  border: 1px solid var(--fp-rule); font-family: var(--sans); font-size: 0.75rem; font-weight: 600;
}
.finale-chips i { width: 8px; height: 8px; border-radius: 50%; background: var(--g); box-shadow: 0 0 0 1.5px var(--paper); }
.finale-chips .is-locked { color: var(--fp-soft); border-style: dashed; }
.finale-chips .is-locked i { background: transparent; }
.finale-chips li[data-grade='blue'] { --g: var(--piste-blue); }
.finale-chips li[data-grade='red'] { --g: var(--piste-red); }
.finale-chips li[data-grade='black'] { --g: var(--piste-black); }

.finale-stats {
  grid-column: 1 / -1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0; border-top: 1px solid var(--fp-rule); padding-top: 22px;
}
.finale-stats div { padding-right: 18px; margin-right: 18px; border-right: 1px solid var(--fp-rule); }
.finale-stats div:last-child { border-right: 0; margin-right: 0; }
.finale-stats dt {
  font-family: var(--sans); font-size: 0.625rem; font-weight: 600; letter-spacing: .11em;
  text-transform: uppercase; color: var(--fp-soft); margin-bottom: 4px;
}
.finale-stats dd { margin: 0; font-size: 1.625rem; line-height: 1.1; white-space: nowrap; }
.finale-stats .unit { color: var(--fp-soft); }
.finale-note {
  grid-column: 1 / -1; margin: 0; font-family: var(--sans); font-size: 0.8125rem;
  line-height: 1.5; color: var(--fp-soft); max-width: 70ch;
}

.finale-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 18px; margin-top: 34px; }
.resort .btn-lift {
  display: inline-flex; align-items: center; gap: 10px; padding: 12px 22px;
  border: 1px solid var(--fp-rule); color: var(--paper); text-decoration: none;
  font-family: var(--sans); font-size: 0.9375rem; font-weight: 600;
}
.resort .btn-lift:hover { border-color: var(--paper); }
/* A chairlift in three strokes: the cable, the hanger, the chair. */
.btn-lift i { position: relative; width: 20px; height: 14px; flex: none; }
.btn-lift i::before {
  content: ''; position: absolute; left: 0; right: 0; top: 3px;
  border-top: 1.5px solid currentColor; transform: rotate(-16deg);
}
.btn-lift i::after {
  content: ''; position: absolute; left: 8px; top: 4px; width: 6px; height: 8px;
  border-left: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
}

/* ---------- the two-routes figure ---------- */

/* Three cells divided by hairlines, the way the metric grid on a resort page
   divides its figures. Explicit columns rather than auto-fit: with auto-fit an
   842px column fits two cells, and the third wrapped to a half-width orphan
   with a hole beside it. Three or one, never two-and-a-bit. */
.routefig { margin: 32px 0 0; }
.rf-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--rule); border-left: 1px solid var(--rule);
}
@media (max-width: 880px) { .rf-grid { grid-template-columns: minmax(0, 1fr); } }
.rf-cell {
  border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: 18px 20px 20px; min-width: 0;
}
.rf-head {
  margin: 0 0 6px; font-family: var(--sans); font-size: 0.6875rem; font-weight: 600;
  letter-spacing: .11em; text-transform: uppercase; color: var(--ink-soft);
}
.rf-cell svg { display: block; width: 100%; height: auto; }
.rf-note {
  margin: 4px 0 0; font-family: var(--sans); font-size: 0.8125rem; line-height: 1.5;
  color: var(--ink-mid); max-width: 40ch;
}

/* The unlit network stays legible but recedes; the chosen route is the only
   thing in full colour, which is the entire point of the pair. */
.rf-edge { fill: none; stroke: var(--rule-strong); stroke-width: 1.5; }
.rf-casing { fill: none; stroke: var(--paper); stroke-width: 11; stroke-linecap: round; stroke-linejoin: round; }
.rf-run { fill: none; stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
.rf-run--blue { stroke: var(--piste-blue); }
.rf-run--red { stroke: var(--piste-red); }
.rf-run--black { stroke: var(--piste-black); }
.rf-node { fill: var(--paper); stroke: var(--rule-strong); stroke-width: 1.5; }
.rf-node--end { fill: var(--ink); stroke: var(--paper); stroke-width: 2.5; }
/* 13px in a 336-wide viewBox, because at three across the panel renders about
   240px wide and 11px arrived as 8. */
.rf-text {
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  letter-spacing: .04em; fill: var(--ink-soft);
}
/* A run that is shut today: the edge recedes further than an unused one and
   takes a cross, so "not chosen" and "not available" never read the same. */
.rf-edge--shut { stroke-dasharray: 4 4; opacity: .45; }
.rf-shut path { stroke: var(--ink-mid); stroke-width: 2; stroke-linecap: round; fill: none; }

.routefig .ribbon-legend { margin-top: 16px; }

/* ---------- spec list ---------- */

.speclist {
  list-style: none; margin: 26px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0 32px; border-top: 1px solid var(--rule);
}
/* Names only: every one of these has a section above that explains it. */
.speclist li {
  padding: 11px 0; border-bottom: 1px solid var(--rule);
  font-family: var(--sans); font-size: 0.9rem; font-weight: 600; color: var(--ink);
}

/* ---------- coverage ---------- */

.cov-note { margin: 10px 0 0; }
.cov-guide-list { margin: 14px 0 24px; border-top: 1px solid var(--rule); }
.cov-guide-list p { margin: 0; padding: 10px 0; border-bottom: 1px solid var(--rule); font-family: var(--serif); font-size: 1.0625rem; line-height: 1.6; color: var(--ink-mid); }
.cov-guide-list a { font-weight: 600; }
.cov-guide-list .cov-guide-country { display: block; font-family: var(--sans); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mid); text-decoration: none; margin-bottom: 2px; }
.cov-guide-list .cov-guide-country:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.idx-table td.cov-name a { color: var(--ink); text-decoration: none; font-weight: 600; }
.idx-table td.cov-name a:hover { text-decoration: underline; text-underline-offset: 3px; }
.cov-plain { color: var(--ink-mid); }

/* ---------- responsive ---------- */

/* Below the width the rail drops out on a resort page, the corridor narrows to
   a gutter on the left of every section and the signs lose their names — the
   sticky section strip carries those. The line keeps the gutter, swinging out
   across each section break and back. The chip leaves the puck, which has no
   room beside it here, and docks at the foot of the screen. */
@media (max-width: 1039px) {
  .descent { --corridor: 32px; --corridor-gap: 14px; }
  .run--r, .run--l { grid-template-columns: var(--corridor) minmax(0, 1fr); }
  .run--r .run-gate, .run--l .run-gate { grid-column: 1; }
  .run--r .run-body, .run--l .run-body { grid-column: 2; }
  .run--r .gate, .run--l .gate { left: 1px; right: auto; top: 5px; }
  .gate-text { display: none; }
  .gate-sign { width: 30px; height: 30px; font-size: 0.75rem; }
  .doc--descent .sec { padding: 60px 0; }
  .dl-chip {
    position: fixed; top: auto; left: 12px; bottom: calc(14px + env(safe-area-inset-bottom));
    transform: none !important; z-index: 55;
  }
  body.has-appbar .dl-chip { bottom: calc(84px + env(safe-area-inset-bottom)); }
  /* Lingers a moment after the reader stops, then gets out of the text. */
  .dl-chip { transition: opacity .35s .9s; }
  .dl-chip.is-on { transition-delay: 0s; }
}

/* The scene becoming a band at the foot of the hero below 860px is in
   resort.css, which owns the hero — it is the same fix for the same reason on
   both pages. Only the padding under the headline is home's own: the rule there
   is (0,1,0) and the base rule above is (0,2,0), so the generic value has to be
   restated here to clear the band. */
@media (max-width: 859px) {
  .rhero--home .rhero-inner { padding-bottom: clamp(215px, 37vh, 310px); }
  .hero-lede { max-width: none; }
  .hero-key { margin-top: 24px; }
  .hero-key .hero-cue { margin-left: 0; flex-basis: 100%; }
}

@media (max-width: 760px) {
  .level-split { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .finale-day { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 700px) {
  .hero-kicker { gap: 8px; margin-bottom: 20px; }
  .hero-actions { gap: 10px 12px; margin-top: 26px; }
  .rhero--home .btn-solid, .rhero--home .btn-ghost { padding: 12px 18px; font-size: 0.875rem; }
  /* Phones side by side are too small to read on a phone, so a stage becomes
     a strip that scrolls inside the column — never the page — and the labels
     move onto the glass, where the strip cannot clip them. */
  .stage {
    justify-content: flex-start; gap: 22px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scrollbar-width: none; padding: 16px 0 38px;
  }
  .stage::-webkit-scrollbar { display: none; }
  .stage .phone, .stage--pair .phone, .stage--three .phone {
    width: min(60vw, 230px); margin: 0; scroll-snap-align: center;
  }
  .stage--pair { padding-left: 0; }
  .callout--l, .callout--r, .callout--in { left: 9%; right: auto; top: auto !important; bottom: 17%; }
  .speclist { gap: 0; }
  .rf-cell { padding: 15px 16px 17px; }
  .watches { gap: 12px; }
  .tablet { max-width: none; }
  .ladder-step { grid-template-columns: 96px minmax(0, 1fr); }
  .ladder-note { grid-column: 1 / -1; }
  .finale-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 18px; }
  .finale-stats div:nth-child(2) { border-right: 0; margin-right: 0; }
}
