/* SPINE/FONT FIX 2026-06-01 — locate does not import styles.css, so the
   @font-face block lives here (same convention as verified.html). Without it
   Signifier + Soehne fell back to Georgia/mono. */
@font-face { font-family: "Signifier"; src: url("/assets/Fonts/WOFF2/signifier-light.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: block; }
@font-face { font-family: "Signifier"; src: url("/assets/Fonts/WOFF2/signifier-light-italic.woff2") format("woff2"); font-weight: 300; font-style: italic; font-display: block; }
@font-face { font-family: "Signifier"; src: url("/assets/Fonts/WOFF2/signifier-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: block; }
@font-face { font-family: "Söhne"; src: url("/assets/Fonts/WOFF2/soehne-leicht.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: block; }
@font-face { font-family: "Söhne"; src: url("/assets/Fonts/WOFF2/soehne-buch.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: block; }
@font-face { font-family: "Soehne"; src: url("/assets/Fonts/WOFF2/soehne-leicht.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: block; }
@font-face { font-family: "Söhne Mono"; src: url("/assets/Fonts/WOFF2/soehne-mono-leicht.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: block; }
@font-face { font-family: "Söhne Mono"; src: url("/assets/Fonts/WOFF2/soehne-mono-buch.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: block; }
@font-face { font-family: "Soehne Mono"; src: url("/assets/Fonts/WOFF2/soehne-mono-leicht.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: block; }

/* ─────────────────────────────────────────────────────────────
   VAREN — /locate  ·  Design Annex full-page map experience
   Shell styles for the page layout. The map itself (palette,
   marker, zoom, compass, readout rows) reuses hud-map.css — no
   duplication of those rules here.
   ───────────────────────────────────────────────────────────── */

/* ── Reset / base ──────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  height: 100%;
  background: #0a0a0a;
  color: #F4F1EA;
  font-family: "Söhne Mono", "Soehne Mono", "SF Mono", Menlo, monospace;
  overflow: hidden; /* map fills the viewport — no page scroll */
}

/* ── CSS custom properties ─────────────────────────────────── */
:root {
  --gold:      #C8A96F;
  --gold-light: #E2CC9A;   /* hover lift of Command Gold — never white */
  --bone:      #F4F1EA;
  --bg:        #0a0a0a;
  /* Logo height — same fluid clamp used in thefield.html spine-pilot */
  --logo-h:    clamp(24px, 3.6vh, 36px);
  /* Spine — content left-aligns to the V-tip of the wordmark (logoH * 1.16048). */
  --spine-x:   calc(var(--logo-h) * 1.16048);
  /* Header area height: eyebrow + title + vertical padding */
  --header-h:  clamp(64px, 10vh, 96px);
  /* Readout panel height: 4 rows × ~1.55 line-height + padding */
  --readout-h: clamp(92px, 14vh, 128px);
  /* --footer-h lives in the VAREN unified footer v1 block at the end of this file */
}

/* ── Persistent logo — always shown (not phone-only on this page) ── */
/* Base .site-logo-link + .site-logo styles come from hud-map.css
   context via welcome.css if that sheet is loaded, but on this page
   we define them independently so there's no dependency on welcome.css. */
.locate-logo {
  display: block !important;  /* override welcome.css phone-only rule if ever loaded */
  position: fixed;
  /* Safe-area-inset-top: Dynamic Island / notch clearance. Portrait: top
     safe-area covers the island. Landscape: top ≈ 0 but left safe-area
     covers it — both axes handled. */
  top:  max(var(--logo-h), calc(env(safe-area-inset-top,  0px) + 16px));
  left: max(clamp(20px, 4vw, 32px), calc(env(safe-area-inset-left, 0px) + 16px));
  z-index: 20;
  text-decoration: none;
  line-height: 0;
  transition: opacity 0.18s ease;
}
.locate-logo:hover { opacity: 0.78; }
.locate-logo:focus-visible { outline: 1px solid var(--gold); outline-offset: 6px; }

.locate-logo .site-logo {
  height: var(--logo-h);
  width: auto;
  display: block;
  color: var(--bone);
}

/* ── Page header: eyebrow + title ──────────────────────────── */
.locate-header {
  position: fixed;
  /* Clear the logo on the left; right flush with safe-area-inset-right */
  top: max(calc(var(--logo-h) + 32px), calc(env(safe-area-inset-top, 0px) + var(--logo-h) + 20px));
  left: calc(max(clamp(20px, 4vw, 32px), calc(env(safe-area-inset-left, 0px) + 16px)) + var(--spine-x));
  right: max(clamp(20px, 4vw, 32px), calc(env(safe-area-inset-right, 0px) + 16px));
  z-index: 10;
  pointer-events: none;
}

.locate-eyebrow {
  font-family: "Söhne Mono", "Soehne Mono", "SF Mono", Menlo, monospace;
  font-size: clamp(0.55rem, 0.48rem + 0.22vw, 0.68rem);
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--gold);
  opacity: 0.82;
  margin-top: 0.5em;
  margin-bottom: 0;
  white-space: nowrap;
}

.locate-title {
  font-family: "Signifier", Georgia, "Times New Roman", serif;
  font-weight: 300;
  font-style: normal;
  font-size: clamp(1.6rem, 2.4vw + 1rem, 3.2rem);
  line-height: 1.06;
  letter-spacing: 0.003em;
  color: var(--bone);
}

/* ── Full-bleed map ─────────────────────────────────────────── */
.locate-map-wrap {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 100vh;
  height: 100dvh; /* iOS Safari: track the visible viewport, not the layout one */
  z-index: 1;
  background: var(--bg);
  overflow: hidden;
}

/* Mapbox GL container fills the entire viewport — same base contract as
   .hud-map__mapbox but without the card constraint. */
.locate-mapbox {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: var(--bg);
  z-index: 0;
  pointer-events: auto;
  touch-action: none; /* let Mapbox own all touch gestures */
}
/* Ensure Mapbox canvas and container don't block interaction */
.locate-mapbox .mapboxgl-canvas,
.locate-mapbox .mapboxgl-canvas-container {
  pointer-events: auto !important;
  outline: none;
}
/* Marker is decorative — events must pass through to the canvas */
.locate-mapbox .mapboxgl-marker {
  pointer-events: none !important;
}
/* Hide default Mapbox attribution + logo (attribution in footer per ToS) */
.locate-mapbox .mapboxgl-ctrl-attrib,
.locate-mapbox .mapboxgl-ctrl-logo,
.locate-mapbox .mapboxgl-ctrl-bottom-left { display: none !important; }

/* Status / loading indicator — centered over the map, same contract
   as .hud-map__status in hud-map.css. .is-ready fades it out. */
.locate-status {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(244, 241, 234, 0.4);
  background: var(--bg);
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
  pointer-events: none;
}

/* Static image fallback — shown if Mapbox fails. Hidden by default;
   JS sets aria-hidden="false" + removes .is-hidden on error. */
.locate-fallback {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none; /* hidden until JS surfaces it on error */
  align-items: center;
  justify-content: center;
  background: var(--bg);
}
.locate-fallback.is-visible {
  display: flex;
}
.locate-fallback-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.55; /* dim so readout panel stays legible */
}

/* Zoom controls — top-right of the viewport.
   Base button styles from .hud-map__zoom in hud-map.css.
   Position override: viewport-relative (not card-relative). */
.locate-zoom {
  position: absolute;
  /* Clear the top safe area + a breathing gap */
  top: max(calc(var(--logo-h) + 100px), calc(env(safe-area-inset-top, 0px) + 80px));
  right: max(16px, calc(env(safe-area-inset-right, 0px) + 12px));
  z-index: 5;
}

/* Dither entrance canvas — covers the map during the entrance and
   dissolves via the Brand Experience 8x8 Bayer grid (locate.js). */
#locate-dither {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}

/* Compass overlay — fills the full viewport, pointer-events: none */
.locate-compass {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  /* Frame ends above the footer so the S label is never covered */
  bottom: calc(var(--footer-h) + env(safe-area-inset-bottom, 0px));
  pointer-events: none;
  z-index: 3;
}
/* Cardinal points — true Soehne Mono spans (replaced the stretched SVG) */
.locate-compass__pt {
  position: absolute;
  font-family: "Söhne Mono", "Soehne Mono", "SF Mono", Menlo, monospace;
  font-weight: 300;
  font-size: 33px; /* 3x — tablets / laptops / desktops (Bryan 2026-06-05) */
  letter-spacing: 0.2em;
  color: rgba(200, 169, 111, 0.78);
  user-select: none;
}
/* Mobile portrait + mobile landscape keep the original 11px scale */
@media (max-width: 640px), (max-height: 500px) {
  .locate-compass__pt { font-size: 11px; font-weight: 400; }
}
.locate-compass__pt--n { top: 14px;   left: 50%; transform: translateX(-50%); }
.locate-compass__pt--s { bottom: 10px; left: 50%; transform: translateX(-50%); }
.locate-compass__pt--w { left: 14px;  top: 50%;  transform: translateY(-50%); }
.locate-compass__pt--e { right: 14px; top: 50%;  transform: translateY(-50%); }

/* ── Coordinate readout panel ──────────────────────────────── */
/* Fixed to the bottom; sits above the footer. Uses safe-area-inset-bottom
   so it clears the iPhone home indicator. The inner .hud-map__readout +
   .hud-map__row styles come from hud-map.css. */
.locate-readout {
  /* Left-side stacked HUD readout (Bryan 2026-06-04) — anchored bottom-left
     above the footer, inside the 100dvh bottom shell. Left edge aligns with
     the Design Annex title + eyebrow: hero left padding, plus the spine
     offset at >=700px (matches the spine-pilot .hero-line rule). */
  position: absolute;
  left: clamp(28px, 3vw, 56px);
  right: auto;
  top: auto;
  bottom: calc(var(--footer-h) + env(safe-area-inset-bottom, 0px) + clamp(14px, 2.5vh, 28px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  pointer-events: none;
  /* Never wider than the viewport minus the side margins */
  max-width: min(52ch, calc(100vw - (clamp(28px, 3vw, 56px) * 2)));
  /* UNCONDITIONAL hero clearance (Bryan caught the toggle on the logo a
     third time, in a viewport between our media buckets): the legend can
     never be taller than the space between the hero zone and the footer,
     at ANY viewport. The panel shrinks and scrolls internally. */
  max-height: calc(100dvh - var(--footer-h) - env(safe-area-inset-bottom, 0px) - 175px);
}
.locate-readout .locate-readout-inner {
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
@media (min-width: 700px) {
  .locate-readout {
    left: calc(clamp(28px, 3vw, 56px) + var(--spine-x));
    max-width: min(52ch, calc(100vw - (clamp(28px, 3vw, 56px) * 2) - var(--spine-x)));
  }
}

/* Show/hide toggle — same HUD button vocabulary as the zoom controls */
.locate-readout__toggle {
  appearance: none;
  pointer-events: auto;
  cursor: pointer;
  margin-bottom: 0.45rem;
  padding: 0.34rem 0.6rem;
  background: rgba(8, 8, 8, 0.78);
  border: 1px solid rgba(200, 169, 111, 0.45);
  color: var(--gold);
  font-family: "Söhne Mono", "Soehne Mono", "SF Mono", Menlo, monospace;
  font-size: 0.55rem;
  font-weight: 300;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}
.locate-readout__toggle:hover {
  background: rgba(200, 169, 111, 0.12);
  border-color: var(--gold);
}
.locate-readout__toggle:focus-visible { outline: 1px solid var(--gold); outline-offset: 3px; }

/* Collapsed state — panel hidden, toggle chip remains */
.locate-readout.is-collapsed .locate-readout-inner { display: none; }
.locate-readout.is-collapsed .locate-readout__toggle { margin-bottom: 0; }

.locate-readout-inner {
  /* Vertical stack, left-aligned, gold hairline on the left edge.
     Translucent blurred backdrop keeps the readout legible over the
     bright map greens (same surface treatment as the footer). */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.1rem;
  text-align: left;
  border-top: none;
  border-right: none;
  border-left: 1px solid rgba(200, 169, 111, 0.35);
  padding: 0.55rem 0.95rem 0.55rem 0.9rem;
  overflow: hidden; /* clips content while the show/hide height tween runs */
  background: rgba(10, 10, 10, 0.66);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Rows use the CANONICAL .hud-map__row grid from hud-map.css
   (grid-template-columns: 64px 1fr) — true table columns: labels
   left-aligned, values left-aligned beside them. Only add wrapping
   so long values (LOC) break inside their column instead of
   clipping past the viewport edge. */
.locate-readout-inner .hud-map__row { white-space: normal; }
.locate-readout-inner .hud-map__value {
  /* No mid-token breaks (an address would never split "NC" into N / C).
     Wrapping happens only at the real spaces between .nb segments, so
     the break order is: before "NC /// 28374" first, then before
     "PINEHURST :" on narrower windows. */
  overflow-wrap: normal;
  word-break: keep-all;
  min-width: 0;
}
.locate-readout-inner .nb { white-space: nowrap; }

/* ── Site footer ────────────────────────────────────────────── */
/* The footer bar + bottom shell are the sitewide unified footer —
   rules live in the "VAREN unified footer v1" block at the END of
   this file (single source for every page's inlined/shared copy). */

/* ── Mapbox attribution (ToS compliance) ───────────────────── */
/* Text attribution below the readout satisfies Mapbox ToS when the
   logo is hidden. The footer already carries enough context; a
   dedicated line lives in the readout's bottom border area. */

/* ── Responsive — mobile (≤640px wide or ≤500px tall) ─────── */
@media (max-width: 640px), (max-height: 500px) {
  :root {
    --logo-h:    clamp(22px, 3vh, 30px);
    --header-h:  clamp(56px, 9vh, 72px);
    --readout-h: clamp(80px, 16vh, 100px);
  }

  /* Header adjustments: smaller type, tighter spacing */
  .locate-eyebrow { font-size: 0.55rem; letter-spacing: 0.16em; }
  .locate-title   { font-size: clamp(1.2rem, 4.5vw, 1.8rem); }

  /* Readout panel: tighter label column + font on phones */
  .locate-readout-inner {
    gap: 0;
    padding: 0.5rem 0.75rem 0.5rem 0.7rem;
  }
  .locate-readout-inner .hud-map__row {
    grid-template-columns: 56px 1fr;
    font-size: 0.66rem;
  }


  /* Zoom controls: larger tap targets for fingers */
  .locate-zoom button { width: 36px; height: 36px; font-size: 18px; }

  /* Zoom position: pull in from the right edge on very narrow phones */
  .locate-zoom {
    top: max(100px, calc(env(safe-area-inset-top, 0px) + 72px));
    right: max(12px, calc(env(safe-area-inset-right, 0px) + 10px));
  }
}

/* Extra-small phones (≤360px wide) — readout grid uses minimal columns */
@media (max-width: 360px) {
  .locate-readout-inner .hud-map__row {
    grid-template-columns: 48px 1fr;
    font-size: 0.64rem;
  }
  .locate-title { font-size: 1.15rem; }
}

/* ── Landscape phone / short viewport (height ≤ 500px) ─────── */
@media (max-height: 500px) {
  /* Open legend must never climb into the hero (Bryan caught the toggle
     covering the VAREN logo in landscape — twice). Root cause of the
     recurrence: flexbox min-height:auto kept the panel at content height,
     overflowing the old max-height cap upward. Fix: pin the aside to a
     hard BAND below the compressed hero (top + bottom), bottom-justify
     the content, and let the panel shrink (min-height:0) + scroll. */
  .locate-readout {
    /* Match the hero text's left edge BY FORMULA: island-aware hero
       padding + the spine offset the title carries at >=700px wide. */
    left: calc(max(44px, env(safe-area-inset-left, 0px) + 16px) + var(--spine-x));
  }
  /* Readout: keep the SAME tabbed column table as portrait (labels and
     values each share one left edge); just tighten the type. The legend
     is collapsed by default on phones, so vertical space only matters
     while the user has it open. */
  .locate-readout-inner .hud-map__row {
    font-size: 0.62rem;
    grid-template-columns: 48px 1fr;
  }
  /* Compass: hide on very short viewports to give map maximum area */
  .locate-compass { display: none; }
  /* Eyebrow: hide to compress the header */
  .locate-eyebrow { display: none; }
  .locate-title   { font-size: 1rem; }
}

/* ── LOC re-center control in the legend ── */
.locate-readout-inner .hud-map__value.loc-recenter {
  pointer-events: auto;
  cursor: pointer;
  position: relative;
  transition: color 0.25s ease;
}
.locate-readout-inner .hud-map__value.loc-recenter::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}
.locate-readout-inner .hud-map__value.loc-recenter:hover,
.locate-readout-inner .hud-map__value.loc-recenter:focus-visible {
  color: var(--gold-light, #E2CC9A);
}
.locate-readout-inner .hud-map__value.loc-recenter:hover::after,
.locate-readout-inner .hud-map__value.loc-recenter:focus-visible::after {
  transform: scaleX(1);
}
.locate-readout-inner .hud-map__value.loc-recenter:focus-visible { outline: none; }

/* ── Course name chip (Phase C) — legend-toggle button vocabulary ── */
.course-chip {
  position: fixed;
  top: 0; left: 0;
  z-index: 30;
  background: rgba(8, 8, 8, 0.85);
  border: 1px solid rgba(200, 169, 111, 0.55);
  color: var(--gold);
  font-family: "Söhne Mono", "Soehne Mono", "SF Mono", Menlo, monospace;
  font-size: 0.6rem;
  font-weight: 300;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1;
  padding: 0.4rem 0.65rem;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  opacity: 0;
  transform: translateY(4px);
  /* Motion rule: ease in AND out — nothing pops */
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.course-chip.is-visible { opacity: 1; transform: translateY(0); }

/* ── Right-click "© VAREN" tooltip — verbatim spec from welcome.css ── */
.varen-context-tooltip {
  position: fixed;
  top: 0;
  left: 0;
  background: #f4f1ea;
  color: #0b0b0b;
  font-family: "Soehne Mono", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 7px 11px;
  border: 1px solid rgba(11, 11, 11, 0.08);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.34);
  pointer-events: none;
  z-index: 99999;
  opacity: 0;
  transform: translate(12px, -8px);
  transition: opacity 0.18s ease-in;
  white-space: nowrap;
  user-select: none;
}
.varen-context-tooltip.is-visible { opacity: 1; transition: opacity 0.18s ease-in; }
.varen-context-tooltip.is-fading  { opacity: 0; transition: opacity 0.55s ease-out; }

/* ── Reduced motion ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  /* Marker pulse animation is defined in hud-map.css; that media
     query already disables it. No additional rules needed here. */
  .locate-logo, .locate-header { transition: none !important; }
}

/* VAREN unified footer v1 — source: css/locate.css */
:root {
  /* Footer height — reserved band for the dark blurred bar */
  --footer-h:  calc(clamp(36px, 6vh, 52px) + 1.05rem); /* reserve tracks the 1.5rem bottom pad (was 0.45rem) */
}
/* Bottom shell — fixed, 100dvh tall. On iOS Safari portrait the layout
   viewport is taller than the visible one while the address bar shows;
   absolute children anchored to this shell's bottom land at the VISIBLE
   bottom instead of off-screen. (Wiki: mobile-image-overlay-pattern /
   front-end-obstruction-class.) Scene pages only — flow pages render
   the footer in-flow and never use this class. */
.locate-bottom-shell {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 100vh;
  height: 100dvh;
  z-index: 11;
  pointer-events: none;
}
.locate-footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 11;
  /* Owner 2026-06-11: >=24px clear below the coordinate line — bottom
     pad steps to 1.5rem (the rem-scale spacing step closest to 24px). */
  padding: 0.45rem clamp(0.75rem, 3vw, 2rem) calc(1.5rem + env(safe-area-inset-bottom, 0px));
  text-align: center;
  font-family: "Söhne Mono", "Soehne Mono", "SF Mono", Menlo, monospace;
  font-size: clamp(0.52rem, 0.46rem + 0.12vw, 0.66rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(244, 241, 234, 0.45);
  background: rgba(10, 10, 10, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  pointer-events: none;
  user-select: none;
}
.locate-footer .footer-seg { display: inline; white-space: nowrap; }
.locate-footer .footer-sep { display: inline; margin: 0 0.55em; opacity: 0.85; }
.locate-footer .coord-stamp {
  display: block;
  margin-top: 0.2rem;
  font-size: clamp(0.48rem, 0.42rem + 0.1vw, 0.6rem);
  letter-spacing: 0.03em;
  text-transform: none;
  color: rgba(244, 241, 234, 0.28);
  pointer-events: auto;
}
.locate-footer a {
  pointer-events: auto;
  color: inherit;
  text-decoration: none;
  /* >=24px tap target (WCAG 2.5.8) without changing visual type size:
     pad the hit area, cancel the box growth with matching negative
     margins so baselines and the mobile colon-wrap are unchanged. */
  display: inline-block;
  padding: 8px 4px;
  margin: -8px -4px;
}
.locate-footer a:hover { color: rgba(244, 241, 234, 0.6); }
@media (max-width: 640px), (max-height: 500px) {
  :root {
    /* Wrapped flex footer runs 2-3 lines on phones — reserve real height */
    --footer-h:  calc(clamp(56px, 8vh, 68px) + 0.95rem); /* reserve tracks the 1.5rem bottom pad (was 0.55rem) */
  }
  /* Footer wrap — canonical fix mirrored from welcome.css v8.30/8.31
     ("overflow at right edge": no whitespace between the span tags for
     the layout engine to break at; flex-wrap breaks lines directly). */
  .locate-footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: baseline;
    row-gap: 0.1em;
    font-size: 8.5px;
    letter-spacing: 0.08em;
    line-height: 1.55;
    padding: 0.55rem 0.5rem calc(1.5rem + env(safe-area-inset-bottom, 0px));
  }
  .locate-footer .footer-seg { white-space: nowrap; }
  .locate-footer .footer-sep { margin: 0 0.28em; opacity: 0.7; }
  .locate-footer .coord-stamp {
    flex-basis: 100%;
    text-align: center;
    font-size: 8px;
    margin-top: 0.3rem;
    letter-spacing: 0.02em;
  }
}
/* end VAREN unified footer v1 */

/* ── THE CRADLE — course index panel (2026-07-02) ─────────────
   Bottom-right mirror of .locate-readout: same toggle chip
   (.locate-readout__toggle is reused on the button), same hud-map__row
   vocabulary inside, gold hairline on the RIGHT edge, right-aligned
   stack. Course rows are <button>s so the list is keyboard-operable;
   the label column carries a two-digit index, the value column the
   course name. Collapsed default is decided in locate.js (phones +
   sub-900px windows). */
.locate-cradle {
  position: absolute;
  right: clamp(28px, 3vw, 56px);
  left: auto;
  top: auto;
  bottom: calc(var(--footer-h) + env(safe-area-inset-bottom, 0px) + clamp(14px, 2.5vh, 28px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-end;
  pointer-events: none;
  max-width: min(38ch, calc(100vw - (clamp(28px, 3vw, 56px) * 2)));
  /* Height cap: same unconditional clearance rule as the readout, with a
     DEEPER top reserve (230px vs 175px) because the cradle shares the
     right column with the zoom cluster and 55 rows always fill the panel
     to its cap. The cap itself (with its never-vanish floor) lives in
     the "Never-vanish floors" block near the end of this file — ONE
     source for the formula. Scrolls internally. */
}
.locate-cradle .locate-cradle-inner {
  /* .hud-map__readout carries flex: 0 0 auto — with 55 course rows the
     panel MUST be allowed to shrink to the aside's max-height cap and
     scroll internally, or it overflows upward past the hero (caught
     2026-07-02 in the local harness). */
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* The panel owns every pixel it covers (Bryan device review
     2026-07-02): without this, wheel/touch over non-button pixels fell
     through the aside's pointer-events:none to the map canvas and
     ZOOMED THE MAP instead of scrolling the list. contain also stops
     scroll-chaining at the list's ends. */
  pointer-events: auto;
  overscroll-behavior: contain;
  /* Scroll affordance in the HUD language (Bryan asked for a simple,
     visible bar): standards properties for Firefox/Chrome, ::-webkit-
     scrollbar below for Safari. Thin gold thumb, bare track. */
  scrollbar-width: thin;
  scrollbar-color: rgba(200, 169, 111, 0.45) rgba(244, 241, 234, 0.06);
}
.locate-cradle-inner::-webkit-scrollbar { width: 4px; }
.locate-cradle-inner::-webkit-scrollbar-track { background: rgba(244, 241, 234, 0.06); }
.locate-cradle-inner::-webkit-scrollbar-thumb { background: rgba(200, 169, 111, 0.45); }
.locate-cradle-inner::-webkit-scrollbar-thumb:hover { background: rgba(200, 169, 111, 0.7); }
.locate-cradle.is-collapsed .locate-cradle-inner { display: none; }
.locate-cradle.is-collapsed .locate-cradle__toggle { margin-bottom: 0; }

.locate-cradle-inner {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.1rem;
  text-align: left;
  border-left: none;
  border-right: 1px solid rgba(200, 169, 111, 0.35);
  padding: 0.55rem 0.9rem 0.55rem 0.95rem;
  overflow: hidden; /* clips content while the show/hide height tween runs */
  background: rgba(10, 10, 10, 0.66);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Category header rows — gold, spaced like a section stamp */
.locate-cradle__cat {
  margin-top: 0.35rem;
}
.locate-cradle__cat:first-child { margin-top: 0; }
.locate-cradle__cat .hud-map__label { color: rgba(200, 169, 111, 0.55); }
.locate-cradle__cat .hud-map__value { color: var(--gold); letter-spacing: 0.14em; }

/* Course rows — real buttons wearing the hud-map__row grid */
.locate-cradle__course {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  pointer-events: auto;
  width: 100%;
}
.locate-cradle__course .hud-map__label { color: rgba(154, 146, 133, 0.6); }
.locate-cradle__course .hud-map__value {
  color: #F4F1EA;
  transition: color 0.16s ease;
}
.locate-cradle__course:hover .hud-map__value,
.locate-cradle__course:focus-visible .hud-map__value { color: var(--gold); }
.locate-cradle__course:focus-visible { outline: 1px solid var(--gold); outline-offset: 2px; }
/* Map-hover mirror (Bryan 2026-07-02): hovering a course SHAPE on the
   map lays a translucent Command-Gold bar behind that course's whole
   line — the text-highlight treatment, eased in/out per the motion
   rule. locate.js toggles .is-map-hover from the same feature-state
   pipeline that lifts the shape. */
.locate-cradle__course {
  transition: background-color 0.25s ease;
  background-color: transparent;
}
.locate-cradle__course.is-map-hover {
  background-color: rgba(200, 169, 111, 0.18);
}
.locate-cradle__course.is-map-hover .hud-map__value { color: var(--gold); }

/* The list inherits the readout's row grid via .hud-map__readout on the
   panel; rows inside the injected list keep the canonical columns. */
.locate-cradle__list { display: flex; flex-direction: column; gap: 0.1rem; }
/* Category stamp + its first course form one unbreakable unit (widowed
   stamps at a column's foot — Bryan 2026-07-02). Mirrors the list's own
   stacking so the grouping is invisible in single-column mode. */
.locate-cradle__cathead {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  break-inside: avoid;
}

/* Two-column index on wide windows (Bryan 2026-07-02: "all the golf
   courses could be listed there"). CSS multicol: reading order runs down
   the first column then over; rows never split; a category stamp never
   strands at a column's foot. The panel widens to carry both columns —
   which is why the open-by-default / mutual-exclusion width moved to
   1200px in locate.js. */
@media (min-width: 900px) {
  .locate-cradle {
    max-width: min(640px, calc(100vw - (clamp(28px, 3vw, 56px) * 2)));
  }
  .locate-cradle__list {
    display: block;
    columns: 2;
    column-gap: 1.3rem;
  }
  .locate-cradle__cathead { gap: 0; } /* rows carry margins in column mode */
  .locate-cradle__list .hud-map__row {
    break-inside: avoid;
    margin-bottom: 0.06rem;
    /* two-digit index needs less runway than the DATA labels; a notch
       tighter type so all 55 rows balance inside the height cap at
       1440x900 without scrolling (the scrollbar stays for shorter
       windows). */
    grid-template-columns: 34px 1fr;
    font-size: 0.68rem;
    line-height: 1.4; /* vs the readout's 1.55 — the density that lets
                         all 55 balance inside the cap at 1440x900 */
  }
  .locate-cradle__cat { break-after: avoid; }
}

/* Phones / short viewports: tighter type, same as the readout ramp */
@media (max-width: 640px), (max-height: 500px) {
  .locate-cradle-inner { gap: 0; padding: 0.5rem 0.7rem 0.5rem 0.75rem; }
  .locate-cradle .hud-map__row { grid-template-columns: 40px 1fr; font-size: 0.66rem; }
}
/* Portrait phones need a deeper top reserve (255px — iphone-pro-max
   caught a 5px hero intersection at 230px); the rule itself lives in the
   "Never-vanish floors" block near the end of this file. */
@media (max-width: 360px) {
  .locate-cradle .hud-map__row { grid-template-columns: 34px 1fr; font-size: 0.64rem; }
}
@media (max-height: 500px) {
  /* Same hard-band discipline as the readout on landscape phones */
  .locate-cradle .hud-map__row { font-size: 0.62rem; grid-template-columns: 34px 1fr; }
}

/* Phones / short viewports: an OPEN bottom panel owns the bottom band —
   the opposite side's chip/panel hides while it's open (locate.js sets
   body.readout-open / body.cradle-open in the toggles' render paths).
   visibility (not display) so GSAP tweens and measurements stay sane. */
@media (max-width: 640px), (max-height: 500px) {
  /* Children, not the asides: the GSAP entrance leaves inline
     visibility:inherit on the aside elements, which beats a stylesheet
     rule there (caught 2026-07-02 in the local harness). The cradle's
     toggle wears .locate-readout__toggle for the shared chip look, so
     exclude it from the readout-side selector.
     :not() guards (Bryan device review 2026-07-02): if BOTH open flags
     are ever set at once — the shrink-a-wide-window path before the
     locate.js resize invariant existed — neither side hides. Two
     overlapping panels beat two invisible ones. */
  body.cradle-open:not(.readout-open)  .locate-readout .locate-readout__toggle:not(.locate-cradle__toggle),
  body.cradle-open:not(.readout-open)  .locate-readout .locate-readout-inner { visibility: hidden; }
  body.readout-open:not(.cradle-open) .locate-cradle .locate-cradle__toggle,
  body.readout-open:not(.cradle-open) .locate-cradle .locate-cradle-inner { visibility: hidden; }
}

/* Never-vanish floors (Bryan 2026-07-02: "when I make it really small,
   the data windows disappear"). The band formulas go to zero on very
   short windows — floor both panels at a usable minimum (they scroll
   internally) and never let the chips themselves be crushed. */
.locate-readout__toggle { flex-shrink: 0; }
.locate-readout {
  max-height: max(120px, calc(100dvh - var(--footer-h) - env(safe-area-inset-bottom, 0px) - 175px));
}
.locate-cradle {
  max-height: max(140px, calc(100dvh - var(--footer-h) - env(safe-area-inset-bottom, 0px) - 230px));
}
@media (max-width: 640px) and (min-height: 501px) {
  .locate-cradle {
    max-height: max(140px, calc(100dvh - var(--footer-h) - env(safe-area-inset-bottom, 0px) - 255px));
  }
}
/* Landscape phones: the zoom cluster's bottom edge (~200px) leaves less
   headroom than the 140px floor assumes — a tighter floor keeps the
   panel below it (caught by the six-viewport probe 2026-07-02). */
@media (max-height: 500px) {
  .locate-cradle {
    max-height: max(105px, calc(100dvh - var(--footer-h) - env(safe-area-inset-bottom, 0px) - 230px));
  }
}

/* The DATA readout gets the same scroll-capture treatment as the Cradle
   (it scrolls on short windows and sat over the map with pass-through
   pixels all the same). */
.locate-readout-inner {
  pointer-events: auto;
  overscroll-behavior: contain;
}
