/* ============== SCREEN 0 — LOADING / SPLASH ============== */

.loading-screen {
  background: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-screen__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 48px;
  padding-block: 24px;
  position: relative;
}

.loading-screen__logo {
  width: min(329px, calc(100% - 48px));
  height: auto;
  aspect-ratio: 329 / 179;
  flex-shrink: 0;
}

/* Watercolor brush progress bar.
   Two layered JPGs (white BG) share the same canvas; mix-blend-mode:
   multiply makes the white invisible against the white splash. The
   painted fill sits on top of the base and is revealed via a horizontal
   mask whose leading edge sweeps left-to-right as --progress goes 0 → 1,
   with a soft 4px feather at the edge. */

@property --progress {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

.loading-screen__brush {
  position: relative;
  width: 254px;
  isolation: isolate;
  --progress: 0;
  /* Painted edge: leading edge sweeps from 0 to bar-width + feather (258px)
     so the bar is fully empty at progress=0 and fully covered at progress=1. */
  --paint-fade-end: calc(var(--progress) * 258px);
  --paint-solid-end: calc(var(--paint-fade-end) - 4px);
  transition: --progress 250ms ease-out;
}

.loading-screen__brush-layer {
  display: block;
  width: 100%;
  height: auto;
  mix-blend-mode: multiply;
  pointer-events: none;
  user-select: none;
}

.loading-screen__brush-base {
  position: relative;
}

.loading-screen__brush-fill {
  position: absolute;
  inset: 0;
  opacity: 0;
  -webkit-mask-image: linear-gradient(
    to right,
    #000 var(--paint-solid-end),
    transparent var(--paint-fade-end)
  );
  mask-image: linear-gradient(
    to right,
    #000 var(--paint-solid-end),
    transparent var(--paint-fade-end)
  );
  transition: opacity 200ms ease-out;
}

.loading-screen.is-painting .loading-screen__brush-fill {
  opacity: 1;
}

/* End of animation: drop the mask so the fill image is fully visible
   (no painted-edge feather), then JS holds for 1s before advancing. */
.loading-screen.is-complete .loading-screen__brush-fill {
  -webkit-mask-image: none;
  mask-image: none;
}

/* ============== SCREEN 1 — LANGUAGE ============== */

.lang-screen {
  background: #ffffff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  /* env() honours the device's safe areas (iOS home-indicator, Android nav
     bar). The 24 px floor preserves the original visual rhythm when no
     inset is present (desktop, older browsers). */
  padding-top: max(env(safe-area-inset-top), 24px);
  padding-bottom: max(env(safe-area-inset-bottom), 24px);
  font-synthesis: none;
  /* The bottom CTA + lang list are anchored to the bottom via space-between;
     we never want the hero to push the CTA out of view, so clip if a tiny
     viewport really can't fit everything. */
  overflow: hidden;
}

.lang-screen__top {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* welcome on top, hero claims the rest of the column — see hero `flex: 1 1 0`.
     justify-content stays at the default (`flex-start`) so the hero hugs the
     gap below the welcome line; vertical centring would just leave dead space
     above the hero on a tall viewport. */
  gap: 24px;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
}

.lang-screen__hero-img {
  /* Height-driven sizing. The hero takes whatever vertical room the top
     section has after the welcome heading + gap, capped at Paper's 364 px.
     `aspect-ratio: 1` maps height → width so it stays a square, and
     `max-width` keeps it inside the page gutters when the frame is narrower
     than 412 px. Width must be `auto` for aspect-ratio to drive it. */
  flex: 1 1 0;
  min-height: 0;
  max-height: 364px;
  width: auto;
  max-width: calc(100% - 48px);
  aspect-ratio: 1 / 1;
  align-self: center;
  background-position: 50%;
  background-size: cover;
}

.lang-screen__bottom {
  /* The bottom block is rigid — CTA + lang list never shrink. Any vertical
     pressure (small phones, browser chrome up) is absorbed by the hero. */
  flex-shrink: 0;
}

.lang-screen__welcome {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.lang-screen__welcome-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 32px;
  line-height: 32px;
  color: #1a1a1a;
  margin: 0;
}

.lang-screen__bottom {
  align-self: stretch;
  background: #ffffff;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 12px 24px 0;
}

.lang-screen__prompt {
  align-self: stretch;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #5b5b5b;
  margin: 0;
}

.lang-list {
  align-self: stretch;
  display: flex;
  flex-direction: column;
}

.lang-row {
  display: flex;
  align-items: center;
  align-self: stretch;
  gap: 16px;
  height: 56px;
  width: 100%;
  padding: 0;
  background: transparent;
  text-align: left;
  font: inherit;
  color: inherit;
  border: 0;
  cursor: pointer;
}

.lang-row__flag {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: flex;
}

.lang-row__flag svg {
  width: 32px;
  height: 32px;
  display: block;
}

.lang-row__body {
  display: flex;
  align-items: center;
  align-self: stretch;
  flex: 1;
  gap: 16px;
}

.lang-row__name {
  flex: 1;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #1a1a1a;
  font-weight: 400;
}

.lang-row[aria-checked="true"] .lang-row__name {
  font-weight: 600;
}

.lang-row__check {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  display: none;
}

.lang-row[aria-checked="true"] .lang-row__check {
  display: block;
}

.lang-screen__cta {
  align-self: stretch;
  background: #1b6b8a;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12.5px 16px;
  border: 0;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  line-height: 22.5px;
  color: #ffffff;
  cursor: pointer;
}

.lang-screen__cta:active {
  background: var(--color-primary-dark);
}

/* ============== SCREEN 1.5 — WEATHER ============== */

.weather-screen {
  background: #ffffff;
  display: flex;
  flex-direction: column;
  font-synthesis: none;
  padding-top: max(env(safe-area-inset-top), 24px);
  padding-bottom: max(env(safe-area-inset-bottom), 24px);
}

