/* E · Ghiaccio's tokens (web/src/styles/ice.css), carried over unchanged in meaning: dark cold
   glass, one signal cyan, `--hot` for "you are here" only, `--ageing` for what must not be leaned
   on (aged or simulated), IBM Plex Sans Condensed captions, IBM Plex Sans text, IBM Plex Mono figures (production's own). */
:root {
  --ice: 11, 22, 32;
  --void: #050c13;
  --glacier: #0e5c63;
  --signal: #22d3ee;
  --hot: #ff6a3d;
  --ageing: #e3ce8a;
  --ageing-rim: #d8c27a;
  --glass-read: rgba(var(--ice), 0.78);
  --glass-solid: #0b1620;
  --well: rgba(3, 9, 15, 0.42);
  --sheen: rgba(226, 246, 252, 0.3);
  --sheen-top: rgba(226, 246, 252, 0.5);
  --sheen-soft: rgba(226, 246, 252, 0.1);
  --rule: rgba(226, 246, 252, 0.13);
  --ink-1: #f2fbfd;
  --ink-2: #cde8ef;
  --ink-3: #9fb4c0;
  /* Risk indicator: green / amber / red, conservative, never "safe". */
  --risk-green: #4fbf7f;
  --risk-amber: #f0a43a;
  --risk-red: #e5484d;
  --display: 'IBM Plex Sans Condensed', 'Helvetica Neue', Arial, sans-serif;
  --ui: 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif;
  --mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;
  --r-pill: 999px;
  --r-sheet: 24px;
  --r-inset: 14px;
  --gutter: clamp(16px, 4vw, 48px);
  --wide: 1200px;
  --float-2:
    0 4px 14px -6px rgba(2, 8, 14, 0.78), 0 18px 48px -20px rgba(2, 8, 14, 0.95);
}
:root[data-em-theme='night'] {
  --sheen: rgba(226, 246, 252, 0.44);
  --sheen-top: rgba(226, 246, 252, 0.62);
  --rule: rgba(226, 246, 252, 0.17);
}

* {
  box-sizing: border-box;
}
[hidden] {
  display: none !important;
}
html {
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--void);
  color: var(--ink-1);
  font: 400 16px/1.6 var(--ui);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a {
  color: inherit;
}
img {
  display: block;
  max-width: 100%;
  height: auto;
}
button {
  font: inherit;
  color: inherit;
}
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}
h1,
h2,
h3 {
  font-family: var(--display);
  margin: 0;
  text-wrap: balance;
}
h2 {
  font-size: clamp(28px, 4.2vw, 46px);
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: -0.015em;
}
p {
  margin: 0;
}
.nw {
  white-space: nowrap;
}
.wrap {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.stamp,
.cap {
  font: 600 12px/1.4 var(--display);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.cap {
  color: var(--ink-3);
  letter-spacing: 0.14em;
}
.ageing {
  color: var(--ageing);
}
.sim {
  display: inline-block;
  font: 600 10px/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ageing);
  border: 1px solid var(--ageing-rim);
  border-radius: var(--r-pill);
  padding: 3px 7px 2px;
  vertical-align: 1px;
}

/* Only what the script makes work is hidden without it. */
html:not(.js) .needs-js {
  display: none !important;
}

.glass {
  background: var(--glass-read);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  backdrop-filter: blur(14px) saturate(1.1);
  border-radius: var(--r-sheet);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    inset 0 1px 0 var(--sheen-top),
    var(--float-2);
}
.glass-ring {
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--float-2);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 18px;
  border-radius: var(--r-pill);
  border: 0;
  background: rgb(var(--ice));
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    inset 0 1px 0 var(--sheen-top);
  font: 600 14px/1 var(--ui);
  text-decoration: none;
  cursor: pointer;
}
.pill:hover {
  box-shadow:
    inset 0 0 0 1px var(--sheen-top),
    inset 0 1px 0 var(--sheen-top);
}
.pill-signal {
  color: var(--signal);
}
.pill[aria-pressed='true'] {
  color: var(--void);
  background: var(--signal);
}

/* Bar */
.bar {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 5;
  padding-top: env(safe-area-inset-top, 0px);
}
.bar .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-block: 12px;
}
.brand {
  line-height: 0;
}
.brand img {
  height: clamp(36px, 5.5vw, 56px);
  width: auto;
  filter: drop-shadow(0 1px 10px rgba(5, 12, 19, 0.6));
}

/* Hero. Three layers in one tall section: the stage pinned at the back, the copy scrolling over
   it with its own dark wash (so the wash leaves with the words), and the season read-out pinned
   on top. The run below the copy is the scroll the season and the climb are told over. */
.hero {
  position: relative;
  isolation: isolate;
}
.hero-pin,
.hero-hud-pin {
  position: sticky;
  top: 0;
  height: 100svh;
}
.hero-pin {
  z-index: 0;
  overflow: hidden;
}
.hero-hud-pin {
  z-index: 4;
  margin-top: -100svh;
  pointer-events: none;
}
.hero-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  touch-action: pan-y;
}
.hero-still,
.hero-gl,
.hero-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.hero-still {
  object-fit: cover;
  object-position: 62% 40%;
}
.hero-gl,
.hero-overlay {
  opacity: 0;
  transition: opacity 0.6s ease;
}
.hero-overlay {
  pointer-events: none;
}
.hero.gl-ready .hero-gl,
.hero.gl-ready .hero-overlay {
  opacity: 1;
}
.hero.gl-ready .hero-still {
  visibility: hidden;
}
.hero-stage::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(5, 12, 19, 0.7) 0%,
    rgba(5, 12, 19, 0) 16%,
    rgba(5, 12, 19, 0) 72%,
    var(--void) 100%
  );
}
.hero-copy {
  position: relative;
  z-index: 1;
  margin-top: -100svh;
  min-height: 100svh;
  display: grid;
  gap: 18px;
  align-content: end;
  padding-block: 140px clamp(32px, 5vw, 56px);
  width: 100%;
  grid-template-columns: minmax(0, 1fr);
  pointer-events: none;
}
.hero-copy::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0 auto -240px 0;
  width: 100vw;
  pointer-events: none;
  margin-left: calc((100% - 100vw) / 2);
  /* Dark under the whole measure of the copy (40rem from its own left edge, at any width) so
     the small caption stays legible over the brightest winter snow and the relief's labels. */
  --copy-x: max(var(--gutter), calc((100vw - var(--wide)) / 2 + var(--gutter)));
  background: linear-gradient(
    90deg,
    rgba(5, 12, 19, 0.88) 0,
    rgba(5, 12, 19, 0.78) calc(var(--copy-x) + 30rem),
    rgba(5, 12, 19, 0.55) calc(var(--copy-x) + 40rem),
    rgba(5, 12, 19, 0) calc(var(--copy-x) + 40rem + 180px)
  );
  /* The wash leaves with the words, and fades out below them rather than ending as a box. */
  -webkit-mask-image: linear-gradient(
    180deg,
    #000 calc(100% - 240px),
    transparent
  );
  mask-image: linear-gradient(180deg, #000 calc(100% - 240px), transparent);
}
.hero-copy > * {
  pointer-events: auto;
  max-width: 40rem;
}
/* The opening still: production's hero, the photo it opened on, under the headline. It is one
   whole screen at any size: the copy stands at its foot and the cue to scroll under the copy, so
   both are on the first screen however short it is. */
.intro {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.intro-img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 40%;
}
.intro::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(
      90deg,
      rgba(10, 24, 34, 0.86) 0%,
      rgba(10, 24, 34, 0.72) 30%,
      rgba(10, 24, 34, 0.35) 50%,
      rgba(10, 24, 34, 0) 72%
    ),
    linear-gradient(
      180deg,
      rgba(10, 24, 34, 0.78) 0%,
      rgba(10, 24, 34, 0.3) 12%,
      rgba(10, 24, 34, 0.05) 24%,
      rgba(10, 24, 34, 0.1) 45%,
      rgba(10, 24, 34, 0.82) 78%,
      var(--void) 100%
    );
}
.intro .wrap {
  width: 100%;
  padding-block: 120px calc(10px + env(safe-area-inset-bottom, 0px));
  display: grid;
  gap: 22px;
}
.intro .wrap > * {
  max-width: 40rem;
}
/* The way down to the climb is the opening's first thing to do (the owner, 2026-10-12): two
   chevrons falling in a ring of glass, in the middle of the screen's foot, and no words. */
