/* ==========================================================================
 * Home page — frosted-glass chrome floating over a full-bleed, interactive
 * Mapbox view.  The map cycles through three showcase locations (aerial /
 * topo / hybrid) and blurs during each "warp" transition (see home.js § 8).
 *
 * Shared "liquid glass" surface (matches the configure page's `.cfg-panel`):
 *   background: rgba(255, 255, 255, 0.55)
 *   backdrop-filter: blur(20px) saturate(150%)
 *   border: 1px solid rgba(255, 255, 255, 0.45)
 * ========================================================================== */

/* The base template renders a `.site-header` breadcrumb for the home page.
 * This page ships its own frosted `.home-topbar`, so hide the default. */
body.home-page > .site-header {
  display: none;
}

/* Lock the home page to the viewport so the floating chrome stays put and
 * nothing scrolls the document. */
body.home-page {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  /* Clean, empty branded backdrop — no hero photo, no dark overlay. */
  background-image: none;
  background-color: #eef1f5;
  color: #171c1e;
}

/* Drop the legacy dark hero overlay; the backdrop is light now. */
body.home-page::before {
  display: none;
}

/* ===========================================================================
 * Hero cinematic animation stage
 *
 * Sits between .home-bg (z:0) and .home-map (z:1), occupying z:2.
 * Plays a "map being drawn on paper" sequence (GSAP) before fading out
 * and revealing the live Mapbox carousel underneath.
 *
 * Layer order inside the stage (low → high):
 *   .hero-paper         — cream parchment sheet + crease SVG
 *   .hero-map-frame     — clipped viewport showing map layers
 *     .hero-layer--terrain  — WebP base imagery (opacity 0→1)
 *     .hero-layer--contours — SVG contour paths  (stroke draw)
 *     .hero-layer--rivers   — SVG river paths    (stroke draw)
 *     .hero-layer--roads    — SVG road paths     (stroke draw)
 *     .hero-layer--labels   — SVG place labels   (opacity stamp)
 *   .hero-scene-label   — floating location badge
 * =========================================================================== */
.hero-stage {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  /* Start hidden; home.js fades in once SVGs are loaded */
  opacity: 0;
  /* Paper-cream backdrop so the stage itself looks like parchment */
  background: #f2ece0;
}

.hero-stage.is-ready {
  opacity: 1;
  transition: opacity 0.6s ease;
}

.hero-stage.is-exiting {
  opacity: 0;
  transition: opacity 1.2s ease;
}

/* ---------------------------------------------------------------------------
 * Paper sheet — full-bleed cream surface with subtle warm gradient and
 * fold-crease SVG overlay.
 * ------------------------------------------------------------------------- */