.weather-screen__header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px 8px 24px;
  gap: 12px;
}

.weather-screen__location {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: #f2f5f0;
  border-radius: var(--radius-pill);
  padding: 5px 11px;
}

.weather-screen__location span {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: #3d6b4f;
}

.weather-screen__tabs {
  flex: 1;
  min-width: 0;
  padding: 0;
  justify-content: flex-start !important;
}

.weather-screen__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 0 24px;
}
.weather-screen__body::-webkit-scrollbar { display: none; }

/* More specific than .weather-panel (two classes vs one) — wins regardless of order */
.weather-screen .weather-panel {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  gap: 16px;
  padding: 8px 0 24px;
}

.weather-screen .wind-rose {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
}

.weather-screen__footer {
  flex-shrink: 0;
  padding: 16px 24px;
  display: flex;
  flex-direction: column;
}

/* ============== SCREEN 2 — RUTES (bottom-sheet layout) ============== */

/* Screen container — overflow:clip so the bottom sheet can extend to the
   bottom edge without triggering a scrollbar on the screen itself. */
.routes-screen {
  background: #ffffff;
  width: 100%;
  font-synthesis: none;
  overflow: clip;
  /* position:absolute + inset:0 comes from .screen in base.css — do NOT
     override it here, or absolutely-positioned children lose their anchor. */
}

/* Scrollable routes list — sits behind the bottom sheet.
   padding-bottom reserves room so the last route card clears the sheet. */
.routes-screen__main {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-top: max(env(safe-area-inset-top), 24px);
  padding-inline: 24px;
  padding-bottom: max(env(safe-area-inset-bottom), 48px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  box-sizing: border-box;
}
.routes-screen__main::-webkit-scrollbar { display: none; }

.routes-screen__list-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 28px;
  line-height: 32px;
  color: #1a1a1a;
  margin: 0;
  align-self: flex-start;
}

/* ── Bottom sheet ──────────────────────────────────────────────────────────── */

.routes-sheet {
  --routes-collapsed-peek: 72px; /* handle pill + header visible when collapsed */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  height: 50vh;
  background: #ffffff;
  border-top-left-radius: var(--radius-sheet);
  border-top-right-radius: var(--radius-sheet);
  box-shadow: var(--shadow-sheet);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: transform 320ms var(--ease-entrance);
  will-change: transform;
}

.routes-sheet.is-collapsed {
  transform: translateY(calc(50vh - var(--routes-collapsed-peek)));
}

.routes-sheet.is-dragging {
  transition: none;
}

/* Drag handle — same pill pattern as the POI sheet */
.routes-sheet__handle {
  flex-shrink: 0;
  width: 100%;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  background: transparent;
  border: none;
  padding: 0;
  touch-action: none;
  user-select: none;
}
.routes-sheet__handle:active { cursor: grabbing; }
.routes-sheet__handle::before {
  content: "";
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: #d1d5d4;
  transition: background 160ms var(--ease-entrance);
}
.routes-sheet__handle:hover::before,
.routes-sheet__handle:focus-visible::before { background: #b5bab9; }
.routes-sheet__handle:focus-visible { outline: none; }

/* Sheet header — tabs + location chip in one row */
.routes-sheet__header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 16px 4px 24px;
  gap: 12px;
}

.routes-sheet__location {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: #f2f5f0;
  border-radius: var(--radius-pill);
  padding: 5px 11px;
}
.routes-sheet__location span {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: #3d6b4f;
}

/* Tab bar — inline with the location chip */
.routes-sheet__tabs {
  flex: 1;
  min-width: 0;
  padding: 0;
  justify-content: flex-start !important;
}

/* Scrollable content area */
.routes-sheet__scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.routes-sheet__scroll::-webkit-scrollbar { display: none; }

/* ── Weather tabs (shared by old layout + new sheet) ─────────────────────── */