.intro .wrap > .scroll-cue {
  justify-self: center;
  max-width: none;
  margin-top: clamp(6px, 3svh, 32px);
  width: 72px;
  height: 72px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #fff;
  background: rgba(var(--ice), 0.42);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow:
    inset 0 0 0 1.5px rgba(242, 251, 253, 0.62),
    0 10px 30px rgba(2, 8, 14, 0.5);
}
.scroll-cue svg {
  width: 36px;
  height: 36px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: cue-fall 1.9s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
.scroll-cue svg path:first-child {
  opacity: 0.45;
}
.scroll-cue:hover {
  background: rgba(var(--ice), 0.62);
  box-shadow:
    inset 0 0 0 1.5px #fff,
    0 10px 30px rgba(2, 8, 14, 0.5);
}
@keyframes cue-fall {
  0%,
  100% {
    transform: translateY(-3px);
  }
  50% {
    transform: translateY(5px);
  }
}
.hero-run {
  height: calc(var(--pin-screens, 2.2) * 100svh);
}
.hero h1,
.intro h1 {
  font-size: clamp(44px, 7.6vw, 100px);
  line-height: 0.94;
  font-weight: 700;
  letter-spacing: -0.03em;
  max-width: 10ch;
  text-shadow: 0 2px 30px rgba(5, 12, 19, 0.6);
}
.lede {
  font-size: clamp(16px, 1.7vw, 19px);
  color: var(--ink-2);
  max-width: 34rem;
  text-shadow: 0 1px 14px rgba(5, 12, 19, 0.8);
}
.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
}
/* Google's own dark button, at the opening and at the close alike (the owner, 2026-10-14). */
.google {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 0 16px 0 12px;
  border-radius: var(--r-pill);
  background: #131314;
  color: #e3e3e3;
  text-decoration: none;
  font: 500 14px/1 var(--ui);
  box-shadow: inset 0 0 0 1px #8e918f;
}
.google:hover {
  background: #1e1f20;
}
.google svg {
  width: 18px;
  height: 18px;
  flex: none;
}
.invite {
  font-size: 14px;
  color: var(--ink-3);
}
.plate-caption {
  font: 400 11px/1.6 var(--mono);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-top: 1px solid var(--rule);
  padding-top: 10px;
}
.plate-caption .notice {
  display: block;
  text-transform: none;
  letter-spacing: 0.02em;
  margin-top: 4px;
}
.js .nojs-only {
  display: none;
}
.sim-note {
  font-size: 13px;
  color: var(--ink-3);
  max-width: 34rem;
}

/* The season read-out: which morning is on the relief, and where it sits in the season. */
.season-hud {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(24px, 4vw, 44px);
  width: min(400px, calc(100% - 2 * var(--gutter)));
  padding: 12px 16px 12px;
  display: grid;
  gap: 8px;
  pointer-events: auto;
}
.hud-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.hud-date {
  font: 600 17px/1.1 var(--mono);
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hud-strip {
  position: relative;
  height: 34px;
  touch-action: none;
  cursor: ew-resize;
  border-radius: 8px;
}
.hud-months {
  position: absolute;
  inset: 0;
  display: flex;
}
.hud-months span {
  flex: 1;
  display: grid;
  place-items: end center;
  padding-bottom: 1px;
  font: 500 9.5px/1 var(--mono);
  color: var(--ink-3);
  text-transform: uppercase;
  border-left: 1px solid var(--rule);
}
.hud-months span:first-child {
  border-left: 0;
}
.hud-ticks {
  position: absolute;
  left: 0;
  right: 0;
  top: 3px;
  height: 16px;
}
.hud-ticks i {
  position: absolute;
  top: 0;
  width: 2px;
  height: 100%;
  margin-left: -1px;
  border-radius: 1px;
  background: rgba(226, 246, 252, 0.55);
}
.hud-ticks i.on {
  background: var(--ink-1);
  box-shadow: 0 0 0 2px rgba(226, 246, 252, 0.18);
}
.hud-thumb {
  position: absolute;
  left: 0;
  top: -2px;
  height: 24px;
  width: 2px;
  margin-left: -1px;
  background: var(--hot);
  border-radius: 2px;
  will-change: transform;
  box-shadow: 0 0 10px 1px rgba(255, 106, 61, 0.55);
}
/* While the copy's words pass where the read-out sits (app.js, measure), it steps aside. */
.season-hud {
  transition:
    opacity 0.25s ease,
    visibility 0s linear 0s;
}
.season-hud.yield {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.25s ease,
    visibility 0s linear 0.25s;
}
.hud-read {
  font-size: 12px;
  line-height: 1.35;
  color: var(--ink-2);
}
.hud-hint {
  font: 500 11px/1.3 var(--mono);
  color: var(--ink-3);
  letter-spacing: 0.02em;
}
.hero.touched .hud-hint {
  display: none;
}
/* The climb's clock, over the relief: the face is a window of the sky the climb is under (its
   colours and the sun's place are the relief's own, app.js setFace), the hands are Europe/Rome's
   time, and the pin is the climber's --hot. Pointer-transparent: the relief under it still turns. */
.climb-clock {
  --cc: 168px;
  position: absolute;
  right: var(--gutter);
  top: calc(clamp(16px, 3vw, 32px) + env(safe-area-inset-top, 0px));
  margin: 0;
  width: max-content;
  display: grid;
  justify-items: end;
  gap: 8px;
  pointer-events: none;
  transition:
    opacity 0.25s ease,
    visibility 0s linear 0s;
}
.climb-clock.yield {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.35s ease,
    visibility 0s linear 0.35s;
}
.cc-cap,
.cc-hint {
  transition: opacity 0.3s ease;
}
@media (max-width: 560px) {
  .climb-clock.opening .cc-cap,
  .climb-clock.opening .cc-hint {
    opacity: 0;
  }
} /* the headline passes under them */
.cc-face {
  width: var(--cc);
  height: var(--cc);
  overflow: visible;
  filter: drop-shadow(0 10px 26px rgba(2, 8, 14, 0.55));
}
.cc-rim {
  fill: none;
  stroke: rgba(226, 246, 252, 0.55);
  stroke-width: 2.2;
}
.cc-ridge {
  fill: #0d1a24;
  stroke: rgba(226, 246, 252, 0.28);
  stroke-width: 0.9;
  stroke-linejoin: round;
}
.cc-sun {
  fill: #fff6df;
  stroke: rgba(255, 196, 120, 0.7);
  stroke-width: 1.2;
}
.cc-stars circle {
  fill: #f2fbfd;
}
.cc-ticks line {
  stroke: rgba(242, 251, 253, 0.55);
  stroke-width: 1;
  stroke-linecap: round;
}
.cc-ticks line.h {
  stroke: #f2fbfd;
  stroke-width: 2.6;
}
.cc-ticks line.q {
  stroke-width: 3.6;
}
.cc-hand path {
  fill: #f2fbfd;
  stroke: rgba(5, 12, 19, 0.7);
  stroke-width: 0.9;
  stroke-linejoin: round;
}
.cc-pin {
  fill: var(--hot);
  stroke: #050c13;
  stroke-width: 1.6;
}
.cc-pin-dot {
  fill: rgba(255, 226, 214, 0.95);
}
.cc-cap {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 5px 12px 6px;
  border-radius: var(--r-pill);
  background: rgba(var(--ice), 0.72);
  box-shadow: inset 0 0 0 1px var(--sheen-soft);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  white-space: nowrap;
}
.cc-day {
  font: 600 12px/1.2 var(--mono);
  color: var(--ink-1);
  letter-spacing: 0.02em;
}
.cc-what {
  font: 600 12.5px/1.2 var(--display);
  color: var(--ink-2);
}
.cc-what::before {
  content: '·';
  margin-right: 8px;
  color: var(--ink-3);
}
.cc-hint {
  margin: 0;
  padding: 4px 10px;
  border-radius: 10px;
  background: rgba(var(--ice), 0.55);
  display: grid;
  justify-items: center;
  font: 500 11px/1.4 var(--mono);
  color: var(--ink-2);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.hero.touched .cc-hint {
  display: none;
}

/* Season strip */
.season {
  padding: 14px 16px 12px;
  display: grid;
  gap: 8px;
  max-width: 30rem;
}
.season-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.season-strip {
  position: relative;
  height: 48px;
  touch-action: none;
  cursor: ew-resize;
  border-radius: var(--r-inset);
}
.season-months {
  position: absolute;
  inset: 0;
  display: flex;
}
.season-months span {
  flex: 1;
  display: grid;
  place-items: end center;
  padding-bottom: 4px;
  font: 500 10.5px/1 var(--mono);
  color: var(--ink-3);
  text-transform: uppercase;
  border-left: 1px solid var(--rule);
}
.season-months span:first-child {
  border-left: 0;
}
.season-line {
  position: absolute;
  left: 0;
  right: 0;
  top: 4px;
  height: 22px;
}
.season-line i {
  position: absolute;
  inset: 0;
  display: block;
}
.season-line svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}
.season-thumb {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--signal);
  border-radius: 2px;
  box-shadow: 0 0 0 4px rgba(34, 211, 238, 0.14);
  will-change: transform;
}
.season-thumb::after {
  content: '';
  position: absolute;
  left: 50%;
  top: -5px;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  background: var(--signal);
}
.season-read {
  font-size: 13.5px;
  color: var(--ink-2);
}
.season-read b {
  font: 600 13.5px/1 var(--mono);
  color: var(--ink-1);
}

.section-head {
  display: grid;
  gap: 14px;
  margin-bottom: clamp(26px, 4vw, 44px);
  max-width: 46rem;
}
.section-head > p:not(.stamp) {
  color: var(--ink-3);
}

