/* =========================================================================
   Sanctuary Virtual Guide — Responsive Navigation
   -------------------------------------------------------------------------
   Bottom navigation  <640px      (mobile)
   Side rail          640–1023px  (tablet)
   Top navigation     >=1024px    (desktop)

   Light mode = Serif editorial (ivory + burnished gold).
   Dark mode  = Art Deco (obsidian + metallic gold, stepped corners, glow).
   Toggled via `body.dark-mode`.

   Depends on: Google Fonts (Playfair Display, Source Sans 3, IBM Plex Mono)
               Material Symbols Outlined
   ========================================================================= */


/* ============================ DESIGN TOKENS ============================== */

:root {
  /* --- Light palette (Warm sanctuary — ivory, sandstone, burnished gold) --- */
  --nv-bg:             #F6F2EC;        /* Warm ivory, like aged parchment */
  --nv-surface:        rgba(248, 244, 238, 0.92);
  --nv-fg:             #2C2418;        /* Warm near-black (sepia tint) */
  --nv-muted:          #EDE8E0;        /* Sandstone beige */
  --nv-muted-fg:       #7A6E5D;        /* Warm grey-brown */
  --nv-accent:         #B8860B;        /* Burnished gold */
  --nv-accent-soft:    #D4A84B;
  --nv-accent-glow:    rgba(184, 134, 11, 0.22);
  --nv-accent-muted:   rgba(184, 134, 11, 0.10);
  --nv-accent-on:      #FFFFFF;
  --nv-border:         #DDD6CB;        /* Warm stone border */
  --nv-border-strong:  #B8860B;

  /* --- Elevation --- */
  --nv-shadow-sm:      0 1px 3px rgba(44, 36, 24, 0.07);
  --nv-shadow-md:      0 4px 16px rgba(44, 36, 24, 0.10);
  --nv-shadow-fab:     0 6px 18px rgba(184, 134, 11, 0.28),
                       0 2px 4px rgba(44, 36, 24, 0.10);

  /* --- Geometry --- */
  --nv-radius:         8px;
  --nv-radius-sm:      6px;
  --nv-radius-pill:    999px;

  /* --- Layout --- */
  --nv-bottom-h:       68px;
  --nv-bottom-total-h: calc(var(--nv-bottom-h) + env(safe-area-inset-bottom, 0px));
  --nv-rail-w:         76px;
  --nv-top-h:          64px;

  /* --- Motion --- */
  --nv-ease:           cubic-bezier(0.22, 1, 0.36, 1);
  --nv-duration:       220ms;
}

/* --- Dark palette (Art Deco) --- */
/* html.theme-dark = set by flash-prevention script in <head> (no flash on load)
   body.dark-mode   = set by navigation.js toggle (runtime switching) */
html.theme-dark,
body.dark-mode {
  --nv-bg:             #0A0A0A;
  --nv-surface:        rgba(10, 10, 10, 0.82);
  --nv-fg:             #F2F0E4;              /* Champagne cream */
  --nv-muted:          #141414;              /* Rich charcoal */
  --nv-muted-fg:       #8A8F98;
  --nv-accent:         #D4AF37;              /* Metallic gold */
  --nv-accent-soft:    #F2E8C4;
  --nv-accent-glow:    rgba(212, 175, 55, 0.32);
  --nv-accent-muted:   rgba(212, 175, 55, 0.10);
  --nv-accent-on:      #0A0A0A;
  --nv-border:         rgba(212, 175, 55, 0.22);
  --nv-border-strong:  #D4AF37;

  --nv-shadow-sm:      0 0 0 1px rgba(212, 175, 55, 0.06),
                       0 1px 2px rgba(0, 0, 0, 0.6);
  --nv-shadow-md:      0 0 0 1px rgba(212, 175, 55, 0.08),
                       0 10px 30px rgba(0, 0, 0, 0.7);
  --nv-shadow-fab:     0 0 22px rgba(212, 175, 55, 0.38),
                       0 6px 18px rgba(0, 0, 0, 0.7);
}


/* ============================ PAGE BASE ================================== */

.material-symbols-outlined {
  font-family: 'Material Symbols Outlined';
  font-weight: normal;
  font-style: normal;
  font-size: 1em;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1em;
  min-width: 1em;
  height: 1em;
  overflow: hidden;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  flex-shrink: 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'liga';
  -webkit-font-feature-settings: 'liga';
}

/* (Removed: legacy `color: transparent` gate on `material-icons-ready`.
   Superseded by the `icons-ready` / `visibility: hidden` block below,
   which runs earlier — outside the jQuery wrapper in navigation.js.) */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* ── Material Symbols FOUT polish ────────────────────────────────
   The Google Fonts URL uses `display=block` so the browser hides
   the literal ligature text (the word "route", "close", …) while
   the icon font loads. This rule adds a second layer of safety:
   every `.material-symbols-outlined` is hidden until JS verifies
   the font is actually decoded — then `html.icons-ready` reveals
   them all in the same frame. Caps at 4s in the JS so a hung font
   never permanently hides icons. See navigation.js + the inline
   fallback in admin/panel.html, public/photos.html, public/error.html.
*/
.material-symbols-outlined {
  visibility: hidden;
}
html.icons-ready .material-symbols-outlined {
  visibility: visible;
}

body {
  margin: 0;
  background: var(--nv-bg);
  color: var(--nv-fg);
  font-family: 'Source Sans 3', system-ui, -apple-system, sans-serif;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  min-height: 100dvh;
  transition: background-color 220ms ease, color 220ms ease;
  overflow-x: hidden;
  /* Suppress the browser's native pull-to-refresh gesture (Chrome iOS,
     Chrome Android, Samsung Internet). Without this, scrolling up past
     the document top reloads the page mid-gesture. `contain` is the
     least intrusive value — it stops the gesture chaining out to the
     browser UI but keeps the normal in-page bounce / momentum scroll. */
  overscroll-behavior-y: contain;
}
html {
  /* Same fix at the html level — Chrome iOS sometimes sources the
     overscroll gesture from <html> rather than <body>.               */
  overscroll-behavior-y: contain;
}


/* ============================ SHELL HELPERS ============================== */

.app-shell {
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
}

/* Reserve space for whichever nav is visible, driven by breakpoint. */
.main-content {
  padding-bottom: calc(var(--nv-bottom-h) + env(safe-area-inset-bottom, 0px));
}

@media (min-width: 640px) {
  .main-content {
    padding-left: 0;
    padding-bottom: 0;
  }
}

@media (min-width: 1024px) {
  .main-content {
    padding-left: 0;
    padding-top: var(--nv-top-h);
  }
}


/* =========================== SHARED PRIMITIVES =========================== */

.nav-brand {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--nv-fg);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}