.weather-tabs {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

.weather-tab {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #5b5b5b;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  padding: 4px 16px;
  cursor: pointer;
  transition:
    background 200ms var(--ease-entrance),
    border-color 200ms var(--ease-entrance),
    color 200ms var(--ease-entrance),
    font-weight 200ms var(--ease-entrance);
  font-weight: 400;
}

.weather-tab.is-active {
  background: #f5f8f1;
  border-color: #e2e6dd;
  color: #1b6b8a;
  font-weight: 600;
}

/* Weather panels inside the sheet — no aspect-ratio lock, stack naturally */
.routes-sheet .weather-panel {
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
  padding: 0 24px 24px;
}

/* Panels shared between contexts */
.weather-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.weather-panel.is-hidden { display: none; }

/* Wind rose — full-width 1:1 square spanning the sheet width */
.routes-sheet .wind-rose {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
}

.wind-rose {
  display: block;
  width: 100%;
  height: 100%;
}

/* ── Wind banner ─────────────────────────────────────────────────────────── */

.wind-banner {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.wind-banner__summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.wind-banner__speed {
  font-family: var(--font-body);
  font-size: 20px;
  font-weight: 600;
  color: #1a1a1a;
  white-space: nowrap;
}

.wind-banner__recommendation {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  color: #374151;
  line-height: 24px;
  margin: 0;
}

.wind-banner__flourish {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  color: #6b7280;
  font-style: italic;
  line-height: 20px;
  margin: 0;
}

/* ── Wind intensity tag (pill badge) ─────────────────────────────────────── */

.wind-tag {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-pill);
  padding: 3px 12px;
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 600;
  white-space: nowrap;
}

.wind-tag--suau      { color: #005B2B; background: #E6F2EB; }
.wind-tag--moderat   { color: #4E5404; background: #EEF0D9; }
.wind-tag--fort      { color: #683E06; background: #F5E9DC; }
.wind-tag--molt-fort { color: #630805; background: #F4DEDD; }

.route-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-align: center;
  font: inherit;
  color: inherit;
}

.route-tile--a {
  width: 376px;
  flex-shrink: 0;
}

.route-tile--b {
  align-self: stretch;
}

.route-tile__media {
  background-position: 50%;
  background-size: cover;
  flex-shrink: 0;
}

.route-tile--a .route-tile__media {
  width: 376px;
  height: 184px;
}

.route-tile--b .route-tile__media {
  width: 100%;
  aspect-ratio: 483 / 278;
}

.route-tile__text {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.route-tile__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  line-height: 32px;
  color: #1b6b8a;
  margin: 0;
}

.route-tile__desc {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #5b5b5b;
  text-align: center;
  width: 200px;
  margin: 0;
}

/* ============== SCREEN 3 — ROUTE DETAIL (Paper AZH-0 / AQB-0) ============== */

.route-screen {
  background: #ffffff;
  font-synthesis: none;
  overflow: hidden;
}

.route-screen__header {
  /* Floats over the scroll area so content slides under it and the
     backdrop-filter actually has something to blur. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: max(env(safe-area-inset-top), 16px) 24px 8px;
  min-height: 56px;
  isolation: isolate;
}

/* Visual layer — white veil + backdrop blur, masked at the bottom so the
   blur boundary feathers out smoothly instead of hitting a hard edge. The
   pseudo-element holds these so the back/next buttons above stay crisp. */
.route-screen__header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: linear-gradient(
    0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 1) 100%
  );
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  mask-image: linear-gradient(
    180deg,
    #000 0%,
    #000 65%,
    transparent 100%
  );
  -webkit-mask-image: linear-gradient(
    180deg,
    #000 0%,
    #000 65%,
    transparent 100%
  );
  pointer-events: none;
}

.route-screen__back {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  flex-shrink: 0;
}

.route-screen__change {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #f5f8f1;
  border: 2px solid #e2e6dd;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  flex-shrink: 0;
  padding: 0;
}

.route-screen__scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Room for the now-absolute header at the top — keeps the heading from
     being hidden under it on first paint. */
  padding-top: calc(max(env(safe-area-inset-top), 16px) + 48px);
  padding-bottom: 128px;
}
.route-screen__scroll::-webkit-scrollbar {
  display: none;
}

.route-screen__section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 24px;
}

.route-screen__heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 28px;
  line-height: 32px;
  color: #1a1a1a;
  margin: 16px 0 8px;
}

/* Map widget — satellite illustration + dashed SVG route overlay + play btn.
   Negative margins bust out of the parent section's 24px side padding so the
   illustration bleeds edge-to-edge. */
.route-map {
  position: relative;
  width: calc(100% + 48px);
  margin-left: -24px;
  margin-right: -24px;
  height: 169px;
  background-position: 50%;
  background-size: cover;
  overflow: hidden;
}

/* "Mapa" pill — sits immediately to the left of the play-button on the
   bottom-right edge of the map widget. Same 40 px height as the play button;
   8 px gap between the two. Pill-shaped because it carries text + icon. */
.map-button {
  position: absolute;
  right: 72px;
  bottom: 8px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px 0 8px;
  background: #f5f8f1;
  border: 2px solid #e2e6dd;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  flex-shrink: 0;
  cursor: pointer;
}

.map-button__icon {
  display: inline-flex;
  width: 24px;
  height: 24px;
}

.map-button__label {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  color: #1a1a1a;
}

.play-button {
  position: absolute;
  /* Anchored to the bottom-right of the map strip; 8px clearance from the
     bottom edge so both buttons float above the image rather than sitting on
     the very edge. */
  right: 24px;
  bottom: 8px;
  width: 48px;
  height: 48px;
  background: #f5f8f1;
  border: 2px solid #e2e6dd;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* Pseudo-element ring sits on top of the button border — keep the icon
     above it via stacking context. */
  isolation: isolate;
}

.play-button__icon {
  position: relative;
  display: inline-flex;
  width: 24px;
  height: 24px;
  z-index: 1;
}

/* Animated border. A pseudo-element sized exactly like the button (matching
   border-radius + corner-shape so it traces the same squircle) gets its
   `border` redrawn from invisible → teal via a conic-gradient mask. While
   `.is-playing` we sweep the gradient angle around 360° in 3s, matching the
   POI carousel cadence. The element is purely visual: pointer-events:none so
   clicks pass through to the button. */
.play-button::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  pointer-events: none;
  padding: 2px;
  background: conic-gradient(from -90deg, #1b6b8a var(--play-ring, 0deg), transparent 0deg);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 200ms var(--ease-exit);
}

.play-button.is-playing::after {
  opacity: 1;
  animation: play-ring-fill 3s linear infinite;
}

@property --play-ring {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@keyframes play-ring-fill {
  from {
    --play-ring: 0deg;
  }
  to {
    --play-ring: 360deg;
  }
}

/* Horizontal POI carousel — scoped to .route-screen because screen 4
   reuses .poi-card / .poi-carousel for its own (full-screen) card. */
.route-screen .poi-carousel {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 16px 0;
  margin: 0 -24px;
  padding-inline: 24px;
  position: static;
  inset: auto;
}
.route-screen .poi-carousel::-webkit-scrollbar {
  display: none;
}

.route-screen .poi-card {
  flex: 0 0 260px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  scroll-snap-align: start;
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
}

.route-screen .poi-card.is-hidden {
  display: none;
}

.route-screen .poi-card__heading {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  align-self: stretch;
}

.route-screen .poi-card__number {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 30px;
  color: #1b6b8a;
}

.route-screen .poi-card__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 30px;
  color: #1a1a1a;
}

.route-screen .poi-card__media {
  width: 220px;
  height: 220px;
  max-width: none;
  align-self: auto;
  position: static;
  border-radius: 12px;
  background-position: 50%;
  background-size: cover;
  background-color: transparent;
  flex-shrink: 0;
  overflow: hidden;
}