/* The instrument */
.line {
  padding-block: clamp(64px, 10vw, 120px);
}
.instrument {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(18px, 2.6vw, 36px);
  align-items: start;
}
.map-col {
  display: grid;
  gap: 12px;
  position: relative;
  align-content: start;
}
.map-frame {
  margin: 0;
  display: grid;
  gap: 8px;
}
/* The frame of the draw screen's film (draw-film.js): the app at 360 x 640, scaled to the frame. */
.map-view {
  position: relative;
  width: 100%;
  max-width: 400px;
  margin-inline: auto;
  border-radius: 30px;
  overflow: hidden;
  background: #0b1620;
  aspect-ratio: 360 / 640;
}
.map-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.map-frame.ready .map-still {
  visibility: hidden;
}
.df-screen {
  position: absolute;
  left: 0;
  top: 0;
  width: 360px;
  height: 640px;
  transform-origin: 0 0;
  transform: scale(var(--df-k, 1));
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
  font: 400 14px/1.4 var(--ui);
  color: var(--ink-1);
  --df-glass: rgba(var(--ice), 0.86);
  --df-float:
    0 2px 8px -2px rgba(2, 8, 14, 0.6), 0 10px 26px -14px rgba(2, 8, 14, 0.9);
}
.df-gl,
.df-ink {
  position: absolute;
  inset: 0;
  width: 360px;
  height: 640px;
}
/* The app's chrome, by its own measures (web/src/styles/draw.css): 10 px from the edges, 44 px targets. */
.df-top {
  position: absolute;
  left: 10px;
  right: 10px;
  top: 10px;
  display: flex;
  gap: 8px;
}
.df-round {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--df-glass);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--df-float);
  font: 700 14px/1 var(--display);
}
.df-round svg,
.df-icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.df-round svg .fill {
  fill: currentColor;
  stroke: none;
}
.df-north text {
  font: 700 8.5px/1 var(--display);
  fill: currentColor;
  stroke: none;
  text-anchor: middle;
}
.df-north path {
  transform-origin: 12px 7.5px;
}
.df-3d.on {
  background: var(--glacier);
  box-shadow:
    inset 0 0 0 1px var(--signal),
    var(--df-float);
}
.df-search {
  flex: 1;
  height: 44px;
  border-radius: 22px;
  padding: 0 18px;
  display: flex;
  align-items: center;
  background: var(--df-glass);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--df-float);
  font: 500 15px/1 var(--display);
  letter-spacing: 0.02em;
  color: var(--ink-3);
}
.df-status {
  position: absolute;
  left: 62px;
  right: 66px;
  top: 62px;
  min-height: 30px;
  padding: 6px 14px;
  border-radius: 22px;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--df-glass);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--df-float);
  font-size: 12.5px;
  line-height: 1.3;
  opacity: 0;
}
.df-spinner {
  flex: none;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 2px solid rgba(34, 211, 238, 0.25);
  border-top-color: var(--signal);
  animation: df-spin 0.8s linear infinite;
}
@keyframes df-spin {
  to {
    transform: rotate(360deg);
  }
}
.df-tools {
  position: absolute;
  right: 10px;
  top: 70px;
  display: grid;
  gap: 9px;
}
.df-bottom {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.df-ribbon {
  background: var(--df-glass);
  border-radius: 20px;
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--df-float);
  padding: 9px 14px 8px;
  opacity: 0;
}
.df-ribbon-figs,
.df-sheet-figs {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font: 600 14px/1 var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.df-ribbon-figs span,
.df-sheet-figs span {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  white-space: nowrap;
}
.df-ribbon-figs small,
.df-sheet-figs small {
  font: 500 10px/1 var(--ui);
  color: var(--ink-3);
  letter-spacing: 0;
}
.df-ribbon-figs i,
.df-sheet-figs i {
  font-style: normal;
  color: var(--signal);
  margin-right: 2px;
}
.df-ribbon-figs i.down {
  color: #eaf4fa;
}
.df-ribbon-plot {
  display: block;
  width: 100%;
  height: 46px;
  margin-top: 7px;
  overflow: visible;
}
.df-ribbon-plot text {
  font: 10px var(--mono);
  fill: var(--ink-2);
}
.df-dock {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px;
  border-radius: var(--r-sheet);
  background: var(--df-glass);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    inset 0 1px 0 var(--sheen-top),
    var(--df-float);
}
.df-segmented {
  display: flex;
  padding: 3px;
  border-radius: var(--r-pill);
  background: var(--well);
  box-shadow: inset 0 0 0 1px var(--sheen-soft);
}
.df-segmented b {
  min-height: 38px;
  padding: 0 10px;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  font: 600 13px/1 var(--display);
  color: var(--ink-3);
}
.df-segmented b.on {
  background: var(--ink-1);
  color: var(--glass-solid);
}
.df-icon {
  flex: none;
  width: 32px;
  height: 44px;
  display: grid;
  place-items: center;
}
.df-icon svg {
  width: 21px;
  height: 21px;
  stroke-width: 1.9;
}
.df-icon.off {
  opacity: 0.3;
}
.df-done {
  margin-left: auto;
  min-height: 40px;
  padding: 0 16px;
  display: inline-grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: var(--glacier);
  box-shadow: inset 0 0 0 1px var(--signal);
  font: 600 14px/1 var(--display);
  opacity: 0.38;
}
.df-done.on {
  opacity: 1;
}
.df-sheet {
  position: absolute;
  left: 0;
  right: 0;
  top: 484px;
  bottom: 0;
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  background: var(--glass-solid);
  box-shadow:
    inset 0 1px 0 var(--sheen-top),
    inset 0 0 0 1px var(--sheen-soft),
    0 -10px 30px -12px rgba(2, 8, 14, 0.9);
  transform: translateY(100%);
  padding: 0 16px;
}
.df-grab {
  height: 28px;
  display: grid;
  place-items: center;
}
.df-grab i {
  width: 38px;
  height: 4px;
  border-radius: 2px;
  background: var(--sheen);
}
.df-sheet-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0 10px;
}
.df-sheet-head > div {
  flex: 1;
  min-width: 0;
  display: grid;
  gap: 2px;
}
.df-sheet-head b {
  font: 600 20px/1.2 var(--display);
  letter-spacing: -0.01em;
}
.df-sheet-head span[data-df-sub] {
  font-size: 11.5px;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.df-sheet-head span[data-df-sub].busy {
  color: var(--signal);
}
.df-sheet-figs {
  padding: 14px 0 0;
  border-top: 1px solid var(--rule);
  font-size: 17px;
}
/* The finger: a fingertip's patch on the glass, larger and fainter while it is off it. */
.df-finger,
.df-ripple {
  position: absolute;
  left: -23px;
  top: -23px;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  opacity: 0;
  will-change: transform, opacity;
}
.df-finger {
  background: radial-gradient(
    circle at 50% 42%,
    rgba(255, 255, 255, 0.5),
    rgba(255, 255, 255, 0.24) 62%,
    rgba(255, 255, 255, 0.34)
  );
  border: 2px solid rgba(255, 255, 255, 0.95);
  box-shadow:
    0 0 0 1.5px rgba(5, 13, 20, 0.5),
    0 8px 18px -4px rgba(2, 8, 14, 0.55);
}
.df-ripple {
  border: 2px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 0 1px rgba(5, 13, 20, 0.35);
}
/* The four steps of the film: the one playing is lit, and any of them starts it from there. */
.film-steps {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  width: 100%;
  max-width: 400px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  counter-reset: step;
}
.film-steps button {
  width: 100%;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  border-radius: var(--r-pill);
  background: rgba(var(--ice), 0.9);
  box-shadow: inset 0 0 0 1px var(--sheen-soft);
  color: var(--ink-3);
  font: 600 13px/1 var(--display);
  letter-spacing: 0.02em;
  cursor: pointer;
  counter-increment: step;
}
.film-steps button::before {
  content: counter(step) ' ';
  font: 500 11px/1 var(--mono);
  opacity: 0.7;
}
.film-steps button.on {
  color: var(--void);
  background: var(--ink-1);
  box-shadow: none;
}
.map-cap {
  text-align: center;
  max-width: 400px;
  margin-inline: auto;
}
.map-cap {
  font: 500 12px/1.4 var(--ui);
  color: var(--ink-2);
}
.read-col {
  display: grid;
  gap: 14px;
}
.figures {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: 6px 28px;
  margin: 0;
}
.figures div {
  display: grid;
  gap: 2px;
}
.figures dt {
  font: 600 10.5px/1.2 var(--display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.figures dd {
  margin: 0;
  font: 500 clamp(22px, 2.6vw, 30px)/1.1 var(--mono);
  font-variant-numeric: tabular-nums;
}
.figures small {
  font-size: 0.5em;
  color: var(--ink-3);
  margin-left: 3px;
}
.profile {
  margin: 0;
  padding: 10px 10px 12px;
  display: grid;
  gap: 8px;
}
.profile-still {
  width: 100%;
  border-radius: var(--r-inset);
}
.profile-canvas {
  width: 100%;
  height: 210px;
  display: none;
  border-radius: var(--r-inset);
}
.profile.ready .profile-canvas {
  display: block;
}
.profile.ready .profile-still {
  display: none;
}
/* The profile's key: the three states, in the fills the canvas draws them with (app.js, STATE). */
.profile-key {
  display: grid;
  gap: 8px;
  padding-inline: 4px;
}
.profile-key ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  font: 500 14px/1.3 var(--display);
  color: var(--ink-1);
}
.profile-key li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.profile-key li::before {
  content: '';
  width: 14px;
  height: 14px;
  border-radius: 4px;
  background: var(--st);
}
.profile-key .st-snow {
  --st: rgba(226, 242, 248, 0.85);
}
.profile-key .st-bare {
  --st: rgba(150, 126, 98, 0.8);
}
.profile-key .st-glacier {
  --st: rgba(31, 182, 200, 0.85);
}
.profile-key .src {
  margin-top: 0;
}
.dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: none;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.06);
}
.dot-green {
  background: var(--risk-green);
}
.dot-amber {
  background: var(--risk-amber);
}
.dot-red {
  background: var(--risk-red);
}
.principle {
  font-size: 13px;
  color: var(--ink-1);
  border-top: 1px solid var(--rule);
  padding-top: 8px;
}