.hero-paper {
  position: absolute;
  inset: 0;
  background:
    /* Subtle paper-grain noise texture via CSS (no extra image) */
    radial-gradient(ellipse at 30% 20%, rgba(255,248,236,0.6) 0%, transparent 60%),
    radial-gradient(ellipse at 75% 80%, rgba(240,228,208,0.5) 0%, transparent 55%),
    linear-gradient(160deg, #f5f0e4 0%, #ede5d0 45%, #e4d8c0 100%);
  /* Paper edge shadow */
  box-shadow: inset 0 0 80px rgba(160,120,60,0.08);
}

.hero-paper__crease {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
 * Map frame — centred viewport that clips the map layers.
 * Slightly smaller than the full screen so the paper border shows.
 * ------------------------------------------------------------------------- */
.hero-map-frame {
  position: absolute;
  /* Slightly inset from the paper edges to show a "paper margin" */
  top: 4%;
  left: 4%;
  right: 4%;
  bottom: 13%;  /* leave room for footer chrome */
  overflow: hidden;
  border-radius: 2px;
  /* Thin inked border like a printed map boundary */
  box-shadow:
    0 0 0 1px rgba(100,70,30,0.25),
    0 0 0 4px rgba(100,70,30,0.06),
    0 4px 24px rgba(0,0,0,0.18);
  /* Subtle inner vignette so edges look printed */
  background: #e8dfc8;
}

/* ---------------------------------------------------------------------------
 * Hero scenes — stacked full-size containers; only the active one is shown.
 * home.js manages visibility via GSAP (opacity).
 * ------------------------------------------------------------------------- */
.hero-scene {
  position: absolute;
  inset: 0;
  opacity: 0;
  /* Prevent hidden scenes from being interactive */
  pointer-events: none;
}

/* .hero-scene--active: opacity managed entirely by GSAP (no CSS rule needed) */

/* ---------------------------------------------------------------------------
 * Hero layers — stacked within each scene (terrain → SVG features → labels).
 * All positioned absolutely and stretched to fill the frame.
 * ------------------------------------------------------------------------- */
.hero-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Terrain base — raster WebP image */
.hero-layer--terrain {
  object-fit: cover;
  /* Initial opacity; GSAP animates to 1 */
  opacity: 0;
  /* Warm paper tint blended over the terrain for the "printed map" look */
  mix-blend-mode: multiply;
  filter: saturate(0.75) sepia(0.15) brightness(1.05);
}

/* SVG feature layers — filled by JS with inline SVG content */
.hero-layer--contours,
.hero-layer--rivers,
.hero-layer--roads,
.hero-layer--labels {
  overflow: visible;
}

/* All SVGs inside the layer divs get the same sizing */
.hero-layer svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Contour paths start invisible; GSAP animates stroke-dashoffset */
.hero-layer--contours path,
.hero-layer--contours line,
.hero-layer--contours ellipse {
  opacity: 0;
  stroke-dasharray: var(--path-len, 2000);
  stroke-dashoffset: var(--path-len, 2000);
}

/* River paths — same stroke draw approach */
.hero-layer--rivers path,
.hero-layer--rivers circle {
  opacity: 0;
  stroke-dasharray: var(--path-len, 2000);
  stroke-dashoffset: var(--path-len, 2000);
}

/* Road paths */
.hero-layer--roads path {
  opacity: 0;
  stroke-dasharray: var(--path-len, 2000);
  stroke-dashoffset: var(--path-len, 2000);
}

/* Labels start invisible; GSAP fades/scales them in */
.hero-layer--labels text,
.hero-layer--labels g {
  opacity: 0;
}

/* ---------------------------------------------------------------------------
 * Scene location badge — bottom-left of the map frame, above paper.
 * Fades in with the labels layer.
 * ------------------------------------------------------------------------- */
.hero-scene-label {
  position: absolute;
  left: calc(4% + 16px);
  bottom: calc(13% + 14px);
  background: rgba(30, 20, 10, 0.72);
  color: #f5f0e4;
  font-family: var(--mt-font-primary, "Georgia", serif);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 3px;
  opacity: 0;
  pointer-events: none;
  backdrop-filter: blur(4px);
}

/* ---------------------------------------------------------------------------
 * Reduced motion — skip cinematic draw-on; show static snapshot instead.
 * home.js checks `prefers-reduced-motion` and skips to Mapbox immediately.
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .hero-stage {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * Empty branded backdrop (replaces the old banner.jpg hero) — a soft light
 * gradient with a single centred MyTopo logo in the upper area.
 * ------------------------------------------------------------------------- */
.home-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(160deg, #f4f6f9 0%, #e4e9ef 55%, #d7dde4 100%);
}

/* ---------------------------------------------------------------------------
 * Floating MyTopo logo — sits OVER the map (the old top bar is gone).  A soft
 * circular frosted halo (`__glass`) keeps the logo legible above any imagery;
 * the blur fades out at the edges via a radial mask so there's no hard box.
 * The whole thing is a link to the MyTopo Map Store.
 * ------------------------------------------------------------------------- */
.home-logo {
  position: fixed;
  top: 20%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Above the map (1) and the banner (5); below the bottom chrome (20). */
  z-index: 8;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 38px 72px;
  text-decoration: none;
  pointer-events: auto;
  transition: transform 160ms ease;
}

.home-logo:hover,
.home-logo:focus-visible {
  outline: none;
  transform: translate(-50%, -50%) scale(1.03);
}

/* No surrounding disc/halo — the logo sits directly on the map.  The layer
 * is kept (empty/transparent) only so the focus ring has something to attach
 * to without affecting layout. */
.home-logo__glass {
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  background: transparent;
}

.home-logo:focus-visible .home-logo__glass {
  box-shadow: 0 0 0 2px rgba(12, 119, 190, 0.55);
}

.home-logo__img {
  position: relative;
  width: min(300px, 58vw);
  height: auto;
  user-select: none;
  pointer-events: none;
  /* Subtle white glow so the dark mark separates from the map underneath. */
  filter: drop-shadow(0 1px 4px rgba(255, 255, 255, 0.7));
}

/* ---------------------------------------------------------------------------
 * Cart button — fixed to the top-right corner over the map.  A rounded,
 * frosted-glass disc using the same translucency / blur / border tokens as
 * the search card and the configure page's side panel, so the chrome feels
 * consistent across pages.
 * ------------------------------------------------------------------------- */
.home-cart {
  position: fixed;
  top: 20px;
  right: 20px;
  /* Above the map (1) and banner (5); in line with the logo (8), below the
   * bottom chrome (20). */
  z-index: 8;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 9999px;
  color: #171c1e;
  text-decoration: none;
  /* Same frosted-glass surface as the search card / configure options panel. */
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.45);
  box-shadow: 0 8px 32px rgba(15, 23, 42, 0.22);
  pointer-events: auto;
  transition: transform 160ms ease, background 160ms ease;
}

/* Empty cart — the button is hidden entirely (home.js toggles `hidden` from
 * the localStorage cart count).  Needed because `.home-cart` sets an explicit
 * `display`, which would otherwise override the native `[hidden]` behaviour. */
.home-cart[hidden] {
  display: none;
}

.home-cart:hover {
  background: rgba(255, 255, 255, 0.7);
  transform: scale(1.05);
}

.home-cart:focus-visible {
  outline: none;
  box-shadow: 0 8px 32px rgba(15, 23, 42, 0.22),
    0 0 0 2px rgba(12, 119, 190, 0.55);
}

/* Red count badge on the cart disc — a pill that hugs the top-right of the
 * button.  Toggled/filled by home.js; `[hidden]` keeps it out of the layout
 * while the cart is empty.  min-width == height so a single digit stays a
 * perfect circle, widening into a pill for 2+ digits / "99+". */
.home-cart__badge {
  position: absolute;
  top: -4px;
  right: -4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 9999px;
  background: #e11d48;
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  border: 2px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 2px 6px rgba(225, 29, 72, 0.45);
  pointer-events: none;
}

.home-cart__badge[hidden] {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Full-bleed interactive map — sits above the branded backdrop and fades in
 * once the first style has loaded.  The user pans/zooms with the cursor;
 * there are no Mapbox nav controls.
 * ------------------------------------------------------------------------- */
.home-map {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: auto;
  opacity: 0;
  /* Fade-in on first load + ease the blur/scale during each location warp. */
  transition: filter 460ms ease, transform 460ms ease, opacity 460ms ease;
}

.home-map.is-ready {
  opacity: 1;
}

/* "Warp" — the previous location blurs and rushes forward (scale up) before
 * the next style/center is jumped in underneath the blur, then settles. */
.home-map.is-warping {
  filter: blur(18px) brightness(1.06) saturate(1.12);
  transform: scale(1.14);
}

/* Keep Mapbox's attribution/logo above the map's own stacking context. */
.home-map .mapboxgl-ctrl-bottom-right,
.home-map .mapboxgl-ctrl-bottom-left {
  z-index: 2;
}

.banner {
  position: relative;
  z-index: 5;
  flex: 1 1 auto;
  width: 100%;
  min-height: 30vh;
  background: transparent;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 80px 5% 96px;
  overflow: visible;
}

.banner__content {
  position: relative;
  z-index: 1;
  max-width: 1100px;
  width: 100%;
  text-align: center;
  color: #ffffff;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.banner__title {
  margin: 0;
  margin-block-end: 0.25em;
  padding-block-start: 0.75em;
  color: var(--mt-banner-yellow);
  font-weight: 700;
  font-size: 24px;
  line-height: 32px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}

.banner__subtitle {
  margin: 0;
  font-style: italic;
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  max-width: 900px;
}

.banner__footnote {
  margin: 0;
  font-style: italic;
  font-size: 14px;
  line-height: 1.5;
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
}

.banner__search {
  width: 100%;
  display: flex;
  justify-content: center;
}

.search-row {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  max-width: 980px;
  /* Same frosted-glass surface as the top bar / configure options panel. */
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  padding: 14px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(15, 23, 42, 0.22);
  /* Re-enable interaction on the actual control (its parents are
     click-through so the map stays pannable around it). */
  pointer-events: auto;
  /* Shared element for the cross-document morph into the configure
     page's options panel (see base.css → `@view-transition`). */
  view-transition-name: vt-panel;
}

/* -----------------------------------------------------------------------
 * Custom Modus 2.0 search input.  The Mapbox SearchBoxCore (headless) API
 * drives suggestions/retrieve; the visible UI below is ours entirely so it
 * stays consistent with the Modus inputs (coord fields, etc.).
 * --------------------------------------------------------------------- */
.search-row__input {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  background: var(--mt-input-bg);
  border: 1px solid var(--mt-input-border-default);
  border-radius: var(--mt-input-radius);
  height: 42px;
  padding: 0 12px;
  gap: 8px;
  min-width: 0;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.search-row__input:has(input:not(:placeholder-shown)) {
  border-color: var(--mt-input-border-filled);
}

.search-row__icon {
  color: var(--mt-input-placeholder);
  flex-shrink: 0;
}

.search-row__field {
  flex: 1 1 auto;
  border: 0;
  outline: 0;
  background: transparent;
  font-family: var(--mt-font-primary);
  font-size: 14px;
  color: var(--mt-input-color);
  height: 100%;
  min-width: 0;
}

.search-row__field::placeholder {
  color: var(--mt-input-placeholder);
}

.search-row__clear {
  display: none;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--mt-input-placeholder);
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 120ms ease, color 120ms ease,
    transform 120ms ease;
}

.search-row__clear svg {
  display: block;
}

.search-row__input:has(.search-row__field:not(:placeholder-shown))
  .search-row__clear {
  display: inline-flex;
}

.search-row__clear:hover,
.search-row__clear:focus-visible {
  background-color: rgba(0, 0, 0, 0.08);
  color: var(--mt-input-color);
  outline: none;
}

.search-row__clear:active {
  background-color: rgba(0, 0, 0, 0.14);
  transform: scale(0.94);
}

.search-row__spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid #cbcdd6;
  border-top-color: #0c77be;
  animation: search-spin 720ms linear infinite;
  flex-shrink: 0;
  box-sizing: border-box;
}

.search-row__spinner[hidden] {
  display: none;
}

@keyframes search-spin {
  to {
    transform: rotate(360deg);
  }
}

.search-row__input:focus-within {
  border: 1px solid var(--mt-input-border-focus);
  outline: 2px solid var(--mt-input-shadow-focus);
  outline-offset: 3px;
  box-shadow: none;
}

.search-row__input.is-locked {
  background-color: #e9ecef;
  border-color: #cbcdd6;
  cursor: not-allowed;
}

.search-row__input.is-locked .search-row__field,
.search-row__input.is-locked .search-row__icon,
.search-row__input.is-locked .search-row__clear,
.search-row__input.is-locked .search-row__spinner {
  pointer-events: none;
}

.search-row__input.is-locked .search-row__field {
  color: #6a6e79;
  cursor: not-allowed;
}

.search-row__input.is-locked .search-row__field::placeholder {
  color: #b7b9c3;
}

.search-row__input.is-locked .search-row__icon {
  color: #b7b9c3;
}

.search-row__input.is-locked .search-row__clear {
  display: none !important;
}

/* -----------------------------------------------------------------------
 * Custom suggestions dropdown for SearchBoxCore.
 * Positioned absolute under the input wrapper so it doesn't push the lat
 * /long column or the banner footnote.
 * --------------------------------------------------------------------- */
.search-suggestions {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 60;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  background: #ffffff;
  border: 1px solid #cbcdd6;
  border-radius: 4px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  max-height: 320px;
  overflow-y: auto;
  font-family: var(--mt-font-primary);
  color: var(--mt-input-color);
}

.search-suggestions[hidden] {
  display: none;
}

.search-suggestion {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1.4;
  transition: background-color 80ms ease;
}

.search-suggestion + .search-suggestion {
  border-top: 1px solid #f1f1f6;
}

.search-suggestion__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
  /* Reset inherited `text-align: center` from .banner__content so the
     name/subtitle/context spans read left-to-right and ellipsis trims
     at the right edge.  The badge (sibling of __text) stays pinned
     right because it has flex-shrink: 0 and __text consumes the
     remaining width. */
  text-align: left;
}