.route-screen .poi-card__desc {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #5b5b5b;
  text-align: center;
  width: 200px;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Recorda */
.recorda-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 24px 0;
}

.recorda-section__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 28px;
  line-height: 32px;
  letter-spacing: -0.02em;
  color: #1a1a1a;
  margin: 0 0 8px;
}

.recorda-section__body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #5b5b5b;
  margin: 0;
}

/* Fixed bottom CTA */
.route-screen__cta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 12px;
  padding: 32px 24px calc(env(safe-area-inset-bottom, 0px) + 24px);
  background-image: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 1) 14.69%,
    rgba(255, 255, 255, 1) 100%
  );
}

.duration-chip {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  width: 138px;
  height: 48px;
  padding: 12px 16px;
  background: #f5f8f1;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  outline: 2px solid #e2e6dd;
  outline-offset: -1px;
  border: 0;
  flex-shrink: 0;
}

.duration-chip__label {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  line-height: 22.5px;
  color: #1a1a1a;
  text-align: center;
}

.start-button {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding: 12px 16px;
  background: #1b6b8a;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  border: 0;
}

.start-button:active {
  background: var(--color-primary-dark);
}

.start-button__label {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  line-height: 22.5px;
  color: #ffffff;
}

/* Duración bottom sheet (overlay) */
.duration-sheet {
  position: absolute;
  inset: 0;
  z-index: 10;
  background: rgba(28, 28, 28, 0.25);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms var(--ease-entrance);
}

.duration-sheet.is-open {
  opacity: 1;
  pointer-events: auto;
}

.duration-sheet__card {
  position: absolute;
  left: 24px;
  right: 24px;
  bottom: 128px;
  background: #ffffff;
  border-radius: 24px;
  corner-shape: var(--corner-shape);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-shadow: 0 0 8px -2px rgba(0, 0, 0, 0.15),
    0 0 40px -19px rgba(0, 0, 0, 0.2);
  transform: translateY(24px);
  transition: transform 240ms var(--ease-entrance);
}

.duration-sheet.is-open .duration-sheet__card {
  transform: none;
}

.duration-sheet__title {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #6f7273;
  margin: 0;
}

.duration-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.duration-row {
  display: flex;
  align-items: center;
  width: 100%;
  height: 56px;
  padding: 0 8px;
  gap: 16px;
  background: transparent;
  border: 0;
  text-align: left;
}

.duration-row__label {
  flex: 1;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 20px;
  color: #1a1a1a;
}

.duration-row.is-selected .duration-row__label {
  font-weight: 700;
}

.duration-row__check {
  display: none;
  flex-shrink: 0;
}

.duration-row.is-selected .duration-row__check {
  display: inline-flex;
}

/* ============== SCREEN 4 — POI DETAILS (Paper A1P-1) ============== */

/* Container — Paper A1P-1 outer frame: 402x874, teal placeholder, flex col,
   space-between, gap 24, overflow clip. The teal acts as the map placeholder
   before Mapbox tiles arrive. */
.poi-screen {
  background: #b1e2df;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  overflow: clip;
  font-synthesis: none;
}

/* Layer 1 — full-bleed map (sits behind everything else). */
.poi-screen__map {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: #b1e2df;
}

.poi-screen__map .mapboxgl-canvas {
  outline: none;
}

/* Layer 2 — header. Paper: align center, space-between, padding 16/24/0/24. */
.poi-screen__header {
  position: relative;
  z-index: 2;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: max(env(safe-area-inset-top), 16px) 24px 0;
  box-sizing: border-box;
}

/* Back button — 48×48, #F5F8F1 bg, 2px #E2E6DD border, full squircle. */
.poi-screen__back {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #f5f8f1;
  border: 2px solid #e2e6dd;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  flex-shrink: 0;
  padding: 0;
}

/* Map-layer toggle — Paper map-stack-layer, same chip as the back button.
   On the POI screen it lives inside the card so it transforms with the sheet
   (drag and collapse alike), sitting 12px above the card's top edge. On the
   standalone map screen it has no sheet to hug, so it anchors 24px above the
   viewport bottom instead. */
.poi-screen__map-toggle {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #f5f8f1;
  border: 2px solid #e2e6dd;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  flex-shrink: 0;
  padding: 0;
  z-index: 3;
}

.poi-screen__card .poi-screen__map-toggle {
  position: absolute;
  top: -60px;
  right: 24px;
}

.poi-screen.map-screen > .poi-screen__map-toggle {
  position: absolute;
  bottom: 24px;
  right: 24px;
}

/* Layer 3 — POI card. iOS-style bottom sheet:
   - Fixed at 60vh so the map always keeps the top 40%-ish band visible.
   - Internal content scrolls; only the handle + title row stay pinned.
   - .is-collapsed translates the whole card down by (height - peek), so
     just the header strip remains on screen. --poi-collapsed-peek is set
     by JS after each buildCard, measured from the title row's bottom. */
.poi-screen__card {
  --poi-collapsed-peek: 96px;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 4px 24px 24px;
  height: 60vh;
  max-height: 60vh;
  background: #ffffff;
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  corner-shape: var(--corner-shape);
  box-sizing: border-box;
  box-shadow: 0 -8px 24px rgba(10, 30, 50, 0.18);
  transition: transform 320ms var(--ease-entrance);
  will-change: transform;
  user-select: none;
}

.poi-screen__card.is-collapsed {
  transform: translateY(calc(60vh - var(--poi-collapsed-peek)));
}

/* While the handle is being dragged, freeze the transition so the sheet
   tracks the finger 1:1. The snap-to-target animation re-enables when the
   inline transform is cleared in pointerup. */
.poi-screen__card.is-dragging {
  transition: none;
}