/* Screens */
/* The Mont Blanc takes the whole window, as the opening does: the still, the map over it once it
   has drawn, and the section's words on the dark sky above the summits. The words let a pointer
   through, so the map under them still answers. */
.mb3d-frame {
  position: relative;
  isolation: isolate;
  margin: 0;
  height: 100vh;
  height: 100svh;
  min-height: 520px;
  overflow: hidden;
  background: #0b1620;
}
.mb3d-still,
.mb3d-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.mb3d-still {
  object-fit: cover;
  object-position: 50% 0;
}
.mb3d-off .mb3d-map {
  display: none;
}
.mb3d-head {
  position: absolute;
  z-index: 2;
  inset: 0 0 auto 0;
  pointer-events: none;
  padding-block: clamp(48px, 8svh, 88px) 56px;
  background: linear-gradient(
    180deg,
    var(--void) 0,
    rgba(5, 12, 19, 0.86) 34%,
    rgba(8, 17, 26, 0.6) 72%,
    rgba(11, 22, 32, 0) 100%
  );
}
.mb3d-head .section-head {
  margin-bottom: 0;
}
.mb3d-head .section-head > p {
  color: var(--ink-2);
}
.mb3d-frame::after {
  content: '';
  position: absolute;
  z-index: 1;
  inset: auto 0 0 0;
  height: 22%;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(5, 12, 19, 0) 0, var(--void) 100%);
}
.mb3d-frame figcaption {
  position: absolute;
  z-index: 2;
  left: var(--gutter);
  right: var(--gutter);
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  font: 400 12.5px/1.5 var(--ui);
  color: var(--ink-2);
  text-shadow: 0 1px 10px rgba(5, 12, 19, 0.9);
  pointer-events: none;
}
.mb3d .maplibregl-ctrl-bottom-right {
  bottom: 44px;
}
.mb3d .maplibregl-ctrl-attrib {
  font: 400 10px/1.4 var(--mono);
}
/* The app's own place names (placeLabels/typeA.ts, paint.ts INKS.light): same faces, grades, inks and halo. */
.mb3d {
  --mb-text: #f5fbfd;
  --mb-soft: rgba(226, 240, 246, 0.86);
  --mb-ice: #8fddf2;
  --mb-water: #a9d8f2;
  --mb-halo: rgba(5, 13, 20, 0.62);
}
.mb-name {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font: 500 11px/1.15 var(--display);
  color: var(--mb-soft);
  white-space: nowrap;
  pointer-events: none;
}
.mb-name .mb-text,
.mb-name .mb-ele {
  paint-order: stroke fill;
  -webkit-text-stroke: 2.6px var(--mb-halo);
  text-shadow: 0 0 4px var(--mb-halo);
}
.mb-name .mb-ele {
  font: 500 9.5px/1 var(--mono);
  letter-spacing: 0.04em;
  order: 1;
}
.mb-name .mb-mark {
  order: 2;
  display: block;
  margin-top: 2px;
  overflow: visible;
  filter: drop-shadow(0 0 2px var(--mb-halo));
}
.mb-name .mb-mark .ring {
  fill: rgba(245, 251, 253, 0.2);
  stroke: currentColor;
  stroke-width: 1;
}
.mb-name.mb-hide {
  visibility: hidden;
} /* not opacity: MapLibre writes that inline on a marker behind a ridge */
.mb-peak.mb-g1 {
  color: var(--mb-text);
}
.mb-peak.mb-g1 .mb-text {
  font: 700 15px/1.1 var(--display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.mb-peak.mb-g1 .mb-ele {
  font-size: 10.5px;
}
.mb-peak.mb-g2 {
  color: var(--mb-text);
}
.mb-peak.mb-g2 .mb-text {
  font-weight: 600;
  font-size: 14px;
}
.mb-peak.mb-g2 .mb-ele {
  font-size: 10px;
}
.mb-peak.mb-g3 {
  color: var(--mb-text);
}
.mb-peak.mb-g3 .mb-text {
  font-size: 12px;
}
.mb-peak.mb-g4 .mb-text {
  font-size: 11px;
}
.mb-glacier {
  color: var(--mb-ice);
  font-style: italic;
  letter-spacing: 0.03em;
}
.mb-glacier.mb-g2 {
  font-size: 11.5px;
}
.mb-glacier.mb-g4 {
  font-size: 10px;
}
.mb-lake {
  color: var(--mb-water);
  font-style: italic;
  font-size: 10px;
}
.mb-lake.mb-g3 {
  font-size: 11px;
}
.mb-town {
  color: var(--mb-text);
  font: italic 600 13px/1.15 var(--display);
}
.mb-village {
  color: var(--mb-text);
  font-style: italic;
  font-size: 11.5px;
}
.mb-hamlet {
  font-style: italic;
  font-size: 10.5px;
}
.mb-hut {
  color: var(--mb-text);
  font-weight: 600;
  font-size: 11.5px;
}
.mb-bivouac {
  font-size: 11px;
}
.mb-valley {
  font: 600 10.5px/1.1 var(--display);
  letter-spacing: 0.3em;
  text-transform: uppercase;
}
.mb-dwelling,
.mb-locality {
  font-size: 10px;
}
.mb3d-stamp {
  position: absolute;
  z-index: 2;
  left: 12px;
  top: 12px;
  display: grid;
  gap: 2px;
  padding: 8px 12px;
  border-radius: var(--r-inset);
  background: var(--glass-read);
  border: 1px solid var(--sheen-soft);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  pointer-events: none;
}
.mb3d-stamp b {
  font: 600 13px/1.2 var(--display);
  color: var(--ink-1);
}
.mb3d-stamp span {
  font: 500 10.5px/1.3 var(--mono);
  color: var(--ink-3);
  letter-spacing: 0.02em;
}
/* The strip of months over the sky: ten names, a tick for each clear morning, and the day passing. */
.season-strip-film {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  top: 0;
  height: 46px;
  padding: 0 22px;
  pointer-events: none;
  color: #132131;
  text-shadow: 0 0 8px rgba(255, 255, 255, 0.55);
}
.season-strip-film .sf-months {
  position: absolute;
  left: 22px;
  right: 22px;
  top: 12px;
  height: 12px;
  font: 500 10px/12px var(--mono);
  letter-spacing: 0.04em;
  text-transform: lowercase;
}
.season-strip-film .sf-months span {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  opacity: 0.42;
  transition: opacity 0.2s ease;
}
.season-strip-film .sf-months span.on {
  opacity: 0.95;
}
.season-strip-film .sf-track {
  position: absolute;
  left: 22px;
  right: 22px;
  top: 30px;
  height: 1px;
  background: rgba(19, 33, 49, 0.28);
}
.season-strip-film .sf-track i {
  position: absolute;
  top: -2px;
  width: 1px;
  height: 5px;
  background: rgba(19, 33, 49, 0.4);
}
.season-strip-film .sf-track i.past {
  background: rgba(19, 33, 49, 0.9);
}
.season-strip-film .sf-now {
  position: absolute;
  left: 0;
  top: -6px;
  width: 2px;
  height: 13px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--hot);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.85);
  will-change: transform;
}
.phone {
  border-radius: 30px;
  overflow: hidden;
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--float-2);
  background: #0b1620;
}

/* Ledger */
.data {
  padding-block: 0 clamp(64px, 10vw, 120px);
}
.as-of {
  font: 400 13px/1.5 var(--ui);
  color: var(--ink-3);
  margin-top: 14px;
}

/* Day dial */
.day {
  padding-block: 0 clamp(64px, 10vw, 120px);
}
.day-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.dial-wrap {
  display: grid;
  grid-template-columns: minmax(220px, 320px) minmax(0, 1fr);
  gap: clamp(18px, 4vw, 48px);
  align-items: center;
  margin-bottom: 32px;
}
.dial {
  width: 100%;
  height: auto;
  overflow: visible;
}
.dial-face {
  fill: rgba(var(--ice), 0.9);
  stroke: var(--sheen);
}
.dial-arc {
  fill: none;
  stroke-width: 14;
  stroke-linecap: round;
}
.dial-arc.sat {
  stroke: #7aa7ff;
}
.dial-arc.sta {
  stroke: var(--signal);
}
.dial-arc.bul {
  stroke: var(--risk-amber);
}
.dial-arc.past {
  opacity: 1;
}
.dial-arc.future {
  opacity: 0.3;
}
.dial-tick {
  stroke: var(--rule);
  stroke-width: 1;
}
.dial-tick.major {
  stroke: var(--ink-3);
}
.dial-num {
  font: 500 9px/1 var(--mono);
  fill: var(--ink-3);
  text-anchor: middle;
}
.dial-lab {
  font: 600 8.5px/1 var(--display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-anchor: middle;
}
.dial-hand line {
  stroke: var(--ink-1);
  stroke-width: 2;
  stroke-linecap: round;
}
.dial-knob {
  fill: var(--hot);
  stroke: var(--void);
  stroke-width: 3;
}
.dial-pin {
  fill: var(--ink-1);
}
.dial-now {
  font: 600 18px/1 var(--mono);
  fill: var(--ink-1);
}
.dial-read {
  padding: 18px 20px;
  display: grid;
  gap: 10px;
}
.dial-title {
  font: 600 18px/1.2 var(--display);
}
.dial-read ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}
.dial-read li {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr);
  gap: 10px;
  font-size: 14px;
  color: var(--ink-2);
}
.dial-read li i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-top: 6px;
}
.dial-read li b {
  color: var(--ink-1);
  font-weight: 600;
}
.dial-read .old {
  color: var(--ageing);
}
.fine {
  font-size: 12px;
  color: var(--ink-3);
}
.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 18px 32px;
}
.timeline time {
  font: 500 22px/1 var(--mono);
  color: var(--ink-1);
}
.timeline h3 {
  font-size: 18px;
  margin: 8px 0 4px;
}
.timeline p {
  color: var(--ink-3);
  font-size: 14.5px;
}
.js .timeline {
  display: none;
}