.nav-brand .material-symbols-outlined {
  color: var(--nv-accent);
  font-size: 24px;
  font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

.nav-link {
  appearance: none;
  -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  background: none;
  border: none;
  cursor: pointer;
  font-family: 'Source Sans 3', system-ui, -apple-system, sans-serif;
  color: var(--nv-muted-fg);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    color var(--nv-duration) var(--nv-ease),
    background-color var(--nv-duration) var(--nv-ease),
    border-color var(--nv-duration) var(--nv-ease),
    transform var(--nv-duration) var(--nv-ease),
    box-shadow var(--nv-duration) var(--nv-ease);
}

.nav-link:hover { color: var(--nv-fg); }
.nav-link.is-active { color: var(--nv-accent); }

.nav-link .material-symbols-outlined {
  font-variation-settings: 'FILL' 0, 'wght' 350, 'GRAD' 0, 'opsz' 24;
  transition: font-variation-settings var(--nv-duration) var(--nv-ease);
}

.nav-link.is-active .material-symbols-outlined {
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

/* Unified focus ring */
.nav-link:focus-visible {
  outline: 2px solid var(--nv-accent);
  outline-offset: 3px;
  border-radius: var(--nv-radius-sm);
}


/* ========================= BOTTOM NAV (MOBILE) =========================== */

.bottom-nav {
  display: flex;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 100;
  height: var(--nv-bottom-total-h);
  padding: 0 6px env(safe-area-inset-bottom, 0px);
  align-items: center;
  justify-content: space-around;
  gap: 2px;
  background: var(--nv-surface);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border-top: 1px solid var(--nv-border);
}

/* Decorative gold hairline above the nav — barely visible on light,
   more present on dark to echo Art Deco rule lines. */
.bottom-nav::before {
  content: '';
  position: absolute;
  top: -1px; left: 50%;
  transform: translateX(-50%);
  width: 48px; height: 2px;
  background: var(--nv-accent);
  opacity: 0.35;
  border-radius: 2px;
}

.bottom-link {
  flex: 1;
  min-width: 56px;
  min-height: 48px;
  padding: 8px 6px 6px;
  border-radius: var(--nv-radius-sm);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--nv-muted-fg);
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: none;
  border: none;
  cursor: pointer;
  transition: color var(--nv-duration) var(--nv-ease);
}

.bottom-link .material-symbols-outlined { font-size: 22px; }
.bottom-link:hover { color: var(--nv-fg); }

.bottom-link.is-active {
  color: var(--nv-accent);
}

/* Active dot removed per design preference */
.bottom-link.is-active::after {
  display: none;
}

/* --- Center "Map" floating action button ----------------------------------
   Lifted above the bar with a soft gold halo behind it. The halo (::before)
   is absolutely positioned and sits behind the button; the FAB itself
   carries layered shadows so it reads as a premium, elevated control. */
.bottom-link.is-map {
  position: relative;
  margin-top: -26px;
  gap: 4px;
  z-index: 1;
}

/* Soft ambient glow behind the FAB — extends past the nav top edge */
.bottom-link.is-map::before {
  content: '';
  position: absolute;
  top: -10px; left: 50%;
  transform: translateX(-50%);
  width: 88px; height: 88px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--nv-accent) 22%, transparent) 0%,
    transparent 70%
  );
  pointer-events: none;
  z-index: -1;
  transition: opacity var(--nv-duration) var(--nv-ease);
}

.bottom-link.is-map .nav-fab {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nv-accent-on);
  background:
    radial-gradient(circle at 30% 28%, rgba(255, 255, 255, 0.18) 0%, transparent 55%),
    linear-gradient(145deg, var(--nv-accent-soft) 0%, var(--nv-accent) 58%, #9E7209 100%);
  /* Layered shadow: sharp lift + soft gold bloom + inner highlight */
  box-shadow:
    0 10px 22px -6px rgba(184, 134, 11, 0.55),
    0 4px 10px rgba(26, 26, 26, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    inset 0 -1px 0 rgba(0, 0, 0, 0.12);
  transition: transform var(--nv-duration) var(--nv-ease),
              box-shadow var(--nv-duration) var(--nv-ease);
  will-change: transform;
}

.bottom-link.is-map .nav-fab .material-symbols-outlined {
  font-size: 26px;
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.18));
}

.bottom-link.is-map:hover .nav-fab {
  transform: translateY(-2px) scale(1.05);
  box-shadow:
    0 14px 28px -6px rgba(184, 134, 11, 0.62),
    0 6px 14px rgba(26, 26, 26, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.30),
    inset 0 -1px 0 rgba(0, 0, 0, 0.12);
}

.bottom-link.is-map:hover::before { opacity: 1.2; }

.bottom-link.is-map:active .nav-fab {
  transform: translateY(0) scale(0.97);
  box-shadow:
    0 6px 14px -4px rgba(184, 134, 11, 0.50),
    0 2px 6px rgba(26, 26, 26, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.bottom-link.is-map.is-active::after { display: none; }

/* Label beneath the FAB — small caps, tightly tracked */
.bottom-link.is-map > span:not(.nav-fab) {
  font-size: 0.56rem;
  color: var(--nv-muted-fg);
}
.bottom-link.is-map.is-active > span:not(.nav-fab) {
  color: var(--nv-accent);
}

@media (min-width: 640px) {
  .bottom-nav { display: none; }
}


/* ============================ SIDE RAIL (TABLET) ========================= */

.side-rail {
  display: none;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 200;
  width: var(--nv-rail-w);
  padding: 18px 0 18px;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  background: var(--nv-surface);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border-right: 1px solid var(--nv-border);
  transform: translateX(-100%);
  transition: transform var(--nv-duration) var(--nv-ease);
}

/* Vertical gold rule — editorial spine / Art Deco column */
.side-rail::after {
  content: '';
  position: absolute;
  top: 20%; bottom: 20%; right: 0;
  width: 1px;
  background: linear-gradient(
    180deg,
    transparent 0%,
    color-mix(in srgb, var(--nv-accent) 35%, transparent) 50%,
    transparent 100%
  );
  pointer-events: none;
}

.side-rail .nav-brand {
  width: 44px;
  height: 44px;
  justify-content: center;
  margin-bottom: 14px;
  font-size: 0;
}

.side-rail .nav-brand .material-symbols-outlined { font-size: 28px; }

/* The rail brand is a 44 px square; constrain the logo image so it
   doesn't overflow the slot. `object-fit: contain` (inherited from
   the base .nav-brand-logo rule) preserves the artwork's aspect
   ratio inside the bounded box. */
.side-rail .nav-brand-logo {
  height: 36px;
  max-width: 36px;
  width: auto;
}

.rail-link {
  width: 60px;
  padding: 10px 6px;
  border-radius: var(--nv-radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  color: var(--nv-muted-fg);
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: none;
  border: none;
  cursor: pointer;
  position: relative;
  transition: color var(--nv-duration) var(--nv-ease),
              background-color var(--nv-duration) var(--nv-ease);
}

.rail-link .material-symbols-outlined { font-size: 22px; }

.rail-link:hover {
  color: var(--nv-fg);
  background: var(--nv-muted);
}

.rail-link.is-active {
  color: var(--nv-accent);
  background: var(--nv-accent-muted);
}

/* Active indicator bar removed per design preference */
.rail-link.is-active::before {
  display: none;
}

/* Map action inside the rail (matches mockup) */
.rail-link.is-map {
  background: var(--nv-accent);
  color: var(--nv-accent-on);
  border-radius: var(--nv-radius);
  margin: 4px 0;
}

.rail-link.is-map:hover {
  background: var(--nv-accent-soft);
  color: var(--nv-accent-on);
}

.rail-link.is-map.is-active {
  background: var(--nv-accent);
  color: var(--nv-accent-on);
}

.rail-link.is-map.is-active::before { display: none; }

.rail-spacer { flex: 1; min-height: 12px; }

.rail-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--nv-border);
  width: 56px;
}

@media (min-width: 640px) {
  .side-rail { display: flex; }
}

@media (min-width: 640px) {
  .rail-open .side-rail {
    transform: translateX(0);
  }
}

@media (min-width: 1024px) {
  .side-rail { display: none; }
}


/* --- Hamburger toggle (tablet only) -------------------------------------- */

.rail-toggle {
  display: none;
  position: fixed;
  top: 12px; left: 12px;
  z-index: 210;
  width: 44px; height: 44px;
  border: none;
  border-radius: var(--nv-radius);
  background: rgba(0, 0, 0, 0.25);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  box-shadow: none;
  transition: background-color var(--nv-duration) var(--nv-ease);
}

.rail-toggle:hover {
  background: rgba(0, 0, 0, 0.4);
}

.rail-toggle .material-symbols-outlined {
  font-size: 24px;
}

@media (min-width: 640px) {
  .rail-toggle { display: flex; }
}

@media (min-width: 1024px) {
  .rail-toggle { display: none; }
}


/* --- Rail backdrop overlay ----------------------------------------------- */

.rail-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 190;
  background: rgba(0, 0, 0, 0.35);
  opacity: 0;
  transition: opacity var(--nv-duration) var(--nv-ease);
  pointer-events: none;
}