/* Drag-handle pill at the top of the sheet. Tap (or Enter) toggles the
   collapsed state. The hit target is a full-width 20px row so a finger
   doesn't have to land on the 4-px pill exactly. */
.poi-card__handle {
  flex-shrink: 0;
  width: 100%;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  background: transparent;
  border: none;
  padding: 0;
  /* iOS would otherwise treat a vertical drag as a page scroll attempt; we
     want the drag handler to own the gesture end-to-end. */
  touch-action: none;
  user-select: none;
}

.poi-card__handle:active {
  cursor: grabbing;
}

.poi-card__handle::before {
  content: "";
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: #d1d5d4;
  transition: background 160ms var(--ease-entrance);
}

.poi-card__handle:hover::before,
.poi-card__handle:focus-visible::before {
  background: #b5bab9;
}

.poi-card__handle:focus-visible {
  outline: none;
}

/* Scrollable body — everything below the title row lives here so the sheet
   stays clamped at 60vh while long descriptions can scroll. Children
   stretch by default so the description fills the full sheet width; the
   media block opts out via its own `align-self: center` so the photo stays
   centered without growing past its native 354×354 frame. */
.poi-card__scroll {
  flex: 1;
  min-height: 0;
  align-self: stretch;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
  -webkit-overflow-scrolling: touch;
}

.poi-card-row {
  align-self: stretch;
  box-sizing: border-box;
}

.poi-card__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/* Paper: heading group — display flex, align start, gap 8. */
.poi-card__heading {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}

/* Paper: "01" — Recoleta 500 20/30, #2F6B89. */
.poi-card__number {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 30px;
  color: #2f6b89;
  flex-shrink: 0;
}

/* Paper: name — Recoleta 500 20/30, #1A1A1A. */
.poi-card__name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 30px;
  color: #1a1a1a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Nav cluster sits to the right of the heading. Both prev and next chips are
   the same shape as the back button; the cluster is conditionally populated
   (no chips on the first POI's left slot, no chip on the last POI's right
   slot). We deliberately do not render disabled chips. */
.poi-card__nav {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.poi-card__nav-btn {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #f5f8f1;
  border: 2px solid #e2e6dd;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  flex-shrink: 0;
  padding: 0;
  cursor: pointer;
}

/* Paper: 354x354 frame with overflow clip. The frame is a button so a tap
   opens the full-screen gallery. The inner stack swaps slides every 3s
   (or on video `ended`); a dots row sits at the bottom edge per Paper F4O-0. */
.poi-card__media {
  width: 354px;
  height: 354px;
  max-width: 100%;
  align-self: center;
  position: relative;
  border-radius: 16px;
  corner-shape: var(--corner-shape, round);
  overflow: hidden;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  background: var(--color-surface-tinted, #ebf4f8);
  cursor: pointer;
  /* Drop the default touchscreen tap highlight — looks like a CSS bug on iOS */
  -webkit-tap-highlight-color: transparent;
}

.poi-carousel {
  position: absolute;
  inset: 0;
}

.poi-carousel__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 360ms var(--ease-entrance);
  pointer-events: none;
}

.poi-carousel__slide.is-active {
  opacity: 1;
  pointer-events: auto;
}

.poi-carousel__img,
.poi-carousel__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Prevent iOS double-tap-to-zoom turning the carousel into a magnifier */
  pointer-events: none;
}

/* Paper F4O-0: 12×12 active dot, 8×8 inactive dots, 8 px gap, centred 15 px
   above the frame's bottom edge. Subtle drop shadow so the dots read on
   light photo regions. */
.poi-carousel__dots {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 1;
}

.poi-carousel__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #e2e6dd;
  box-shadow: 0 0 3px -1px rgba(0, 0, 0, 0.15);
  cursor: pointer;
  transition: width 220ms var(--ease-entrance),
    height 220ms var(--ease-entrance),
    background 220ms var(--ease-entrance);
}

.poi-carousel__dot.is-active {
  width: 12px;
  height: 12px;
  background: #ffffff;
}

/* Description — DM Sans 16/24, #5B5B5B. Spans the full scroll width so the
   sheet's fixed height has room to breathe; the 200px Paper width clipped
   long Catalan blocks. */
.poi-card__description {
  align-self: stretch;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  color: #5b5b5b;
  white-space: pre-wrap;
}

/* Distance rows — added on top of Paper. Same DM Sans / muted body as the
   description, lighter label color for the leading word. */
.poi-card__distances {
  align-self: stretch;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 1px solid #e2e6dd;
  padding-top: 16px;
}

.poi-card__distance {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 20px;
}

.poi-card__distance-label {
  color: #5b5b5b;
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.poi-card__distance-value {
  color: #1a1a1a;
  font-weight: 600;
  flex-shrink: 0;
}

/* Mapbox markers — 24×24 thumbnails using each POI's first image, with a
   2-px white ring (via box-shadow spread so it doesn't fight the circle's
   border-radius) and a soft drop shadow so they look gently lifted off
   the map. The active marker grows to 48×48, keeps a 4-px white ring,
   and gets a larger, more diffused shadow to read as more elevated. */
.poi-marker {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: #d1d5d4;
  background-size: cover;
  background-position: 50%;
  box-shadow: 0 0 0 2px #ffffff, 0 2px 6px rgba(10, 30, 50, 0.18);
  cursor: pointer;
  transition:
    width 220ms var(--ease-entrance),
    height 220ms var(--ease-entrance),
    box-shadow 220ms var(--ease-entrance);
}

.poi-marker.is-active {
  width: 48px;
  height: 48px;
  box-shadow: 0 0 0 4px #ffffff, 0 14px 32px 2px rgba(10, 30, 50, 0.2);
  z-index: 1;
}

/* ============== SCREEN 5 — POI GALLERY (Paper A1P-1) ============== */

/* Full-screen viewer over the POI sheet. White ground; X-close + POI name
   header (16 top, 24 sides), large square image area (full-width, 1:1),
   '1/N' counter row. Swipe between slides on the media area. */
.gallery-screen {
  background: #ffffff;
  align-items: stretch;
  justify-content: space-between;
  gap: 24px;
  padding: max(env(safe-area-inset-top), 16px) 24px
    max(env(safe-area-inset-bottom), 24px);
  font-synthesis: none;
}

/* A flex spacer wrapping the media so the header pins to the top and the
   counter pins to the bottom while the media block stays vertically centred
   without stretching past its natural height. */
.gallery-screen__media-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
}