/* Closing + footer */
.closing {
  padding-block: 0 clamp(64px, 10vw, 120px);
}
.closing .panel {
  padding: clamp(24px, 4vw, 48px);
  display: grid;
  gap: 16px;
  max-width: 52rem;
}
.closing .principle {
  font: 600 16px/1.3 var(--display);
  color: var(--ink-1);
  border: 0;
  padding: 0;
}
.closing p {
  color: var(--ink-2);
}
footer {
  border-top: 1px solid var(--rule);
  padding-block: 36px 48px;
}
.foot-brand {
  width: 160px;
  height: auto;
  margin-bottom: 18px;
}
.notices {
  display: grid;
  gap: 8px;
  font: 400 12.5px/1.55 var(--ui);
  color: var(--ink-3);
  max-width: 60rem;
}
/* A credit that is a link keeps its underline, a quiet one: a paragraph of a dozen of them under
   lines of the text's own colour stood out of the footer as its brightest block. */
.notices a {
  text-decoration-color: var(--sheen);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Tuning panel, ?tune */
.tune {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: 50;
  width: 260px;
  padding: 12px 14px;
  display: grid;
  gap: 8px;
  font: 500 11px/1.3 var(--mono);
}
.tune label {
  display: grid;
  gap: 2px;
}
.tune input {
  width: 100%;
}

@media (max-width: 900px) {
  .instrument {
    grid-template-columns: minmax(0, 1fr);
  }
  .dial-wrap {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
  }
  .dial {
    max-width: 300px;
  }
  .dial-read {
    width: 100%;
  }
}
@media (max-width: 560px) {
  .hero-stage::after {
    background: linear-gradient(
      180deg,
      rgba(5, 12, 19, 0.6) 0%,
      rgba(5, 12, 19, 0) 13%,
      rgba(5, 12, 19, 0) 80%,
      var(--void) 100%
    );
  }
  /* On a phone the copy is an opaque sheet passing over the pinned relief, and over its
     read-out too: text never runs through the glass. The season waits until the sheet has
     gone (app.js, measure), and the sheet's words stop above its own fade. */
  .hero-copy {
    z-index: 3;
    padding-top: 54svh;
    padding-bottom: 88px;
    gap: 16px;
    align-content: start;
  }
  .hero-copy::before {
    bottom: 0;
    -webkit-mask-image: none;
    mask-image: none;
    background: linear-gradient(
      180deg,
      rgba(5, 12, 19, 0) 0,
      rgba(5, 12, 19, 0) calc(54svh - 80px),
      rgba(5, 12, 19, 0.9) calc(54svh - 8px),
      var(--void) calc(54svh + 60px),
      var(--void) calc(100% - 60px),
      rgba(5, 12, 19, 0) 100%
    );
  }
  .season-hud {
    top: calc(66px + env(safe-area-inset-top, 0px));
    bottom: auto;
    left: 16px;
    right: 16px;
    width: auto;
    padding: 10px 14px;
    gap: 6px;
  }
  .hud-date {
    font-size: 15px;
  }
  .hud-strip {
    height: 30px;
  }
  /* In the sky above the relief, where the summit never reaches. */
  /* Always in the top right corner, over the sky, where the summit never reaches. */
  .climb-clock {
    --cc: 104px;
    top: calc(64px + env(safe-area-inset-top, 0px));
    right: 12px;
    gap: 6px;
  }
  .climb-clock .cc-cap {
    padding: 4px 10px 5px;
  }
  .hero-still {
    object-position: 50% 0%;
  }
  .figures {
    gap: 6px 20px;
  }
  .phone {
    border-radius: 20px;
  }
  .profile-canvas {
    height: 180px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .df-spinner,
  .scroll-cue svg {
    animation: none;
  }
  .mb3d-map {
    transition: none;
  }
  .arc-glow,
  .arc-wash {
    transition: none !important;
  }
  .hero-gl,
  .hero-overlay,
  .hud-hint,
  .season-hud,
  .season-hud.yield,
  .climb-clock,
  .climb-clock.yield,
  .climb-clock.opening,
  .climb-clock.night {
    transition: none;
  }
}
.season-strip-film::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 64px;
  background: linear-gradient(
    rgba(244, 248, 252, 0.78),
    rgba(244, 248, 252, 0)
  );
  z-index: -1;
}

/* Under reduced motion the film stands still until it is asked for. */
.df-play {
  display: none;
  position: absolute;
  z-index: 5;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  min-height: 48px;
  padding: 0 22px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--ink-1);
  color: #0b1620;
  font: 600 16px/1 var(--ui);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  cursor: pointer;
}
.map-frame.ready.film-waits .df-play {
  display: block;
}

/* Until the relief is drawn the hero is its still alone: no clock that would not turn, no
   pinned stretch to scroll through over a picture that does not move. */
.hero:not(.gl-ready) .hero-hud-pin,
.hero:not(.gl-ready) .hero-run {
  display: none;
}

/* Nothing stands on the Mont Blanc scene before its ground is drawn. */
.mb3d-map {
  transition: opacity 0.5s ease;
}
.mb3d-map.mb-wait {
  opacity: 0;
}
/* MapLibre draws nothing above its horizon: the canvas is a hole there, and the still under it,
   framed for another window, showed a summit of its own through it. Once the map stands it has
   its own ground colour behind it, so the still is wholly covered. */
.mb3d-map.mb-live {
  background: #0b1620;
}
/* The map keeps the page's scroll first (one finger, the wheel), without MapLibre's veil that says
   so: the massif turning as the page passes is what says it can be moved (the owner, 2026-10-12). */
.mb3d .maplibregl-cooperative-gesture-screen {
  display: none;
}
.mb3d-map.mb-wait .maplibregl-marker {
  visibility: hidden;
}

/* The page's instruments stand on the page itself, not in cards (the owner, 2026-10-12: tinted
   rounded panels read as a template). A hairline above each is the only frame they keep. Glass
   stays where something floats over a picture: the hero's read-outs, the film's own screen. */
.profile.glass,
.dial-read.glass,
.closing .panel.glass {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 0;
  border-top: 1px solid var(--sheen-soft);
  border-radius: 0;
  box-shadow: none;
  padding: 18px 0 0;
}

/* Mono is for figures and an instrument's read-out; a caption, a source or a notice is prose.
   The signal colour is for data (the line, the glacier, the dial's arcs), never for emphasis. */
.cc-hint {
  font-family: var(--ui);
}
.bulletin {
  display: grid;
  gap: 8px;
  padding-top: 18px;
  border-top: 1px solid var(--sheen-soft);
}
.bulletin h3 {
  font-size: 19px;
  font-weight: 600;
}
.bulletin p {
  margin: 0;
  color: var(--ink-2);
  font-size: 15px;
}
.src {
  display: block;
  margin-top: 8px;
  font: 400 13px/1.5 var(--ui);
  color: var(--ink-3);
}
.bulletin .src {
  margin-top: 0;
}
.sources {
  margin: 0;
  display: grid;
  border-top: 1px solid var(--rule);
}
.sources > div {
  display: grid;
  grid-template-columns: minmax(180px, 0.4fr) minmax(0, 1fr);
  gap: 6px 32px;
  padding-block: 18px;
  border-bottom: 1px solid var(--rule);
}
.sources dt {
  font: 600 19px/1.25 var(--display);
}
.sources dd {
  margin: 0;
  color: var(--ink-2);
  font-size: 15px;
}
/* The two arc-wide chapters (stations, danger): one picture of the whole arc each, a title, and a
   note under it (what the picture is, its figures, its source). As it comes, the arc is held whole
   across the width between the title and the note, and that is every upright or squarish screen.
   In a window 3:2 or wider, which the picture's own 1.62:1 covers losing next to nothing, the
   picture takes the window: the title stands on its dark north-west and the note on the dark
   south of the chain, the plain and the sea, where no station and no bulletin reach. Both keep a
   little night of their own behind them, for the window whose crop brings a light or a colour
   under a word. --arc-zoom is the page's scroll (app.js, initArc; the stations' chapter alone,
   the danger's map is held by a hand): a few hundredths, so the
   picture is felt to come closer rather than seen to, and less still where the arc is held whole, so that its
   two ends stay in the picture. `translate` places the picture and `transform` zooms it, so the one never
   rewrites the other. */