@media (min-width: 640px) {
  .rail-backdrop { display: block; }
}

@media (min-width: 1024px) {
  .rail-backdrop { display: none; }
}

.rail-open .rail-backdrop {
  opacity: 1;
  pointer-events: auto;
}


/* =========================== TOP NAV (DESKTOP) =========================== */

.top-nav {
  display: none;
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--nv-top-h);
  padding: 0 40px 0 12px;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  background: var(--nv-surface);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border-bottom: 1px solid var(--nv-border);
}

/* Decorative Art-Deco gold rule below the top nav */
.top-nav::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--nv-accent) 25%, transparent) 20%,
    color-mix(in srgb, var(--nv-accent) 55%, transparent) 50%,
    color-mix(in srgb, var(--nv-accent) 25%, transparent) 80%,
    transparent 100%
  );
  opacity: 0.7;
  pointer-events: none;
}

.top-nav .nav-brand { font-size: 1.25rem; }

.top-nav .nav-brand.has-logo {
  padding: 4px 0;
  gap: 0;
}

.nav-brand-logo {
  display: block;
  height: 48px;
  width: auto;
  max-width: 220px;
  object-fit: contain;
  transition: filter var(--nv-duration) var(--nv-ease),
              transform var(--nv-duration) var(--nv-ease);
}

.top-nav .nav-brand:hover .nav-brand-logo {
  transform: translateY(-1px);
}

/* Logo artwork is dark navy on transparent — recolor to a warm champagne
   in dark mode so it reads against the obsidian backdrop. */
body.dark-mode .nav-brand-logo {
  filter: brightness(0) invert(0.92) sepia(0.18) saturate(2.4) hue-rotate(2deg);
}

.top-nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
}

.top-link {
  padding: 8px 16px;
  border-radius: var(--nv-radius-sm);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--nv-muted-fg);
  background: none;
  border: none;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  transition: color var(--nv-duration) var(--nv-ease),
              background-color var(--nv-duration) var(--nv-ease);
}

.top-link .material-symbols-outlined { font-size: 18px; }

.top-link:hover {
  color: var(--nv-fg);
  background: var(--nv-muted);
}

.top-link.is-active {
  color: var(--nv-accent);
  background: var(--nv-accent-muted);
}

/* Editorial underline — removed per design preference */
.top-link::after {
  display: none;
}

/* The map link as primary action (matches mockup) */
.top-link.is-map {
  color: var(--nv-accent-on);
  background: var(--nv-accent);
  padding: 8px 18px;
  border-radius: var(--nv-radius-sm);
}

.top-link.is-map:hover {
  background: var(--nv-accent-soft);
  color: var(--nv-accent-on);
}

.top-link.is-map.is-active {
  background: var(--nv-accent);
  color: var(--nv-accent-on);
}

.top-link.is-map::after { display: none; }

.top-nav-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.top-nav-actions .material-symbols-outlined { font-size: 18px; }

/* Icon-only circular utility button (theme, language, feedback) */
.nav-icon-btn {
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: var(--nv-radius-pill);
  background: transparent;
  border: 1px solid var(--nv-border);
  color: var(--nv-muted-fg);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  transition: all var(--nv-duration) var(--nv-ease);
}

.nav-icon-btn:hover {
  color: var(--nv-fg);
  border-color: var(--nv-accent);
  background: var(--nv-muted);
}

.nav-icon-btn .material-symbols-outlined { font-size: 18px; }

/* Language pill button, shows current code */
.lang-pill {
  height: 36px;
  padding: 0 12px;
  border-radius: var(--nv-radius-pill);
  background: transparent;
  border: 1px solid var(--nv-border);
  color: var(--nv-muted-fg);
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all var(--nv-duration) var(--nv-ease);
}

.lang-pill:hover {
  color: var(--nv-fg);
  border-color: var(--nv-accent);
  background: var(--nv-muted);
}

.lang-pill .material-symbols-outlined { font-size: 16px; }

.lang-pill .lang-pill-caret {
  font-size: 16px;
  margin-left: 2px;
  margin-right: -4px;
  opacity: 0.65;
  transition: transform var(--nv-duration) var(--nv-ease),
              opacity var(--nv-duration) var(--nv-ease);
}

.lang-pill:hover .lang-pill-caret { opacity: 1; }

.lang-pill.is-open {
  color: var(--nv-fg);
  border-color: var(--nv-accent);
  background: var(--nv-muted);
}

.lang-pill.is-open .lang-pill-caret {
  transform: rotate(180deg);
  opacity: 1;
}

@media (min-width: 1024px) {
  .top-nav { display: flex; }
}


/* ===================== LANGUAGE DROPDOWN (DESKTOP) ======================= */

@keyframes langDdIn {
  from { opacity: 0; transform: translateY(-6px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1);    }
}