.search-suggestion__name,
.search-suggestion__subtitle {
  color: var(--mt-input-color);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-suggestion__context {
  color: #6a6e79;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-suggestion__badge {
  flex-shrink: 0;
  align-self: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: #eef4fb;
  color: #0c77be;
  padding: 2px 6px;
  border-radius: 3px;
  border: 1px solid #cfe2f4;
}

.search-suggestion:hover,
.search-suggestion.is-active {
  background-color: #f1f1f6;
}

.search-suggestion.is-active {
  background-color: #e7f0fa;
}

.search-suggestions__empty,
.search-suggestions__error {
  padding: 10px 12px;
  font-size: 13px;
  color: #6a6e79;
  text-align: center;
}

.search-suggestions__error {
  color: #a30014;
}

.search-row__coords {
  display: flex;
  gap: 16px;
  flex-shrink: 0;
  align-items: flex-start;
}

.coord-field {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 134px;
}

.coord-input {
  background: var(--mt-input-bg);
  border: 1px solid var(--mt-input-border-default);
  border-radius: var(--mt-input-radius);
  height: 42px;
  width: 100%;
  padding: 0 12px;
  font-family: var(--mt-font-primary);
  font-size: 14px;
  color: var(--mt-input-color);
  outline: 0;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.coord-input::placeholder {
  color: var(--mt-input-placeholder);
}

.coord-input:not(:placeholder-shown) {
  border-color: var(--mt-input-border-filled);
}

.coord-input:focus {
  border: 1px solid var(--mt-input-border-focus);
  outline: 2px solid var(--mt-input-shadow-focus);
  outline-offset: 3px;
  box-shadow: none;
}

.coord-input.is-invalid {
  border: 1px solid var(--mt-input-border-invalid);
  outline: 0;
  box-shadow: none;
}

.coord-input.is-invalid:focus {
  border: 1px solid var(--mt-input-border-invalid);
  outline: 2px solid var(--mt-input-shadow-invalid);
  outline-offset: 3px;
  box-shadow: none;
}

.coord-input:disabled {
  background-color: #e9ecef;
  border-color: #cbcdd6;
  color: #6a6e79;
  cursor: not-allowed;
  pointer-events: none;
}

.coord-input:disabled::placeholder {
  color: #b7b9c3;
}

.coord-field.is-locked {
  cursor: not-allowed;
}

.coord-field__error {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  z-index: 5;
  font-size: 12px;
  line-height: 1.4;
  font-weight: 600;
  color: #8b0000;
  background: #fde2e4;
  border: 1px solid #f5c2c7;
  border-radius: 3px;
  padding: 2px 6px;
  text-shadow: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
  word-break: break-word;
}

.coord-field__error::before {
  content: "\26A0";
  margin-right: 4px;
  font-size: 11px;
}

.coord-input.is-invalid + .coord-field__error:not(:empty) {
  display: block;
}

@media (max-width: 960px) {
  .banner {
    padding-top: 60px;
    padding-bottom: 24px;
    min-height: auto;
    background-position: center;
  }

  .banner__title {
    font-size: 1.2rem;
    font-weight: 400;
    line-height: 1.4;
  }

  .banner__subtitle,
  .banner__footnote {
    font-size: 0.9rem;
  }

  .search-row {
    flex-direction: column;
    align-items: stretch;
  }

  .search-row__coords {
    justify-content: center;
  }
}

@media (max-width: 520px) {
  .search-row__coords {
    width: 100%;
    gap: 12px;
  }

  .coord-field {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
  }

  .coord-input {
    width: 100%;
  }
}

/* ---------------------------------------------------------------------------
 * Bottom chrome — auto-advance progress bar pinned on top of the frosted
 * footer.  The wrapper is click-through; the footer re-enables interaction
 * so the Mapbox attribution link stays usable.
 * ------------------------------------------------------------------------- */
.home-bottom {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  pointer-events: none;
}

/* Thin progress track — fills over the cycle interval, then resets when the
 * map warps to the next showcase location. */
.home-progress {
  position: relative;
  width: 100%;
  height: 8px;
  /* Same frosted-glass surface as the chrome (top bar / search / footer). */
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
  border-top: 1px solid rgba(255, 255, 255, 0.45);
  overflow: hidden;
}

.home-progress__fill {
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: left center;
  /* Bright white fill. */
  background: #ffffff;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.8);
  will-change: transform;
}

.site-footer {
  flex: 0 0 auto;
  pointer-events: auto;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  color: #171c1e;
  padding: 14px 32px;
  border-top: 1px solid rgba(255, 255, 255, 0.45);
}

.site-footer__copy {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  text-align: center;
  color: #171c1e;
  text-shadow: none;
}

.site-footer__link {
  color: #0c77be;
  text-decoration: none;
  border-bottom: 1px solid rgba(12, 119, 190, 0.4);
  transition: border-color 120ms ease, color 120ms ease;
}

.site-footer__link:hover,
.site-footer__link:focus-visible {
  border-bottom-color: #0c77be;
  outline: none;
}

@media (max-width: 520px) {
  .site-footer {
    padding: 12px 16px;
  }
}

.mode-hint {
  position: fixed;
  bottom: 88px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: #252a2e;
  color: #ffffff;
  padding: 10px 18px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 200ms ease, transform 200ms ease,
    visibility 200ms ease;
  z-index: 100;
  max-width: calc(100% - 32px);
  text-align: center;
}

.mode-hint.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

@media (max-width: 520px) {
  .mode-hint {
    white-space: normal;
    bottom: 72px;
  }
}