.arc {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--void);
  display: flex;
  flex-direction: column;
  padding-block: clamp(48px, 9svh, 96px) clamp(40px, 7svh, 72px);
}
.arc-head {
  order: 1;
}
.arc-map {
  order: 2;
  position: relative;
  aspect-ratio: 2400 / 1484;
  margin-block: clamp(14px, 2.4svh, 26px) clamp(16px, 2.8svh, 30px);
  transform: scale(calc(0.4 + 0.6 * var(--arc-zoom, 1)));
  transform-origin: 50% 50%;
  will-change: transform;
}
.arc-foot {
  order: 3;
}
.arc-map > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* Held whole, the ground ends in the page's night rather than at an edge; the lights do not fade. */
.arc-ground,
.arc-wash {
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 6%,
    #000 93%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 6%,
    #000 93%,
    transparent 100%
  );
}
.arc-head h2 {
  position: relative;
  z-index: 0;
  width: fit-content;
}
.arc-note {
  position: relative;
  z-index: 0;
  display: grid;
  gap: 14px;
  max-width: 40rem;
}
.arc-note > p:first-child {
  color: var(--ink-2);
  line-height: 1.55;
  text-wrap: balance;
}
.arc-note .src {
  margin-top: 0;
}
.arc-nets,
.arc-levels {
  list-style: none;
  margin: 0;
  padding: 13px 0 0;
  border-top: 1px solid var(--rule);
  font: 500 13.5px/1.6 var(--display);
  color: var(--ink-2);
}
/* The networks as a table read down its columns, the largest first. In two columns a long name
   turns under itself; where there is room for three, each column is as wide as its longest name. */