.lang-dd {
  position: fixed;
  top: 0; right: 0;
  z-index: 1100;
  width: 132px;
  background: var(--nv-bg);
  border: 1px solid var(--nv-border);
  border-radius: 12px;
  box-shadow:
    0 14px 36px rgba(44, 36, 24, 0.16),
    0 3px 8px rgba(44, 36, 24, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.5);
  padding: 6px;
  display: none;
  transform-origin: top right;
  font-family: 'Source Sans 3', system-ui, sans-serif;
}

.lang-dd.open {
  display: block;
  animation: langDdIn 180ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Small caret pointing up at the pill */
.lang-dd-arrow {
  position: absolute;
  top: -6px;
  right: 18px;
  width: 11px;
  height: 11px;
  background: var(--nv-bg);
  border-top: 1px solid var(--nv-border);
  border-left: 1px solid var(--nv-border);
  transform: rotate(45deg);
  border-top-left-radius: 3px;
}

.lang-dd-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lang-dd-option {
  appearance: none;
  -webkit-appearance: none;
  display: grid;
  grid-template-columns: 22px 1fr 14px;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  color: var(--nv-fg);
  font-family: inherit;
  text-align: left;
  width: 100%;
  transition:
    background-color 160ms var(--nv-ease),
    border-color    160ms var(--nv-ease),
    color           160ms var(--nv-ease),
    transform       160ms var(--nv-ease);
}

.lang-dd-option:hover { background: var(--nv-muted); }

.lang-dd-option:focus { outline: none; }

.lang-dd-option:focus-visible {
  background: var(--nv-muted);
  border-color: var(--nv-accent);
  box-shadow: 0 0 0 2px var(--nv-accent-glow);
}

.lang-dd-option.is-active {
  background: var(--nv-accent-muted);
  border-color: color-mix(in srgb, var(--nv-accent) 32%, transparent);
}

.lang-dd-option:active { transform: scale(0.985); }

.lang-dd-flag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  font-size: 1.05rem;
  line-height: 1;
  flex-shrink: 0;
}

.lang-dd-code {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--nv-fg);
  text-transform: uppercase;
  line-height: 1;
}

.lang-dd-option.is-active .lang-dd-code {
  color: var(--nv-accent);
}

.lang-dd-check {
  font-size: 14px !important;
  width: 14px !important;
  min-width: 14px !important;
  height: 14px !important;
  color: var(--nv-accent);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 180ms var(--nv-ease), transform 180ms var(--nv-ease);
  font-variation-settings: 'FILL' 1, 'wght' 600, 'GRAD' 0, 'opsz' 24;
}

.lang-dd-option.is-active .lang-dd-check {
  opacity: 1;
  transform: scale(1);
}

/* Dark mode polish */
body.dark-mode .lang-dd {
  background: linear-gradient(180deg, #14140f 0%, #0d0d09 100%);
  border-color: rgba(212, 175, 55, 0.22);
  box-shadow:
    0 0 0 1px rgba(212, 175, 55, 0.08),
    0 22px 50px rgba(0, 0, 0, 0.65),
    0 6px 14px rgba(0, 0, 0, 0.45);
}

body.dark-mode .lang-dd-arrow {
  background: #14140f;
  border-color: rgba(212, 175, 55, 0.22);
}

/* Dropdown is desktop-only — never let it bleed into smaller layouts */
@media (max-width: 1023px) {
  .lang-dd { display: none !important; }
}


/* ============================ MOTION / A11Y ============================== */

@media (prefers-reduced-motion: reduce) {
  .nav-link,
  .bottom-link,
  .rail-link,
  .top-link,
  .top-link::after,
  .bottom-link.is-map .nav-fab,
  .rail-link.is-map,
  .nav-icon-btn,
  .lang-pill,
  .lang-pill-caret,
  .lang-dd,
  .lang-dd-option,
  .lang-dd-check {
    transition: none !important;
    transform: none !important;
    animation: none !important;
  }
}


/* ========================= LANGUAGE GATE MODAL =========================== */

@keyframes langGateFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes langGateSlideIn {
  from { opacity: 0; transform: scale(0.92) translateY(16px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.lang-gate-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(7, 7, 10, 0.78);
  -webkit-backdrop-filter: blur(8px) saturate(105%);
          backdrop-filter: blur(8px) saturate(105%);
  /* Force the overlay onto its own compositing layer so the backdrop
     filter captures painted content behind it consistently on pages
     that promote sub-trees to GPU layers (Leaflet map tiles use
     translate3d transforms, which can otherwise leave the backdrop
     unblurred on tour/map screens). isolation also creates a fresh
     stacking context so nothing further down z-index can poke
     through.                                                        */
  isolation: isolate;
  will-change: backdrop-filter;
  transform: translateZ(0);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: langGateFadeIn 380ms cubic-bezier(0.16, 1, 0.3, 1);
}
.lang-gate-overlay.open { display: flex; }

body.lang-gate-open { overflow: hidden; }

/* ── Skeleton + shimmer entry state ────────────────────────────────
   When the modal opens, JS adds `is-loading` for ~550 ms. While the
   class is on, every text-bearing element inside the modal is masked
   by a skeleton bar with a travelling gold shimmer overlay. When JS
   removes the class, the bars fade out and the real text + indicator
   chrome fades in. Gives the modal a polished "loaded into place"
   feel that matches the rest of the site's skeleton patterns.       */
.lang-gate-overlay.is-loading .lang-gate-modal h2,
.lang-gate-overlay.is-loading .lang-gate-modal p,
.lang-gate-overlay.is-loading .lang-gate-option-label,
.lang-gate-overlay.is-loading .lang-gate-btn {
  position: relative;
  color: transparent !important;
}
.lang-gate-overlay.is-loading .lang-gate-modal h2::before,
.lang-gate-overlay.is-loading .lang-gate-modal p::before,
.lang-gate-overlay.is-loading .lang-gate-option-label::before,
.lang-gate-overlay.is-loading .lang-gate-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 4px;
  background: rgba(28, 28, 36, 0.08);
  overflow: hidden;
  z-index: 1;
}
.lang-gate-overlay.is-loading .lang-gate-modal h2::after,
.lang-gate-overlay.is-loading .lang-gate-modal p::after,
.lang-gate-overlay.is-loading .lang-gate-option-label::after,
.lang-gate-overlay.is-loading .lang-gate-btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg,
      transparent 0%,
      rgba(184, 134, 11, 0.12) 50%,
      transparent 100%);
  transform: translateX(-100%);
  animation: langGateShimmer 1.1s linear infinite;
  z-index: 2;
  pointer-events: none;
}

/* Hide the radio-button indicator + flag emoji while loading so the
   options read as pure skeleton rows. The flag is small enough to
   skip — masking it would over-engineer the moment. */
.lang-gate-overlay.is-loading .lang-gate-option-flag,
.lang-gate-overlay.is-loading .lang-gate-option-indicator {
  opacity: 0;
}