.gallery-screen__header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.gallery-screen__close {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 0;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
}

.gallery-screen__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 30px;
  color: #1a1a1a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0;
}

/* Gallery image frame — width fills the page gutter (max ~356), height fills
   the remaining vertical space between header and counter. Inside each slide,
   the <img> is sized by its natural aspect (width:100%, height:auto): if the
   resulting height exceeds the frame the overflow is clipped center-aligned
   via the flex `align-items: center`, so portrait shots show in full unless
   the viewport runs out of vertical room — and only ever lose top/bottom,
   never the center. Landscape shots letterbox naturally with empty bands. */
.gallery-screen__media {
  align-self: center;
  width: 100%;
  max-width: 356px;
  max-height: 100%;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  overflow: hidden;
  position: relative;
  background: #f3f4f1;
  /* Touch swipes belong to the slide changer — prevent the browser from
     stealing them for back-navigation gestures. */
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
}

.gallery-screen__stack {
  position: relative;
  width: 100%;
  /* The active slide owns the height: an image at width:100% sets it via its
     natural aspect ratio, and inactive slides are absolutely-positioned so
     they don't stretch the container. */
}

.gallery-screen__slide {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  opacity: 0;
  transition: opacity 280ms var(--ease-entrance);
  pointer-events: none;
  position: absolute;
  inset: 0;
}

.gallery-screen__slide.is-active {
  position: relative;
  inset: auto;
  opacity: 1;
  pointer-events: auto;
}

.gallery-screen__img,
.gallery-screen__video {
  width: 100%;
  height: auto;
  max-height: none;
  display: block;
  /* No object-fit — the image sits at its natural aspect ratio (width 356,
     height = 356/aspect). When taller than the slide, the parent's
     overflow:hidden + align-items:center crops top and bottom equally. */
}

.gallery-screen__counter {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
  color: #1a1a1a;
  flex-shrink: 0;
}

/* ============== CODE ENTRY SCREEN (3.1a) ============== */

.code-entry-screen {
  background: #e8ece4;
  padding-top: max(env(safe-area-inset-top), 16px);
  padding-bottom: max(env(safe-area-inset-bottom), 24px);
}

.code-entry-screen__header {
  height: 56px;
  display: flex;
  align-items: center;
  padding: 0 20px;
  flex-shrink: 0;
}

/* Body pushes all content to the bottom so the title/boxes/button sit
   in the lower portion of the screen — matching the Paper design. */
.code-entry-screen__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 0 24px;
  gap: 20px;
}

.code-entry-screen__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  font-weight: 500;
  line-height: 1.3;
  color: var(--color-text-primary);
  margin: 0;
}

.code-entry-screen__digits {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
}

.code-entry-screen__digit {
  width: 100%;
  aspect-ratio: 1;
  max-height: 58px;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-control);
  corner-shape: var(--corner-shape);
  background: #ffffff;
  font-family: var(--font-body);
  font-size: 22px;
  font-weight: 600;
  color: var(--color-text-primary);
  text-align: center;
  outline: none;
  transition: border-color 160ms var(--ease-entrance),
    box-shadow 160ms var(--ease-entrance);
  -webkit-tap-highlight-color: transparent;
}

.code-entry-screen__digit:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(27, 107, 138, 0.15);
}

.code-entry-screen__digit:not(:placeholder-shown) {
  border-color: var(--color-text-primary);
}

.code-entry-screen__error {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  color: var(--color-emergency);
  margin: -8px 0 0;
}

.code-entry-screen__continue:disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* ============== ROUTE SUMMARY SCREEN (3.1b) ============== */

.summary-screen {
  background: #e8ece4;
}

.summary-screen__header {
  padding: max(env(safe-area-inset-top), 16px) 24px 0;
  height: calc(max(env(safe-area-inset-top), 16px) + 56px);
  display: flex;
  align-items: flex-end;
  flex-shrink: 0;
}

.summary-screen__content {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 24px 24px 0;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.summary-screen__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  font-weight: 500;
  color: var(--color-text-primary);
  margin: 0;
}

.summary-screen__stat-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.summary-stat-card {
  background: #ffffff;
  border-radius: 16px;
  corner-shape: var(--corner-shape);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  box-shadow: var(--shadow-card);
}

.summary-stat-card__label {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  color: var(--color-text-secondary);
}

.summary-stat-card__value {
  font-family: var(--font-body);
  font-size: 22px;
  font-weight: 700;
  color: var(--color-text-primary);
  line-height: 1.2;
}

.summary-screen__poi-heading {
  font-family: var(--font-display);
  font-size: var(--fs-heading-sm);
  font-weight: 500;
  color: var(--color-text-primary);
  margin: 0;
}

/* Vertical timeline — a hairline runs behind the dots connecting them. */
.summary-timeline {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}

.summary-timeline::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 18px;
  bottom: 18px;
  width: 2px;
  background: var(--color-text-primary);
  opacity: 0.12;
}

.summary-timeline__item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 0;
  position: relative;
}

.summary-timeline__dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-text-primary);
  flex-shrink: 0;
  z-index: 1;
}

/* Open circle for the fixed start point */
.summary-timeline__dot--open {
  background: transparent;
  border: 2.5px solid var(--color-text-primary);
}