.arc-nets {
  columns: 2;
  column-gap: 20px;
}
.arc-nets li {
  display: flex;
  align-items: baseline;
  gap: 9px;
  break-inside: avoid;
}
.arc-nets b {
  flex: none;
  width: 3ch;
  text-align: right;
  font: 500 12.5px/1 var(--mono);
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 720px) {
  .arc-nets,
  .arc-levels {
    font-size: 14px;
  }
  .arc-nets b {
    font-size: 13px;
  }
}
.arc-levels {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: 5px 24px;
}
.arc-levels li {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.arc-levels li::before {
  content: '';
  flex: none;
  width: 13px;
  height: 13px;
  border-radius: 3px;
  background: var(--lv);
}
.arc-levels b {
  font: 600 13px/1 var(--mono);
  color: var(--ink-1);
}
/* The app's own colours (web/src/lib/bulletinValidity.ts); the fifth as the picture draws it. */
.lv-1 {
  --lv: #4d9f3a;
}
.lv-2 {
  --lv: #f5e400;
}
.lv-3 {
  --lv: #f08300;
}
.lv-4 {
  --lv: #e2001a;
}
.arc-levels .lv-5::before {
  background: #46000c;
  box-shadow: inset 0 0 0 1.5px #ff3c46;
}
.arc-levels .lv-0::before {
  background: rgba(143, 154, 166, 0.35);
}
/* The stations come network by network (drawn by app.js, initStations) and their common light
   rises under them; the picture of the danger, where the season has not come, as one wash over the
   night relief. Each when its picture is well in view, and only with the script, which is what
   says when that is. */
/* On a phone the lights stand a few pixels apart: there their common light is kept low, so that
   each stays a light of its own where the chain is densest. */
.arc-glow {
  opacity: var(--arc-glow, 1);
}
@media (max-width: 700px) {
  .arc {
    --arc-glow: 0.45;
  }
}
.js .arc-glow {
  opacity: 0;
  transition: opacity 2.8s ease 0.4s;
}
.js .arc-on .arc-glow {
  opacity: var(--arc-glow, 1);
}
.js .arc-wash {
  opacity: 0;
  transition: opacity 1.8s ease;
}
.js .arc-on .arc-wash {
  opacity: 1;
}
/* The script holds the picture's source back while the season loads (app.js, initDanger): a
   picture with no source would draw its alt text over the map. */
.arc-wash:not([src]) {
  visibility: hidden;
}
@media (min-aspect-ratio: 3/2) {
  .arc {
    --arc-h: max(100svh, 560px);
    display: block;
    height: var(--arc-h);
    padding-block: 0;
  }
  .arc-map {
    position: absolute;
    left: 50%;
    top: 50%;
    translate: -50% -50%;
    width: max(100%, calc(var(--arc-h) * 2400 / 1484));
    margin-block: 0;
    transform: scale(var(--arc-zoom, 1));
  }
  .arc-ground,
  .arc-wash {
    -webkit-mask-image: none;
    mask-image: none;
  }
  /* The danger reaches the picture's north and stops well short of its south: held by its head,
     the window's crop falls on the sea, and the north-west stays open for the title. */
  .arc-danger .arc-map {
    top: 0;
    translate: -50% 0;
    transform-origin: 50% 25%;
  }
  .arc::after {
    content: '';
    position: absolute;
    z-index: 1;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(
      180deg,
      var(--void) 0,
      rgba(5, 12, 19, 0) 7%,
      rgba(5, 12, 19, 0) 90%,
      var(--void) 100%
    );
  }
  .arc-head {
    position: absolute;
    z-index: 2;
    inset: 0 0 auto 0;
    padding-top: clamp(40px, 7svh, 88px);
    pointer-events: none;
  }
  .arc-foot {
    position: absolute;
    z-index: 2;
    inset: auto 0 0 0;
    padding-bottom: clamp(20px, 3.6svh, 40px);
  }
  .arc-foot .wrap {
    display: flex;
    justify-content: flex-end;
  }
  .arc-note {
    width: min(39rem, 53vw);
    max-width: none;
  }
  .arc-head h2::before,
  .arc-note::before {
    content: '';
    position: absolute;
    z-index: -1;
    pointer-events: none;
  }
  .arc-head h2::before {
    inset: -72px -130px -72px -150px;
    background: radial-gradient(
      closest-side,
      rgba(5, 12, 19, 0.92) 0,
      rgba(5, 12, 19, 0.84) 52%,
      rgba(5, 12, 19, 0) 100%
    );
  }
  .arc-note::before {
    inset: -64px -72px -72px -80px;
    background: radial-gradient(
      closest-side,
      rgba(5, 12, 19, 0.86) 0,
      rgba(5, 12, 19, 0.74) 58%,
      rgba(5, 12, 19, 0) 100%
    );
  }
  .arc-levels {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 4px 14px;
  }
}
@media (min-width: 720px) and (max-aspect-ratio: 3/2),
  (min-width: 1100px) and (min-aspect-ratio: 3/2) {
  .arc-nets {
    columns: auto;
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(5, auto);
    justify-content: space-between;
    column-gap: 24px;
  }
}
@supports not (height: 100svh) {
  .arc {
    --arc-h: max(100vh, 560px);
  }
}

/* The danger chapter as a season (app.js, initDanger). Everything here sits on the rules for
   `.arc` above and is keyed on two classes the script sets. `dz-season` is on the chapter from
   the start and leaves only if the season's file fails to come: it lays the chapter out for the
   season, its strip's place held empty, so that nothing moves under a reader when a slow file
   arrives, here or in the chapters below. `dz-live` is added once the season is drawn. Without
   either the chapter is the picture of 20 February. Nothing here holds the chapter or lengthens
   the page: the days turn under a hand on the map or on the strip, never with the page's scroll. */
.dz-moving,
.dz-season .dz-still {
  display: none;
}
.dz-season .dz-moving {
  display: inline;
}
/* A finger or a mouse dragged on the map turns the days, so the map takes the stroke whole: on an
   upright screen it is a band a third of the window high, with the title, the strip, the legend
   and the note around it for the thumb that wants the page. */
.dz-canvas {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.dz-canvas.dz-grabbing {
  cursor: grabbing;
}
.dz-live .arc-wash {
  display: none;
}

/* ---------- the strip: the season counted, a column a day ---------- */
.dz-strip {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
  font: 500 13px/1.4 var(--display);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
/* Waiting for the season the strip is its own height of nothing: its two lines of words are
   empty until then, and each is given a line to stand on. */
.dz-season .dz-strip[hidden] {
  display: grid !important;
  visibility: hidden;
}
.dz-season .dz-strip[hidden] .dz-day > ::before {
  content: '\00a0';
}
.dz-day {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 14px;
}
/* The date is the scene's clock: after the title it is the first thing read. */
.dz-day b {
  font: 600 22px/1.25 var(--display);
  color: var(--ink-1);
  /* the longest date of the season, so the figures beside it do not shift as the day turns */
  min-width: 10.5em;
}
.dz-pick {
  min-height: 1.4em;
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dz-pick b {
  font-weight: 600;
  color: var(--ink-1);
}
.dz-track {
  position: relative;
  height: var(--dz-track-h, 58px);
  border-radius: 4px;
  overflow: hidden;
  cursor: ew-resize;
  /* A finger dragged along the strip turns the days; dragged across it, it scrolls the page. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.dz-track:focus-visible {
  outline-offset: 2px;
}
.dz-chart,
.dz-band {
  position: absolute;
  left: 0;
  width: 100%;
  display: block;
}
.dz-chart {
  top: 0;
  height: calc(100% - 8px);
}
.dz-band {
  bottom: 0;
  height: 6px;
}
/* The days not yet reached, under the page's night. */
.dz-ahead {
  position: absolute;
  inset: 0;
  background: rgba(5, 12, 19, 0.72);
  transform: translateX(var(--dz-x, 0px));
  will-change: transform;
}
.dz-cursor {
  position: absolute;
  top: 0;
  bottom: 0;
  left: -1px;
  width: 2px;
  background: var(--ink-1);
  transform: translateX(var(--dz-x, 0px));
  will-change: transform;
}
.dz-months {
  position: relative;
  height: 15px;
  font: 500 11px/15px var(--mono);
  color: var(--ink-3);
  text-transform: lowercase;
}
.dz-months span {
  position: absolute;
  top: 0;
  padding-left: 5px;
  border-left: 1px solid var(--rule);
}

/* ---------- upright and squarish screens: the arc whole across the width ---------- */
@media not (min-aspect-ratio: 3/2) {
  .dz-season.arc-danger {
    padding-block: clamp(16px, 3svh, 40px) 20px;
  }
  .dz-season .arc-map {
    margin-block: 10px 12px;
  }
  .dz-season .arc-foot,
  .dz-season .arc-foot .wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  /* The note's parts stand in the chapter's own column, so the strip can come first, right
     under the map it counts. */
  .dz-season .arc-foot .wrap {
    gap: 10px;
  }
  .dz-season .arc-note {
    display: contents;
  }
  .dz-season .dz-strip {
    order: 1;
  }
  .dz-season .arc-levels {
    order: 2;
    padding-top: 9px;
    gap: 2px 20px;
  }
  .dz-season .arc-note .src {
    order: 3;
    font-size: 12.5px;
    line-height: 1.45;
  }
  .dz-season .dz-about {
    order: 4;
    color: var(--ink-2);
    line-height: 1.55;
  }
  .dz-day b {
    width: 100%;
  }
}

/* ---------- a window 3:2 or wider: the picture takes it, the strip is its horizon ---------- */
@media (min-aspect-ratio: 3/2) {
  /* The foot lies across the whole south of the picture: only its note and its strip take the
     pointer, the zones between and around them stay the map's. */
  .dz-season .arc-foot {
    padding-bottom: clamp(14px, 2.4svh, 26px);
    pointer-events: none;
  }
  /* Here the picture is the whole window: a finger's upright stroke stays the page's, or a tablet
     on its side would have nowhere to scroll from. A sideways stroke turns the days. */
  .dz-canvas {
    touch-action: pan-y;
  }
  /* The zones end at 88 % of the picture's height (the Maritime Alps). Held by its head, the
     picture is no taller than keeps that tip above the strip (--dz-south: the strip, its foot and
     a breath), so the whole arc stands over its season. Where that makes it narrower than the
     window, the ground ends in the page's night rather than at an edge; the colours are not faded. */
  .dz-season.arc-danger .arc-map {
    --dz-south: 172px;
    width: min(
      max(100%, calc(var(--arc-h) * 2400 / 1484)),
      max(60%, calc((var(--arc-h) - var(--dz-south)) / 0.88 * 2400 / 1484))
    );
  }
  .dz-season .arc-ground {
    -webkit-mask-image: linear-gradient(
      90deg,
      transparent 0,
      #000 6%,
      #000 94%,
      transparent 100%
    );
    mask-image: linear-gradient(
      90deg,
      transparent 0,
      #000 6%,
      #000 94%,
      transparent 100%
    );
  }
  .dz-season .arc-note,
  .dz-season .dz-track {
    pointer-events: auto;
  }
  .dz-season .arc-foot .wrap {
    flex-direction: column;
    align-items: stretch;
    gap: clamp(12px, 2svh, 22px);
  }
  .dz-season .arc-note {
    align-self: flex-end;
    gap: 10px;
  }
  .dz-strip {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: baseline;
    gap: 6px 24px;
  }
  .dz-pick {
    text-align: right;
  }
  .dz-track,
  .dz-months {
    grid-column: 1 / -1;
  }
  /* The strip runs under the plain and the sea; a little of the page's night behind it keeps the
     columns their own colours. */
  .dz-strip::before {
    content: '';
    position: absolute;
    z-index: -1;
    inset: -18px -100vw -60px;
    pointer-events: none;
    background: linear-gradient(
      180deg,
      rgba(5, 12, 19, 0) 0,
      rgba(5, 12, 19, 0.78) 34%,
      var(--void) 100%
    );
  }
}

@media (prefers-reduced-motion: reduce) {
  .dz-ahead,
  .dz-cursor {
    will-change: auto;
  }
}

/* The stations chapter, answering (app.js, initStations). Everything is under `.arc-stations`. */
/* The three pictures in one group, so one transform moves them together (app.js, initStations). The group
   fills the map's box exactly, so that untouched it is today's picture. */
.arc-stations .wx-world {
  position: absolute;
  inset: 0;
}
.arc-stations .wx-world > *,
.arc-stations .wx-glow > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* The night the ground ends in belongs to the box, not to the picture: carried by the picture, it
   would be zoomed away with it and the ground would end at an edge. */
.arc-stations .arc-ground {
  -webkit-mask-image: none;
  mask-image: none;
}
.arc-stations .wx-clip {
  overflow: hidden;
}
@media not (min-aspect-ratio: 3/2) {
  .arc-stations .wx-clip {
    -webkit-mask-image: linear-gradient(
      180deg,
      transparent 0,
      #000 6%,
      #000 93%,
      transparent 100%
    );
    mask-image: linear-gradient(
      180deg,
      transparent 0,
      #000 6%,
      #000 93%,
      transparent 100%
    );
  }
}
/* The stations' common light is the arc seen whole. Brought closer it would be a fog over each
   valley, so it goes as the map comes (--wx-near, 0 at the whole arc and 1 at the closest). */
.arc-stations .wx-glow {
  opacity: calc(1 - 0.85 * var(--wx-near, 0));
}

/* With the script the dots are drawn (app.js, initStations) and the picture of them is not shown, unless
   the stations could not be read: then it stands as it does without the script. */
.arc-stations .wx-dots {
  pointer-events: none;
}
.js .arc-stations:not(.wx-failed) .arc-dots {
  visibility: hidden;
}
/* One finger moving up or down is the page's, always; anything else on the map is the map's. */
.arc-stations.wx-live .arc-map {
  touch-action: pan-y;
  cursor: zoom-in;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  outline-offset: -3px;
}
.arc-stations.wx-live .arc-map.wx-over {
  cursor: pointer;
}
.arc-stations.wx-live .arc-map.wx-closest {
  cursor: default;
}
.arc-stations.wx-live .arc-map.wx-near {
  cursor: grab;
}
.arc-stations.wx-live .arc-map.wx-near.wx-over {
  cursor: pointer;
}
.arc-stations.wx-live .arc-map.wx-held {
  cursor: grabbing;
}
/* The pictures are ground, not things to pick up: a press on one would otherwise start the
   browser's own drag of the image (and on a phone, its menu) and the map would lose the pointer. */
.arc-stations.wx-live .wx-world img {
  pointer-events: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}
/* In a wide window the note's row spans the picture's foot; only the note itself takes the pointer. */
.arc-stations.wx-live .arc-foot {
  pointer-events: none;
}
.arc-stations.wx-live .arc-note {
  pointer-events: auto;
}

/* The card: a station's name, where and whose it is, up to three figures, and when they were read.
   Nothing in it is a frame for something else: no rule, no label that a figure does not need. One
   card for a pointer and a finger; only where it stands differs (app.js, initStations).

   By the dot, over the relief, it is a solid surface with the faintest edge: glass was tried and
   WebKit draws no blur over this map, so through it every dot behind stood sharp among the
   figures. */
.wx-card {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 0;
  width: max-content;
  min-width: 168px;
  max-width: min(340px, calc(100% - 24px));
  padding: 14px 16px 13px;
  border-radius: var(--r-inset);
  background: var(--glass-solid);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow:
    inset 0 0 0 1px var(--rule),
    var(--float-2);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.16s ease,
    visibility 0s linear 0.16s;
  will-change: transform;
}
.wx-card.wx-shown {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.16s ease;
}
/* Under a narrow map the reading takes the place of the note's first words, on the page's own
   night and in the note's own column: there it needs no surface at all. Those words leave while it
   is read and keep its height, so that the networks' table never comes up under it. Only when
   there is no room under the map does it stand over the title, and there it is a surface again. */
.wx-card.wx-docked {
  width: calc(100% - 2 * var(--gutter));
  max-width: 420px;
}
.wx-card.wx-docked[data-side='under'] {
  max-width: 40rem;
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
.arc-stations .arc-note > p:first-child {
  transition: opacity 0.16s ease;
}
/* 129 px is the reading at its usual tallest (a name on one line, figures, the hour): held from
   the start, so that choosing a station does not move the table under it. */
.arc-stations.wx-narrow .arc-note > p:first-child {
  min-height: 129px;
}
.arc-stations.wx-reading .arc-note > p:first-child {
  opacity: 0;
  min-height: max(129px, var(--wx-card-h, 0px));
}
.wx-name {
  font: 600 17px/1.2 var(--display);
  color: var(--ink-1);
  overflow-wrap: anywhere;
  text-wrap: balance;
}
.wx-where {
  margin-top: 3px;
  font: 400 13px/1.4 var(--ui);
  color: var(--ink-3);
}
/* The one thing in the card that takes a touch: a network's notice that its licence wants linked
   here (the card itself lets every touch through to the map). Its target is taller than its line
   without the line growing. */
.wx-where a {
  display: inline-block;
  margin: -10px 0;
  padding: 10px 0;
  pointer-events: auto;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 3px;
}
.wx-figs {
  display: flex;
  gap: 22px;
  margin: 14px 0 0;
}
.wx-figs > div {
  display: flex;
  flex-direction: column-reverse;
  min-width: 0;
}
.wx-figs dt {
  margin-top: 2px;
  font: 500 12px/1.3 var(--display);
  color: var(--ink-3);
  white-space: nowrap;
}
/* The figures in the page's text face with its tabular digits: in the mono a decimal comma takes a
   whole digit's width and «7,7» reads as three things. */
.wx-figs dd {
  margin: 0;
  font: 500 22px/1.15 var(--ui);
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.wx-figs dd small {
  font: 400 12px/1 var(--ui);
  color: var(--ink-3);
}
/* A figure read well before the others says its own day, in the colour of what must not be leaned on. */
.wx-figs dt span,
.wx-when.wx-old {
  color: var(--ageing);
}
.wx-when,
.wx-none {
  margin-top: 12px;
  font: 400 13px/1.4 var(--ui);
  color: var(--ink-3);
}
.wx-none {
  max-width: 26ch;
  color: var(--ink-2);
}

/* The way back to the whole arc: there only while the map is closer than that. What is seen is a
   34 px pill; what answers a finger is the 44 px around it. */
.wx-back {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 0;
  min-height: 44px;
  padding: 0 15px;
  border: 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
  font: 600 13px/1 var(--display);
  letter-spacing: 0.02em;
  color: var(--ink-1);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.2s ease,
    visibility 0s linear 0.2s;
}
.wx-back::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 5px 0;
  border-radius: var(--r-pill);
  background: var(--glass-solid);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--float-2);
}
.wx-back.wx-shown {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s ease;
}
@media (prefers-reduced-motion: reduce) {
  .wx-card,
  .wx-card.wx-shown,
  .wx-back,
  .wx-back.wx-shown {
    transition: none;
  }
}

/* The layers chapter: the sheet's own screen, as tall as the window lets it be and held whole in
   it while the rows beside it pass (they are taller than a laptop's window), and beside it what
   seven of its tiles are. A row's picture is its tile, cut from that same screenshot: the
   screenshot is 390 x 844 and a tile 20.26 % of its width, so a box --b wide shows one tile from a
   background 100 / 20.26 = 4.936 times --b wide, moved by the tile's corner (--x, --y, in percent). */
.screens {
  padding-block: clamp(40px, 6vw, 80px) clamp(64px, 10vw, 120px);
}
.screens-grid {
  display: grid;
  align-items: center;
  min-height: 100svh;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto 1fr;
  column-gap: clamp(32px, 6vw, 96px);
  grid-template-areas: 'head phone' 'list phone' '. phone';
}
.screens-grid .section-head {
  grid-area: head;
  margin-bottom: clamp(18px, 2.4vw, 30px);
  align-self: end;
}
.phone-one {
  --pw: min(380px, calc((100svh - 96px) * 390 / 844));
  grid-area: phone;
  margin: 0;
  width: var(--pw);
  align-self: start;
  position: sticky;
  top: calc((100svh - var(--pw) * 844 / 390) / 2);
}
.layers {
  grid-area: list;
  margin: 0;
  display: grid;
  max-width: 40rem;
  border-top: 1px solid var(--rule);
}
.layers > div {
  --b: 52px;
  position: relative;
  display: grid;
  gap: 2px;
  padding: 12px 0 12px calc(var(--b) + 16px);
  min-height: calc(var(--b) + 24px);
  align-content: center;
  border-bottom: 1px solid var(--rule);
}
.layers > div::before {
  content: '';
  position: absolute;
  left: 0;
  top: 12px;
  width: var(--b);
  height: var(--b);
  border-radius: 12px;
  background: #0b1620 url(assets/app-layers.jpg) no-repeat;
  background-size: calc(var(--b) * 4.936) auto;
  background-position: calc(var(--b) * var(--x) * -0.04936)
    calc(var(--b) * var(--y) * -0.10682);
  box-shadow: inset 0 0 0 1px var(--sheen);
}
.layers dt {
  font: 600 18px/1.25 var(--display);
}
.layers dd {
  margin: 0;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.5;
}
.layers .src {
  margin-top: 2px;
}
@media (max-width: 860px) {
  .screens-grid {
    min-height: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-template-areas: 'head' 'phone' 'list';
    row-gap: clamp(22px, 5vw, 32px);
  }
  .screens-grid .section-head {
    margin-bottom: 0;
  }
  .phone-one {
    position: static;
    width: 100%;
    max-width: 420px;
    margin-inline: auto;
  }
}
@media (max-width: 720px) {
  .sources > div {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* An upright screen: the opening is the upright picture, clear above (the wordmark on its sky, the
   massif under it) and dark only where the copy stands, from a little above its first line down. */
@media (max-aspect-ratio: 4/5) {
  .intro-img {
    object-position: 50% 0;
  }
  .intro::before {
    background: linear-gradient(
      180deg,
      rgba(5, 12, 19, 0.5) 0,
      rgba(5, 12, 19, 0) 15%
    );
  }
  .intro .wrap {
    padding-top: 150px;
    background: linear-gradient(
      180deg,
      rgba(5, 12, 19, 0) 0,
      rgba(5, 12, 19, 0.72) 130px,
      rgba(5, 12, 19, 0.9) 62%,
      var(--void) 100%
    );
  }
  .mb3d-head {
    padding-top: clamp(28px, 5svh, 56px);
    padding-bottom: 72px;
  }
}

/* The access request and the zone alert (spec 2026-10-14 §3). Both stand on the page as the
   closing's text does, without a card; the fields are wells of the page's own glass, 48 px high and
   16 px type, so Safari does not zoom into them. Hidden until app.js shows them. */
.ask {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--r-pill);
  background: rgba(var(--ice), 0.42);
  box-shadow: inset 0 0 0 1px var(--sheen-top);
  color: var(--ink-1);
  font: 500 14px/1 var(--ui);
  cursor: pointer;
}
.ask:hover,
.ask[aria-expanded='true'] {
  background: rgba(var(--ice), 0.72);
  box-shadow: inset 0 0 0 1px var(--ink-2);
}
.closing .ask {
  min-height: 48px;
  font-size: 16px;
}
.access-slot,
.alerts-body {
  max-width: 34rem;
}
.lform {
  display: grid;
  gap: 16px;
}
.lform .field {
  display: grid;
  gap: 6px;
}
.lform label {
  font: 600 14px/1.3 var(--display);
  letter-spacing: 0.02em;
  color: var(--ink-1);
}
.lform .opt {
  font-weight: 500;
  color: var(--ink-3);
}
.lform input,
.lform textarea {
  width: 100%;
  min-height: 48px;
  padding: 11px 14px;
  border: 0;
  border-radius: var(--r-inset);
  background: var(--well);
  box-shadow: inset 0 0 0 1px var(--sheen);
  color: var(--ink-1);
  font: 400 16px/1.4 var(--ui);
  -webkit-appearance: none;
  appearance: none;
}
.lform textarea {
  resize: vertical;
}
.lform input:focus-visible,
.lform textarea:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 1px;
}
.lform [aria-invalid='true'] {
  box-shadow: inset 0 0 0 1px var(--risk-red);
}
.field-hint,
.form-note {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-3);
}
.form-note a {
  color: var(--ink-2);
}
.form-actions {
  display: flex;
}
.send {
  min-height: 48px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--ink-1);
  color: #0b1620;
  font: 600 16px/1 var(--ui);
  cursor: pointer;
}
.send:hover {
  background: #fff;
}
.send:disabled {
  opacity: 0.6;
  cursor: progress;
}
.form-status:empty {
  display: none;
}
.form-status,
.form-alert,
.form-lead {
  font-size: 15px;
  color: var(--ink-2);
}
.form-status.is-error,
.form-alert {
  color: var(--ink-1);
  border-left: 2px solid var(--risk-red);
  padding-left: 12px;
}
.form-lead {
  border-left: 2px solid var(--signal);
  padding-left: 12px;
}
.form-ack {
  font-size: 16px;
  color: var(--ink-1);
  border-left: 2px solid var(--signal);
  padding-left: 12px;
}
/* The honeypot: off the screen and out of the accessibility tree, so only a form-filling robot
   writes in it. */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.alerts {
  padding-block: 0 clamp(48px, 8vw, 96px);
}
.alerts-body {
  display: grid;
  gap: 16px;
  border-top: 1px solid var(--sheen-soft);
  padding-top: 18px;
}
.alerts-body > p {
  color: var(--ink-2);
}
.combo {
  position: relative;
}
.options {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  margin: 0;
  padding: 6px;
  list-style: none;
  max-height: 264px;
  overflow-y: auto;
  border-radius: var(--r-inset);
  background: var(--glass-solid);
  box-shadow:
    inset 0 0 0 1px var(--sheen),
    var(--float-2);
}
.options li {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  color: var(--ink-2);
  cursor: pointer;
}
.options li[aria-selected='true'],
.options li:hover {
  background: rgba(34, 211, 238, 0.16);
  color: var(--ink-1);
}
.options li.empty {
  color: var(--ink-3);
  cursor: default;
  background: none;
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.chips:empty {
  display: none;
}
.chips li {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding-left: 14px;
  border-radius: var(--r-pill);
  background: rgba(34, 211, 238, 0.14);
  box-shadow: inset 0 0 0 1px rgba(34, 211, 238, 0.5);
  color: var(--ink-1);
  font-size: 15px;
}
.chips button {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}
.chips button svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
}