/* When `is-loading` is removed the real text/indicator fades in. */
.lang-gate-modal h2,
.lang-gate-modal p,
.lang-gate-option-label,
.lang-gate-btn,
.lang-gate-option-flag,
.lang-gate-option-indicator {
  transition: color 220ms ease, opacity 220ms ease;
}

@keyframes langGateShimmer {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%);  }
}

/* Dark theme — darker skeleton bars + brighter shimmer to read on
   the obsidian modal background.                                   */
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-modal h2::before,
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-modal p::before,
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-option-label::before,
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-btn::before,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-modal h2::before,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-modal p::before,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-option-label::before,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-btn::before {
  background: rgba(255, 255, 255, 0.06);
}
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-modal h2::after,
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-modal p::after,
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-option-label::after,
html.theme-dark .lang-gate-overlay.is-loading .lang-gate-btn::after,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-modal h2::after,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-modal p::after,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-option-label::after,
body.dark-mode .lang-gate-overlay.is-loading .lang-gate-btn::after {
  background:
    linear-gradient(90deg,
      transparent 0%,
      rgba(212, 175, 55, 0.18) 50%,
      transparent 100%);
}

@media (prefers-reduced-motion: reduce) {
  .lang-gate-overlay.is-loading .lang-gate-modal h2::after,
  .lang-gate-overlay.is-loading .lang-gate-modal p::after,
  .lang-gate-overlay.is-loading .lang-gate-option-label::after,
  .lang-gate-overlay.is-loading .lang-gate-btn::after {
    animation: none;
    transform: translateX(0);
    opacity: 0.3;
  }
}

.lang-gate-modal {
  background: #fbfaf6;
  border: 1px solid rgba(28, 28, 36, 0.08);
  box-shadow:
    0 20px 55px rgba(0,0,0,0.16),
    inset 0 1px 0 rgba(255,255,255,0.8);
  border-radius: 18px;
  max-width: 520px;
  width: min(520px, 100% - 32px);
  padding: 28px 28px 24px;
  color: var(--nv-fg);
  position: relative;
  overflow: hidden;
  animation: langGateSlideIn 420ms cubic-bezier(0.16, 1, 0.3, 1);
}

.lang-gate-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 20% 0%, rgba(184,134,11,0.06), transparent 45%);
  pointer-events: none;
  opacity: 0.8;
}

.lang-gate-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  position: relative;
  z-index: 2;
}

/* Right cluster: theme toggle + close. Both share the same circular
   icon-button chassis so the head reads as a tight pair of controls
   instead of two unrelated buttons.                                */
.lang-gate-head-tools {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lang-gate-icon-btn {
  appearance: none;
  -webkit-appearance: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid rgba(28, 28, 36, 0.10);
  background: rgba(28, 28, 36, 0.04);
  color: #5c5c68;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 180ms ease;
  padding: 0;
}
.lang-gate-icon-btn:hover {
  background: rgba(28, 28, 36, 0.08);
  color: #1f1f27;
}
.lang-gate-icon-btn:active { transform: scale(0.94); }
.lang-gate-icon-btn .material-symbols-outlined {
  font-size: 18px;
  font-variation-settings: 'wght' 500;
}
/* Theme toggle gets a subtle accent tint to telegraph that it does
   "something colourful". The icon swaps between sun/moon via the
   existing applyTheme() hook on [data-theme-icon].                 */
#langGateThemeToggle {
  color: #b8860b;
  border-color: rgba(184, 134, 11, 0.28);
  background: rgba(184, 134, 11, 0.08);
}
#langGateThemeToggle:hover {
  background: rgba(184, 134, 11, 0.16);
  color: #8b6914;
}

/* Theme-toggle SVG icons. The button always contains BOTH icons (moon
   for light theme, sun for dark theme) and CSS hides whichever one
   doesn't match the current theme. Replaces the Material Symbols
   ligature here because that font is the only thing that breaks if
   it loads stale or subsetted-without-light_mode, and the gate is
   the first screen a visitor sees. */
.lang-gate-theme-icon {
  width: 20px;
  height: 20px;
  display: block;
}
.lang-gate-theme-icon--sun { display: none; }
html.theme-dark .lang-gate-theme-icon--moon { display: none; }
html.theme-dark .lang-gate-theme-icon--sun  { display: block; }

.lang-gate-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(28, 28, 36, 0.06);
  color: #5c5c68;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  margin-bottom: 12px;
  border: 1px solid rgba(28, 28, 36, 0.08);
  position: relative;
  z-index: 2;
  text-transform: uppercase;
}
.lang-gate-badge .material-symbols-outlined { font-size: 14px; font-variation-settings: 'FILL' 1; }