.summary-timeline__name {
  flex: 1;
  font-family: var(--font-body);
  font-size: var(--fs-body-md);
  color: var(--color-text-primary);
  line-height: 1.4;
}

.summary-timeline__remove {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
  border-radius: 50%;
  flex-shrink: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
  transition: color 120ms var(--ease-entrance),
    background 120ms var(--ease-entrance);
}

.summary-timeline__remove:active {
  color: var(--color-text-primary);
  background: rgba(0, 0, 0, 0.06);
}

.summary-screen__footer {
  padding: 16px 24px max(env(safe-area-inset-bottom), 24px);
  flex-shrink: 0;
}

/* Tile pre-cache overlay */
.preparing-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.preparing-overlay[hidden] {
  display: none;
}

.preparing-overlay__card {
  background: #ffffff;
  border-radius: var(--radius-sheet);
  padding: 32px 24px;
  margin: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
  text-align: center;
  box-shadow: var(--shadow-sheet);
}

.preparing-overlay__title {
  font-family: var(--font-display);
  font-size: var(--fs-heading-sm);
  font-weight: 500;
  color: var(--color-text-primary);
  margin: 0;
}

.preparing-overlay__subtitle {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  color: var(--color-text-secondary);
  margin: 0;
}

.preparing-overlay__bar-track {
  width: 100%;
  height: 8px;
  background: var(--color-border);
  border-radius: 4px;
  overflow: hidden;
  margin-top: 8px;
}

.preparing-overlay__bar-fill {
  height: 100%;
  background: var(--color-primary);
  border-radius: 4px;
  transition: width 300ms linear;
  width: 0%;
}

.preparing-overlay__pct {
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
  margin: 0;
}

/* Toast notification */
.summary-toast {
  position: absolute;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: rgba(26, 26, 26, 0.88);
  color: #ffffff;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  padding: 10px 20px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 240ms var(--ease-entrance),
    transform 240ms var(--ease-entrance);
  pointer-events: none;
}

.summary-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ============== NAVIGATE SCREEN ============== */

.navigate-screen {
  background: #b1e2df; /* teal placeholder while map tiles load */
  overflow: hidden;
  font-synthesis: none;
}

/* ── Floating header (over map) ── */
.nav-float-header {
  position: absolute;
  top: max(env(safe-area-inset-top), 16px);
  left: 16px;
  right: 16px;
  z-index: 4;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  pointer-events: none;
}

/* ── Map top gradient scrim — lifts header text off the map tiles ── */
.nav-map-gradient {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 150px;
  background: linear-gradient(to bottom, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
  z-index: 3;
  pointer-events: none;
}

/* Shared squircle button — matches poi-screen__back and poi-screen__map-toggle exactly */
.nav-map-btn {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  box-shadow: 0 0 8px -2px rgba(26, 26, 26, 0.15);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border: 2px solid #e2e6dd;
  border-radius: 50%;
  corner-shape: var(--corner-shape);
  padding: 0;
  cursor: pointer;
  pointer-events: auto;
}

/* Right-side vertical button stack */
.nav-map-btn-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: auto;
}

/* SOS button — danger colors from Paper */
.nav-sos-btn {
  background: #f0bcb4;
  border-color: #7d0001;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 800;
  color: #7d0001;
  letter-spacing: 0.04em;
}

.nav-float-header__poi {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  pointer-events: none;
  min-width: 0;
}

.nav-float-poi-label {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  color: rgba(26, 26, 26, 0.55);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.nav-float-poi-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  color: #1a1a1a;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ── Map (fills full screen) ── */
.navigate-map-view {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.navigate-map-view .mapboxgl-canvas {
  outline: none;
}

/* ── Dades overlay (over map, under panel) ── */
.navigate-dades-view {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: #e8ece4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 32px;
  padding: 32px 24px 280px;
  box-sizing: border-box;
}

.dades-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}

.dades-block--poi {
  background: #ffffff;
  border-radius: var(--radius-card);
  corner-shape: var(--corner-shape);
  padding: 16px 20px;
  box-shadow: var(--shadow-card);
  align-self: stretch;
}

.dades-time {
  font-family: var(--font-display);
  font-size: 72px;
  font-weight: 500;
  line-height: 1;
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
}

.dades-time.is-overtime {
  color: var(--color-emergency);
}

.dades-remaining {
  font-family: var(--font-body);
  font-size: var(--fs-body-md);
  color: var(--color-text-secondary);
}

.dades-poi-label {
  font-family: var(--font-body);
  font-size: var(--fs-body-md);
  color: var(--color-text-secondary);
}

.dades-poi-dist {
  font-family: var(--font-body);
  font-size: 28px;
  font-weight: 700;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
}

.dades-base-label {
  font-family: var(--font-body);
  font-size: var(--fs-body-md);
  color: var(--color-text-secondary);
  text-align: center;
}

/* ── Bottom wrapper: toggle floats above the white panel ── */
.nav-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  pointer-events: none;
}

/* ── Mapa / Dades pill toggle (sits above the white panel) ── */
.nav-tab-toggle {
  display: flex;
  background: rgba(240, 240, 240, 0.96);
  backdrop-filter: blur(8px);
  box-shadow: 0 0 8px -2px rgba(26, 26, 26, 0.15);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 50px;
  padding: 4px;
  pointer-events: auto;
}

/* ── White bottom panel ── */
.navigate-screen__panel {
  width: 100%;
  background: #ffffff;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 0 8px -2px rgba(26, 26, 26, 0.15);
  padding-bottom: max(env(safe-area-inset-bottom), 16px);
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.08);
  pointer-events: auto;
}

.nav-tab-btn {
  height: 40px;
  padding: 0 28px;
  border: none;
  border-radius: 50px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: background 160ms var(--ease-entrance),
    color 160ms var(--ease-entrance),
    box-shadow 160ms var(--ease-entrance);
}