.lang-gate-close {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid rgba(28, 28, 36, 0.1);
  background: rgba(28, 28, 36, 0.04);
  color: #5c5c68;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 180ms ease;
}
.lang-gate-close:hover { background: rgba(28, 28, 36, 0.08); color: #1f1f27; }
.lang-gate-close .material-symbols-outlined { font-size: 18px; }

.lang-gate-modal h2 {
  margin: 0 0 8px;
  font-size: 1.32rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
  position: relative;
  z-index: 2;
  color: #1d1d24;
}

.lang-gate-modal p {
  margin: 0 0 20px;
  color: #6a6a76;
  line-height: 1.65;
  font-size: 0.94rem;
  position: relative;
  z-index: 2;
  letter-spacing: 0.2px;
}

.lang-gate-options {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  position: relative;
  z-index: 1;
  margin-bottom: 16px;
}

.lang-gate-option {
  border: 1px solid rgba(28, 28, 36, 0.08);
  border-radius: 12px;
  padding: 14px 16px;
  background: #ffffff;
  color: var(--nv-fg);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  transition: all 240ms cubic-bezier(0.25, 0.1, 0.25, 1);
  text-align: left;
  font-weight: 600;
  font-size: 0.92rem;
  position: relative;
  min-height: 68px;
}
.lang-gate-option:hover {
  border-color: rgba(28, 28, 36, 0.16);
  box-shadow: 0 10px 24px rgba(0,0,0,0.10);
  transform: translateY(-1px);
}
.lang-gate-option.active {
  border-color: rgba(184,134,11,0.45);
  background: #fffaf0;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.9),
    0 8px 18px rgba(184,134,11,0.12);
}

.lang-gate-option-left {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.lang-gate-option-flag {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.9rem;
  line-height: 1;
  background: #eef2fb;
  color: #1f4dbb;
  flex-shrink: 0;
  overflow: hidden;
}
.lang-gate-option[data-lang="pt"] .lang-gate-option-flag { background: #e6f7ee; color: #1f7a3c; }
.lang-gate-option[data-lang="es"] .lang-gate-option-flag { background: #fdeeee; color: #b53636; }

.lang-gate-option-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.lang-gate-option-label {
  font-weight: 700;
  color: #1f1f27;
  font-size: 0.92rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Radio indicator — Material Symbols `radio_button_unchecked` /
   `radio_button_checked` swap. Both glyphs are emitted by the JS;
   the modifier classes below show whichever is appropriate for the
   current state, so the icon is the only thing telegraphing the
   selection (no border tricks).                                   */
.lang-gate-option-indicator {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  color: #aab2c4;
  background: transparent;
  border: 0;
  transition: color 220ms ease, transform 220ms ease;
}
.lang-gate-option-radio {
  position: absolute;
  inset: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  line-height: 1;
  transition: opacity 200ms ease, transform 240ms cubic-bezier(0.34, 1.4, 0.64, 1);
  font-variation-settings: 'FILL' 0, 'wght' 500;
}
.lang-gate-option-radio--on  { opacity: 0; transform: scale(0.6); }
.lang-gate-option-radio--off { opacity: 1; transform: scale(1);   }
.lang-gate-option.active .lang-gate-option-indicator {
  color: #b8860b;
}
.lang-gate-option.active .lang-gate-option-radio--off { opacity: 0; transform: scale(0.7); }
.lang-gate-option.active .lang-gate-option-radio--on  {
  opacity: 1; transform: scale(1);
  font-variation-settings: 'FILL' 1, 'wght' 600;
}

.lang-gate-footer {
  margin-top: 4px;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  position: relative;
  z-index: 1;
}

/* Primary "Continue" button — matches the gold .btn-primary used on
   the home hero (Start Visit). Same accent fill, same letter-spacing,
   same hover lift, so the gate's CTA reads as part of the brand
   button family.                                                    */
.lang-gate-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--nv-accent);
  color: var(--nv-accent-on);
  border: 1px solid var(--nv-accent);
  padding: 11px 24px;
  border-radius: var(--nv-radius, 10px);
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 0.88rem;
  letter-spacing: 0.04em;
  cursor: pointer;
  min-height: 44px;
  white-space: nowrap;
  transition: background-color 220ms cubic-bezier(0.22, 1, 0.36, 1),
              border-color 220ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 220ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
  box-shadow: 0 6px 14px color-mix(in srgb, var(--nv-accent) 24%, transparent);
}
.lang-gate-btn:hover {
  background: var(--nv-accent-soft, var(--nv-accent));
  border-color: var(--nv-accent-soft, var(--nv-accent));
  box-shadow: 0 10px 22px color-mix(in srgb, var(--nv-accent) 32%, transparent);
  transform: translateY(-2px);
}
.lang-gate-btn:active { transform: translateY(0); }
.lang-gate-btn.secondary {
  background: transparent;
  color: #8f7c45;
  border: 1px solid rgba(184,134,11,0.22);
  box-shadow: none;
  font-weight: 600;
}
.lang-gate-btn.secondary:hover {
  border-color: var(--nv-accent);
  color: #775f25;
  background: rgba(184,134,11,0.06);
}

/* --- Language gate dark mode --- */
body.dark-mode .lang-gate-modal {
  background: linear-gradient(135deg, rgba(16,16,22,0.96), rgba(12,12,18,0.94));
  border-color: rgba(184,134,11,0.16);
  box-shadow: 0 22px 60px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.04);
}
body.dark-mode .lang-gate-modal h2 { color: #f1efe6; }
body.dark-mode .lang-gate-modal p { color: #b8b8c8; }
body.dark-mode .lang-gate-option {
  background: rgba(18,18,26,0.92);
  border-color: rgba(255,255,255,0.08);
  color: #E8E8EC;
}
body.dark-mode .lang-gate-option:hover {
  background: rgba(22,22,32,0.96);
  border-color: rgba(255,255,255,0.16);
  box-shadow: 0 10px 24px rgba(0,0,0,0.35);
}
body.dark-mode .lang-gate-option.active {
  background: rgba(255,255,255,0.06);
  border-color: rgba(212,165,116,0.5);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 10px 22px rgba(0,0,0,0.35);
}
body.dark-mode .lang-gate-option-label { color: #f1f1f5; }
body.dark-mode .lang-gate-option.active .lang-gate-option-label { color: #f5e6c8; }
body.dark-mode .lang-gate-option-flag { background: rgba(90,120,200,0.2); color: #cfe0ff; }
body.dark-mode .lang-gate-option[data-lang="pt"] .lang-gate-option-flag { background: rgba(80,170,110,0.2); color: #c8f1d6; }
body.dark-mode .lang-gate-option[data-lang="es"] .lang-gate-option-flag { background: rgba(200,90,90,0.2); color: #ffd2d2; }
/* Indicator on dark surfaces — keep the radio icon visible against
   the near-black option card. The active state uses the warmer
   `--nv-accent` tint we use elsewhere in the dark palette.        */
body.dark-mode .lang-gate-option-indicator { color: rgba(255, 255, 255, 0.40); }
body.dark-mode .lang-gate-option.active .lang-gate-option-indicator { color: #d4a574; }
/* Dark-mode Continue keeps the gold accent fill — same as the
   home hero's Start Visit button on dark backgrounds. The
   --nv-accent / --nv-accent-on tokens are theme-aware so we don't
   need to hardcode anything; just preserve the brand colour against
   the darker modal surface.                                       */
body.dark-mode .lang-gate-btn {
  background: var(--nv-accent);
  color: var(--nv-accent-on);
  border-color: var(--nv-accent);
  box-shadow: 0 8px 20px color-mix(in srgb, var(--nv-accent) 28%, transparent);
}
body.dark-mode .lang-gate-btn:hover {
  background: var(--nv-accent-soft, var(--nv-accent));
  border-color: var(--nv-accent-soft, var(--nv-accent));
  box-shadow: 0 10px 26px color-mix(in srgb, var(--nv-accent) 38%, transparent);
}
body.dark-mode .lang-gate-btn.secondary {
  background: rgba(20,20,28,0.92); color: #E8E8EC; border-color: rgba(255,255,255,0.12);
}
body.dark-mode .lang-gate-btn.secondary:hover {
  background: rgba(24,24,34,0.96); border-color: rgba(255,255,255,0.18);
}
body.dark-mode .lang-gate-badge { background: rgba(255,255,255,0.08); color: #cfcfd8; border-color: rgba(255,255,255,0.12); }
body.dark-mode .lang-gate-close { border-color: rgba(255,255,255,0.14); background: rgba(255,255,255,0.06); color: #d8d8e1; }
body.dark-mode .lang-gate-close:hover { border-color: rgba(255,255,255,0.22); background: rgba(255,255,255,0.1); color: #f1f1f6; }
/* Shared icon-button (close + theme-toggle) on dark surfaces — same
   recipe as .lang-gate-close so the pair stays consistent.        */
body.dark-mode .lang-gate-icon-btn {
  border-color: rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.06);
  color: #d8d8e1;
}
body.dark-mode .lang-gate-icon-btn:hover {
  border-color: rgba(255,255,255,0.22);
  background: rgba(255,255,255,0.10);
  color: #f1f1f6;
}
/* Theme toggle keeps its gold tint in dark mode too — visually
   marks it as the "switch theme" button distinct from close.    */
body.dark-mode #langGateThemeToggle {
  color: #e6c47a;
  border-color: rgba(212, 165, 116, 0.32);
  background: rgba(212, 165, 116, 0.10);
}
body.dark-mode #langGateThemeToggle:hover {
  background: rgba(212, 165, 116, 0.18);
  color: #f1d28f;
}

/* --- Language gate mobile (bottom sheet) --- */
@media (max-width: 639px) {
  .lang-gate-overlay {
    align-items: flex-end;
    padding: 0;
    background: rgba(7, 7, 10, 0.62);
  }
  .lang-gate-modal {
    width: 100%;
    max-width: none;
    border-radius: 22px 22px 0 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
    padding: 16px 16px calc(12px + env(safe-area-inset-bottom));
    animation: langGateSlideIn 360ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .lang-gate-modal::before {
    content: '';
    width: 42px;
    height: 4px;
    border-radius: 999px;
    background: rgba(120, 120, 140, 0.4);
    display: block;
    margin: 0 auto 10px;
  }
  .lang-gate-badge { margin-bottom: 10px; }
  .lang-gate-modal h2 { font-size: 1.12rem; margin-bottom: 6px; }
  .lang-gate-modal p { font-size: 0.88rem; margin-bottom: 14px; }
  .lang-gate-option { min-height: 62px; padding: 12px 13px; }
  .lang-gate-option-flag { width: 40px; height: 40px; font-size: 1.55rem; }
  .lang-gate-footer {
    margin-top: 8px;
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  .lang-gate-btn { min-height: 42px; width: 100%; }
}

@media (min-width: 1024px) {
  .lang-gate-modal {
    max-width: 460px;
    width: min(460px, 100% - 64px);
    padding: 28px 26px 24px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   ACCESSIBILITY OVERRIDES — site-wide
   ───────────────────────────────────────────────────────────────────────
   These rules belong here (not in accessibility.css) because the
   /accessibility stylesheet only loads on its own page, but the user's
   high-contrast / reduce-motion preferences need to take effect on
   every page. Toggled via classes on <html> by the inline boot script
   in each page's <head>. Both are no-ops when their class isn't set.
   ─────────────────────────────────────────────────────────────────── */

/* ── HIGH CONTRAST ────────────────────────────────────────────────────
   Philosophy: this is a TOKEN-ONLY override. We do not add borders,
   focus rings, underlines, or any new chrome. The existing components
   already have their own borders / focus states; HC just feeds them
   stronger colours.

   Earlier versions tried to add a 1px outline to every "interactive"
   element and replaced shadows with hard outlines — that piled
   borders on top of borders and produced a wireframe look. Lesson
   learned: HC is a re-palette, not a redesign.                       */

/* Light mode — pure white surfaces, near-black text, darker brand
   gold so AA passes on white. Muted surface stays near-white so
   muted-fg-on-muted-bg keeps usable contrast. Borders are a soft
   mid-grey rather than pure black; pure black borders + pure black
   text on every card looks like a coloring book.

   IMPORTANT: each page (home, guide) defines its own `--home-*` /
   `--guide-*` color tokens in their own stylesheet. Those tokens are
   ALSO rebound here so high-contrast actually flips the page chrome
   on every page, not just on /accessibility. tour.css uses --nv-*
   directly for colors so it doesn't need its own block. */
/* `!important` on every custom property — page stylesheets
   (home.css, guide.css) declare their own --home-* / --guide-* /
   --nv-* sibling values in selectors like `html.theme-dark` that have
   IDENTICAL specificity to `html.high-contrast`. When specificity
   ties, the later-loaded stylesheet wins — and home.css/guide.css
   load after navigation.css. Without `!important` here, dark-mode
   home/guide tokens would beat our HC overrides on /home and
   /guide, which is exactly the bug the user reported ("HC only
   shows on /accessibility"). `!important` on custom properties is
   the documented pattern for theming overrides.                    */
html.high-contrast {
    /* Site-wide */
    --nv-bg:             #FFFFFF !important;
    --nv-surface:        #FFFFFF !important;
    --nv-fg:             #000000 !important;
    --nv-muted:          #F4F4F4 !important;
    --nv-muted-fg:       #222222 !important;
    --nv-accent:         #8B5A00 !important;
    --nv-accent-soft:    #B07A1C !important;
    --nv-accent-glow:    rgba(139, 90, 0, 0.18) !important;
    --nv-accent-muted:   rgba(139, 90, 0, 0.08) !important;
    --nv-accent-on:      #FFFFFF !important;
    --nv-border:         #6E6E6E !important;
    --nv-border-strong:  #000000 !important;

    /* home.css tokens */
    --home-card:         #FFFFFF !important;
    --home-card-border:  #6E6E6E !important;
    --home-card-hover:   rgba(0, 0, 0, 0.06) !important;
    --home-shadow-sm:    none !important;
    --home-shadow-md:    none !important;
    --home-shadow-lg:    none !important;
    --home-glass:        rgba(255, 255, 255, 0.92) !important;
    --home-divider:      linear-gradient(to right, transparent, #6E6E6E 20%, #6E6E6E 80%, transparent) !important;
    --home-hero-overlay: linear-gradient(to top, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.30) 55%, rgba(0,0,0,0.05) 100%) !important;

    /* guide.css tokens */
    --guide-card:        #FFFFFF !important;
    --guide-card-border: #6E6E6E !important;
    --guide-card-hover:  rgba(0, 0, 0, 0.06) !important;
    --guide-shadow-sm:   none !important;
    --guide-shadow-md:   none !important;
    --guide-shadow-lg:   none !important;
    --guide-shadow-xl:   none !important;
    --guide-glass:       rgba(255, 255, 255, 0.92) !important;
    --guide-hero-bg:     #FFFFFF !important;
    --guide-accent-glow: rgba(139, 90, 0, 0.06) !important;
    --guide-divider:     linear-gradient(to right, transparent, #6E6E6E 20%, #6E6E6E 80%, transparent) !important;

    /* accessibility.css tokens */
    --ac-fg:             #000000 !important;
    --ac-muted-fg:       #1A1A1A !important;
    --ac-border:         #000000 !important;
    --ac-muted:          #F4F4F4 !important;
    --ac-surface:        #FFFFFF !important;

    color-scheme: light;
}

/* Dark mode — pure black surfaces, near-white text, brand gold kept
   close to its existing value (D4AF37) rather than a bright yellow,
   so the look stays warm + intentional instead of a yellow neon. */
html.high-contrast.theme-dark,
body.dark-mode.high-contrast {
    /* Site-wide */
    --nv-bg:             #000000 !important;
    --nv-surface:        #000000 !important;
    --nv-fg:             #FFFFFF !important;
    --nv-muted:          #0F0F0F !important;
    --nv-muted-fg:       #DCDCDC !important;
    --nv-accent:         #D4AF37 !important;     /* brand gold — already AA on pure black */
    --nv-accent-soft:    #E5C76F !important;
    --nv-accent-glow:    rgba(212, 175, 55, 0.28) !important;
    --nv-accent-muted:   rgba(212, 175, 55, 0.14) !important;
    --nv-accent-on:      #000000 !important;
    --nv-border:         #6B6B6B !important;
    --nv-border-strong:  #FFFFFF !important;

    /* home.css tokens */
    --home-card:         #000000 !important;
    --home-card-border:  #6B6B6B !important;
    --home-card-hover:   rgba(255, 255, 255, 0.06) !important;
    --home-shadow-sm:    none !important;
    --home-shadow-md:    none !important;
    --home-shadow-lg:    none !important;
    --home-glass:        rgba(0, 0, 0, 0.92) !important;
    --home-divider:      linear-gradient(to right, transparent, #6B6B6B 20%, #6B6B6B 80%, transparent) !important;
    --home-hero-overlay: linear-gradient(to top, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.50) 55%, rgba(0,0,0,0.15) 100%) !important;

    /* guide.css tokens */
    --guide-card:        #000000 !important;
    --guide-card-border: #6B6B6B !important;
    --guide-card-hover:  rgba(255, 255, 255, 0.06) !important;
    --guide-shadow-sm:   none !important;
    --guide-shadow-md:   none !important;
    --guide-shadow-lg:   none !important;
    --guide-shadow-xl:   none !important;
    --guide-glass:       rgba(0, 0, 0, 0.92) !important;
    --guide-hero-bg:     #000000 !important;
    --guide-accent-glow: rgba(212, 175, 55, 0.06) !important;
    --guide-divider:     linear-gradient(to right, transparent, #6B6B6B 20%, #6B6B6B 80%, transparent) !important;

    /* accessibility.css tokens */
    --ac-fg:             #FFFFFF !important;
    --ac-muted-fg:       #DCDCDC !important;
    --ac-border:         #FFFFFF !important;
    --ac-surface:        #000000 !important;
    --ac-muted:          #0F0F0F !important;

    color-scheme: dark;
}

/* Translucent + blurred panels look smudged when forced onto a flat
   palette. Flatten them so they read as solid surfaces. This is the
   only "structural" change HC makes — it does NOT add borders or
   outlines anywhere, only kills the glassy filter. */
html.high-contrast .nav-top,
html.high-contrast .nav-rail,
html.high-contrast .nav-bottom,
html.high-contrast .ap-app,
html.high-contrast .ap-topbar,
html.high-contrast .ap-sidebar,
html.high-contrast .map-side-panel,
html.high-contrast .sheet-panel,
html.high-contrast .poi-panel,
html.high-contrast .map-toolbar,
html.high-contrast .map-floating-search,
html.high-contrast .map-basemap-popover,
html.high-contrast .tour-card,
html.high-contrast .tour-player,
html.high-contrast .tour-topbar,
html.high-contrast .scc-card {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* ── REDUCED MOTION ──
   Applied site-wide when the user opts in. Kill all transitions and
   animations everywhere. The OS-level `prefers-reduced-motion: reduce`
   media query is honoured separately by the browser. */
html.reduce-motion,
html.reduce-motion *,
html.reduce-motion *::before,
html.reduce-motion *::after {
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
}


/* ═══════════════════════════ NAV SKELETON ═══════════════════════════════
   `navigation.js` is loaded with `defer`, which means there is a brief
   window between HTML parse-complete and the script firing where
   `<div id="nav-root">` is empty and the visitor sees no nav at all.
   The CSS below fills that gap with a shimmering placeholder bar so
   the page's first paint never has a missing nav.

   It is rendered entirely with `:empty` + pseudo-elements so we don't
   need to inline any skeleton HTML in the 5+ public pages. The instant
   navigation.js writes the real nav (via `$root.html(buildTopNav() + …)`),
   `#nav-root` is no longer empty, the `:empty` rule stops matching, and
   the pseudos vanish — replaced atomically by the real `<nav>` markup.

   Visibility per breakpoint mirrors the real nav:
     • ≥ 1024 px (desktop)         → `::before` shows the top-nav bar.
     • <  1024 px (mobile + tablet)→ `::after`  shows the bottom-nav bar.

   The shimmer uses the same 110°/220%-width gradient idiom already in
   use elsewhere (`.is-skel-line` in guide.css) so it reads consistently
   across the app.                                                       */

@keyframes nav-skeleton-shimmer {
    0%   { background-position: 220% 0; }
    100% { background-position: -120% 0; }
}

#nav-root:empty::before,
#nav-root:empty::after {
    content: '';
    position: fixed;
    left: 0;
    right: 0;
    z-index: 100;
    pointer-events: none;
    background-color: var(--nv-surface);
    background-image: linear-gradient(110deg,
        rgba(184, 134, 11, 0.04) 0%,
        rgba(184, 134, 11, 0.20) 50%,
        rgba(184, 134, 11, 0.04) 100%);
    background-size: 220% 100%;
    animation: nav-skeleton-shimmer 1.6s linear infinite;
}

/* Top bar — visible on desktop only, same height as the real `.top-nav`. */
#nav-root:empty::before {
    top: 0;
    height: var(--nv-top-h);
    border-bottom: 1px solid var(--nv-border);
}
@media (max-width: 1023px) {
    #nav-root:empty::before { display: none; }
}

/* Bottom bar — visible on mobile + tablet only, includes the iOS
   safe-area inset the real `.bottom-nav` allocates via
   `--nv-bottom-total-h`. */
#nav-root:empty::after {
    bottom: 0;
    height: var(--nv-bottom-total-h);
    border-top: 1px solid var(--nv-border);
}
@media (min-width: 1024px) {
    #nav-root:empty::after { display: none; }
}

/* Dark theme — switch the highlight band to the brighter gold variant
   used by other dark-mode shimmer surfaces so the sweep stays readable
   on the near-black `--nv-surface`.                                    */
html.theme-dark #nav-root:empty::before,
html.theme-dark #nav-root:empty::after,
body.dark-mode  #nav-root:empty::before,
body.dark-mode  #nav-root:empty::after {
    background-image: linear-gradient(110deg,
        rgba(212, 175, 55, 0.04) 0%,
        rgba(212, 175, 55, 0.18) 50%,
        rgba(212, 175, 55, 0.04) 100%);
}

/* Honour the OS-level reduced-motion preference. The site-wide
   `.reduce-motion` rule above already pins this to 1 iteration, but
   browsers also expose `prefers-reduced-motion` independently. */
@media (prefers-reduced-motion: reduce) {
    #nav-root:empty::before,
    #nav-root:empty::after {
        animation: none;
    }
}