.nav-tab-btn.is-active {
  background: #ffffff;
  color: var(--color-text-primary);
  font-weight: 600;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}

/* ── Stats row ── */
.nav-stats-row {
  display: flex;
  align-items: flex-start;
  padding: 14px 20px 0;
}

.nav-stat {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.nav-stat + .nav-stat {
  padding-left: 12px;
  margin-left: 12px;
}

.nav-stat__label {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  color: rgba(26, 26, 26, 0.70);
  white-space: nowrap;
}

.nav-stat__value {
  font-family: var(--font-body);
  font-size: 24px;
  font-weight: 600;
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.nav-stat__unit {
  font-size: 16px;
  font-weight: 600;
}

.nav-stat__value.is-overtime {
  color: var(--color-emergency);
}

.nav-stat__value-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.nav-direction-badge {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  color: var(--color-text-secondary);
  background: #f0f0f0;
  border-radius: 50px;
  padding: 2px 8px;
  white-space: nowrap;
}

/* ── Timeline — scrolling distance ruler ── */
.nav-timeline {
  padding: 28px 0 0;
}

.nav-timeline__scroll {
  position: relative;
  height: 60px; /* 32px line area + 28px label area */
  overflow: hidden;
}

/* Track translates in JS so the current position sits under the needle. */
.nav-timeline__track {
  position: absolute;
  top: 0;
  left: 0;
  height: 60px;
  will-change: transform;
}

/* Layer 1 — tick marks only, pinned to top of track */
.nav-timeline__lines {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
}

/* Layer 2 — POI labels, pinned below the lines layer */
.nav-timeline__pois {
  position: absolute;
  top: 32px;
  left: 0;
}

/* Each tick: fixed 16px slot for a single line */
.nav-timeline__tick {
  flex: 0 0 16px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

/* Regular 20 m tick mark */
.nav-timeline__line {
  width: 2px;
  height: 8px;
  background: #d0d0d0;
}

/* POI tick — taller and darker */
.nav-timeline__line--poi {
  width: 2px;
  height: 28px;
  background: #3a3a3a;
}

/* POI label — absolutely placed in the pois layer at its tick x-position */
.nav-timeline__poi-label {
  position: absolute;
  top: 4px;
  white-space: nowrap;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-secondary);
}

/* Fixed red needle — always centered, shows current position */
.nav-timeline__needle {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--color-emergency);
  border-radius: 1px;
  z-index: 1;
  pointer-events: none;
}

/* ── Kayak illustration ── */
.nav-kayak {
  width: 100%;
  height: 104px;
  overflow: hidden;
  margin-top: 8px;
}

.nav-kayak img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 45%;
}

/* ── Overtime banner ── */
.navigate-screen__overtime-banner {
  position: absolute;
  top: max(calc(env(safe-area-inset-top) + 72px), 88px);
  left: 12px;
  right: 12px;
  z-index: 5;
  padding: 10px 16px;
  border-radius: var(--radius-pill);
  background: var(--color-emergency);
  color: #ffffff;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  box-shadow: 0 2px 10px rgba(217, 58, 43, 0.28);
  pointer-events: none;
}

/* ── GPS-denied banner ── */
.navigate-screen__gps-banner {
  position: absolute;
  bottom: 290px;
  left: 16px;
  right: 16px;
  z-index: 5;
  padding: 12px 16px;
  border-radius: var(--radius-pill);
  background: rgba(26, 26, 26, 0.88);
  color: #ffffff;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 500;
  text-align: center;
}

/* ── Threshold flash banner ── */
.nav-threshold-banner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, calc(-50% + 12px));
  z-index: 10;
  background: rgba(26, 26, 26, 0.88);
  color: #ffffff;
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 600;
  padding: 20px 28px;
  border-radius: var(--radius-card);
  corner-shape: var(--corner-shape);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms var(--ease-entrance),
    transform 240ms var(--ease-entrance);
}

.nav-threshold-banner.is-visible {
  opacity: 1;
  transform: translate(-50%, -50%);
}

/* ── Map POI markers ── */
.nav-poi-marker {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #ffffff;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 2px #ffffff, 0 2px 8px rgba(10, 30, 50, 0.25);
  cursor: pointer;
  transition: width 200ms var(--ease-entrance),
    height 200ms var(--ease-entrance);
}

.nav-poi-marker.is-active {
  width: 40px;
  height: 40px;
  box-shadow: 0 0 0 3px #ffffff, 0 4px 16px rgba(10, 30, 50, 0.3);
  z-index: 1;
}

/* ── Live position marker (blue pulsing dot) ── */
.nav-position-marker {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #2563eb;
  box-shadow: 0 0 0 3px #ffffff, 0 2px 8px rgba(37, 99, 235, 0.35);
  position: relative;
}

.nav-position-marker::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  background: rgba(37, 99, 235, 0.2);
  animation: nav-position-pulse 2s ease-out infinite;
}

@keyframes nav-position-pulse {
  0%   { transform: scale(0.5); opacity: 0.8; }
  100% { transform: scale(1);   opacity: 0; }
}

/* .nav-recenter-btn is now a .nav-map-btn inside .nav-float-header — no separate positioning needed */

/* ── End-session confirm dialog ── */
.nav-end-dialog {
  max-width: 320px;
  width: calc(100% - 48px);
  border: 0;
  border-radius: var(--radius-card);
  corner-shape: var(--corner-shape);
  padding: 24px;
  box-shadow: var(--shadow-sheet);
}

.nav-end-dialog::backdrop {
  background: rgba(28, 28, 28, 0.35);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.nav-end-dialog__text {
  font-family: var(--font-body);
  font-size: var(--fs-body-md);
  color: var(--color-text-primary);
  margin: 0 0 20px;
  text-align: center;
}

.nav-end-dialog__actions {
  display: flex;
  gap: 12px;
}
