/* Backbase Captain - live tour mode stylesheet.
   Tokens mirror tour.css (Backbase palette per CLAUDE.md). */
:root{
  --bb-light-blue:#E5EBFF;
  --bb-offwhite:#F3F6F9;
  --bb-border:#E0E2E6;
  --bb-text:#0E2B4D;
  --bb-muted:#4B5563;
  --font:'Libre Franklin',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --safe-top:env(safe-area-inset-top, 0px);
  --safe-bottom:env(safe-area-inset-bottom, 0px);

  /* Liquid Glass token set (2026-05-28 UI audit, Pattern 1). Used by the
     overlays that float over the map: status row, next-highlight strip,
     popup, GPS card, recenter FAB, compass, mini-player, SIM panel.
     Pair with @supports fallback at the bottom of this file. */
  /* Commit K (2026-07-06): the --glass-* set is now an ALIAS of the
     canonical --bb-glass-* tokens in styles/shared-prototype.css (radius
     22px, border alpha 0.55, navy-tinted shadow). The fallbacks carry the
     bb values so the surfaces render identically even without that file.
     --glass-bg-dark has no bb counterpart and keeps its own literal. */
  --glass-bg: var(--bb-glass-bg, rgba(255, 255, 255, 0.66));
  --glass-bg-dark: rgba(9, 28, 53, 0.66);
  --glass-blur: var(--bb-glass-blur, blur(22px) saturate(180%));
  --glass-border: 1px solid var(--bb-glass-border, rgba(255, 255, 255, 0.55));
  --glass-shadow: var(--bb-glass-shadow, 0 14px 44px rgba(9, 28, 53, 0.18),
                  inset 0 1px 0 rgba(255, 255, 255, 0.70));
  --glass-radius: var(--bb-glass-radius, 22px);
  --spring:        cubic-bezier(.32, .72, 0, 1);
  --spring-snap:   cubic-bezier(.34, 1.56, .64, 1);
  --spring-fast:   cubic-bezier(.4, 0, .2, 1);
  --t-fast: 180ms;
  --t-base: 260ms;
  --t-slow: 380ms;
}
/* Suppress the iOS / Chrome cyan tap-highlight flash on every button +
   interactive control. PWA captain feedback (audit 2026-05-25-1519 PWA
   dim 6): the flash is jarring during a live boat trip; not a single
   .lt-mini-btn / FAB / pill in the chrome wants it. Global reset for
   the whole live-tour surface. */
.lt-active, .lt-active *, .lt-nav, .lt-nav *, .lt-splash, .lt-splash * {
  -webkit-tap-highlight-color: transparent;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* Force the [hidden] attribute to always win over our display:flex rules below. */
[hidden]{display:none !important}
/* Drop the previous `html,body{height:100%;overflow:hidden}` lock -
   in iOS PWA standalone that constrained the layout viewport to the
   small viewport, clipping fixed children at the safe-area line.
   Now html/body grow naturally, .lt-main handles all sizing via its
   own min-height calc (see below). overscroll-behavior:none prevents
   iOS rubber-band scroll if anything inside ever overflows. */
/* overflow:hidden (NO height:100% lock - that lock was the old black-bar bug)
   clips the ~34px of safe-area scroll-slack that .lt-main's min-height
   (100dvh + safe) introduces. Without this the page is scrollable by the
   safe inset, so the fixed bottom-nav has two resting positions and the
   cross-document View Transition SLIDES it between them on navigation (the
   captain's "menu springt omhoog"). The .lt-main stage is normal-flow content
   taller than the viewport, so it still paints through the home-indicator
   zone (no black bar) - overflow:hidden only removes the scroll, not the bleed. */
html,body{margin:0;padding:0;overflow:hidden}
body{position:relative;overscroll-behavior:none}
body{
  font-family:var(--font);color:var(--bb-text);background:#fff;
  -webkit-font-smoothing:antialiased;line-height:1.5;font-size:15px;font-weight:400;
  overscroll-behavior:none;
}
/* In PWA standalone mode iOS reserves a strip at the top (status bar)
   and bottom (home indicator). With viewport-fit=cover the body extends
   into both safe areas. Paint the top safe area navy (matches the nav
   bar) and the bottom safe area in the map water-fallback color so the
   home-indicator zone visually merges with the map below the End-tour
   pill - no jarring white band between Google Maps' attribution and
   the screen edge. Captain feedback: "ik wil dat kaartje tot onderin
   reikt, net zoals bij index". */
/* see MEMORY.md project_session_2026_05_24 for the PWA viewport-bleed debug trail */
html{background:var(--bb-navy)}      /* visible behind iOS status bar */
body{background:#dee5ee}              /* safety net behind any uncovered bottom area */
a{color:var(--bb-blue);text-decoration:none}
button{font-family:inherit;border:none;background:none;cursor:pointer}

/* ── Top nav ──
   Content area is 64 px tall (was 54) so the 36 px pills inside have
   14 px of breathing room top + bottom instead of 9 px. Captain
   feedback: "te weinig padding boven en onder". */
.lt-nav{
  position:fixed;top:0;left:0;right:0;z-index:1000;
  background:var(--bb-navy);color:#fff;
  height:calc(64px + var(--safe-top));padding-top:var(--safe-top);
  display:flex;align-items:center;gap:0.75rem;padding-left:14px;padding-right:14px;
}
.lt-back{color:#fff;font-size:20px;line-height:1;
  width:36px;height:36px;border-radius:50%;
  background:rgba(255,255,255,0.08);
  border:1px solid rgba(255,255,255,0.16);
  margin-left:0;
  display:inline-flex;align-items:center;justify-content:center;
  text-decoration:none;
  transition:background 0.15s ease, transform 0.15s ease}
.lt-back:hover{background:rgba(255,255,255,0.14)}
.lt-back:active{transform:scale(0.94)}
.lt-title{flex:1;font-size:0.95rem;font-weight:500;letter-spacing:0.02em}
.lt-title-logo{flex:0 0 auto;margin-right:auto;background:transparent;border:none;
  padding:0 8px;cursor:pointer;border-radius:8px;display:inline-flex;
  align-items:center;justify-content:center;color:inherit;
  height:36px;
  transition:background 0.15s ease, transform 0.15s ease}
.lt-title-logo:hover{background:rgba(255,255,255,0.08)}
.lt-title-logo:active{transform:scale(0.95)}
.lt-title-logo[aria-expanded="true"]{background:rgba(105,254,255,0.16)}
/* 2026-06-08 (D1): the gear / settings panel adopts the shared always-dark
   glass material (--bb-glass-dark-* from shared-prototype.css) so it reads as
   the SAME navy-glass family as the on-map legend panels + the dark InfoWindow
   popups. The --bb-glass-dark-* tokens are theme-independent (this panel
   floats over a map that keeps its own theme), and fall back to the previous
   solid navy values so the panel never goes transparent if the token file is
   missing. */
/* 2026-06-09 (task 165, glass-design consistency): surface + header + layout
   now mirror the D5 P2 segmented cards (.vi-seg-card on vaarinfo /
   .vv-seg-card on vaarverkeer) exactly: blur(24px) saturate(160%), 18px
   radius, 0 12px 36px navy shadow, a 13px/600 header row with a 16px cyan
   icon, and the 11px/13px head + 2px/13px/12px body padding split. */
.lt-logo-panel{position:absolute;top:calc(100% + 4px);left:8px;z-index:1000;
  background:var(--bb-glass-dark-bg, #091C35);
  -webkit-backdrop-filter:blur(24px) saturate(160%);
  backdrop-filter:blur(24px) saturate(160%);
  border:1px solid var(--bb-glass-dark-border, rgba(255,255,255,0.18));border-radius:18px;
  padding:0;min-width:220px;
  box-shadow:0 12px 36px rgba(9,28,53,0.34)}
/* Header row = .vi-seg-head / .vv-seg-head spec: flex, gap 8, 11px 13px 9px. */
.lt-logo-panel-head{display:flex;align-items:center;gap:8px;
  padding:11px 13px 9px;
  font-size:13px;font-weight:600;
  color:var(--bb-glass-dark-ink, rgba(243,246,249,0.94))}
.lt-logo-panel-head-icon{width:16px;height:16px;flex:0 0 auto;
  fill:none;stroke:var(--bb-cyan, #69FEFF);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.lt-logo-panel-head-title{flex:1}
/* Body block = .vi-seg-panes spec. */
.lt-logo-panel-body{padding:2px 13px 12px}
.lt-logo-panel-row{display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-size:0.85rem;color:#fff;padding:6px 0}
.lt-logo-panel-route-row{flex-direction:column;align-items:stretch;gap:4px}
/* Route group label = the cyan uppercase section label family
   (.glass-grp / .vi-grp / .lt-sim-section-label). */
.lt-logo-panel-route-row .lt-logo-panel-label{font-size:0.62rem;font-weight:700;
  text-transform:uppercase;letter-spacing:0.1em;color:rgba(105,254,255,0.88)}
.lt-logo-panel-select{
  background:rgba(243,246,249,0.10);color:#fff;
  border:1px solid var(--bb-glass-dark-hairline, rgba(255,255,255,0.12));
  border-radius:10px;padding:8px 10px;font-family:var(--font);font-size:0.85rem;
  width:100%;cursor:pointer;
}
/* The translucent select needs an explicit option bg (the old solid #0B1F3E
   fill used to supply it implicitly) - white-on-white otherwise. */
.lt-logo-panel-select option{background:#091C35;color:#fff}
.lt-logo-panel-link{display:block;padding:8px 0;font-size:0.85rem;
  color:rgba(255,255,255,0.9);text-decoration:none;
  border-top:1px solid var(--bb-glass-dark-hairline, rgba(255,255,255,0.12))}
.lt-logo-panel-link:hover{color:#69FEFF}
.lt-logo-panel-version-row{margin-top:6px;border-top:1px solid var(--bb-glass-dark-hairline, rgba(255,255,255,0.12));padding-top:8px}
.lt-logo-panel-label{color:rgba(255,255,255,0.75)}
.lt-logo-panel .version-badge{margin-left:0;padding:2px 6px;border-left:none;
  color:#69FEFF;font-weight:600;display:flex;flex-direction:column;
  align-items:flex-end;gap:2px}
.lt-logo-panel .version-badge-v{font-weight:700;font-size:0.75rem}
.lt-logo-panel .version-badge-d{font-weight:400;font-size:0.65rem;
  color:rgba(255,255,255,0.55)}
/* Lang toggle: pill container with sliding cyan thumb (::before).
   Styling MATCHES tour.css .lang-toggle / .lang-btn exactly so the
   index.html and live.html flags look identical (captain feedback:
   "die van index status bar zijn goed", live flags were smaller +
   harder-dimmed). */
.lt-lang{display:inline-flex;align-items:center;position:relative;
  background:rgba(255,255,255,0.06);
  border:1px solid rgba(255,255,255,0.14);
  border-radius:999px;padding:0;gap:0;
  margin-right:0.6rem;isolation:isolate;
  height:36px;
}
.lt-lang::before{
  content:'';position:absolute;top:0;left:0;
  width:50%;height:100%;
  background:rgba(105,254,255,0.18);border-radius:999px;
  transition:transform 0.28s cubic-bezier(0.4,0,0.2,1);
  pointer-events:none;z-index:0;
}
.lt-lang:has(.lt-lang-btn:nth-child(2).active)::before{
  transform:translateX(100%);
}
.lt-lang-btn{padding:4px 8px;font-family:var(--font);font-size:0.7rem;font-weight:600;letter-spacing:0.04em;
  background:transparent;color:rgba(255,255,255,0.7);border:none;cursor:pointer;
  transition:opacity 0.18s ease;white-space:nowrap;
  display:inline-flex;align-items:center;justify-content:center;line-height:1;
  border-radius:999px;opacity:0.55;position:relative;z-index:1;flex:1}
.lt-lang-btn svg{display:block}
.lt-lang-btn:hover{opacity:0.9}
.lt-lang-btn.active{opacity:1}
@media (prefers-reduced-motion:reduce){
  .lt-lang::before{transition:none}
}

/* ── Main wrapper ──
   Use top + explicit height (rather than inset bottom:0) so the wrapper
   physically extends through the iOS home-indicator zone. With
   `bottom:0` in PWA standalone mode iOS treats it as "bottom of safe
   area" (above the home indicator), leaving a 100+ px strip below the
   wrapper that shows the body bg. Using `height: 100lvh - nav` forces
   the wrapper to claim the full viewport including the safe-area zone.
   Background matches map water-fallback as a final safety net. */
/* see MEMORY.md project_session_2026_05_24 for the PWA viewport-bleed debug trail */
.lt-main{
  position:relative;
  /* 100vh fallback for older iOS (no svh support); then 100svh = the STABLE
     small-viewport height. We deliberately do NOT use 100dvh here: on iOS
     standalone, dvh is reported small at first paint and GROWS ~60px as the
     safe-areas settle over the first ~300-400ms (measured on the captain's
     device: 812 -> 874px). Pinning this stage to dvh reflowed the whole Live
     view AFTER it had already painted = the captain's Live-ONLY "sprong"
     (Routes/More are normal-flow and never reference the viewport, so they
     never jump). svh is computed once and does NOT grow, so the stage is the
     right size from the first paint -> no reflow, no jump. The
     +safe-area-inset-bottom still bleeds the stage through the iOS
     home-indicator zone in PWA mode (keeps the black-bar fix). */
  min-height:calc(100vh + env(safe-area-inset-bottom, 0px));
  min-height:calc(100svh + env(safe-area-inset-bottom, 0px));
  padding-top:calc(64px + var(--safe-top));
  overflow:hidden;
  background:#dee5ee;
}
/* min-height covers nav-below-area only - no extra safe-area opslag.
   .lt-main already has min-height calc(100vh + safe-area-inset-bottom)
   so the map (.lt-map abs inset:0 inside .lt-active) still extends
   through the home-indicator zone via .lt-main's container.
   Adding +safe-area here would DOUBLE-count it via padding-bottom
   on .lt-active below, pushing floating cards into the device corner
   radius (captain reported: LOCATION OFF card visibly clipped). */
.lt-active{
  /* 100vh fallback for older iOS, then 100svh (STABLE) - same reasoning as
     .lt-main above: dvh grows ~60px after first paint on iOS standalone and
     reflowed the stage. svh holds steady. */
  min-height:calc(100vh - 64px - var(--safe-top));
  min-height:calc(100svh - 64px - var(--safe-top));
}

/* ── Splash (pre-start) ──
   Edge-to-edge dark splash (Pattern 3, UI audit 2026-05-28). The
   centred white card-on-light-gradient was replaced with a navy
   gradient mesh that bleeds full-bleed and bottom-anchors the CTA
   above the home-indicator zone. Every existing element id stays so
   the JS event handlers (Start button, route picker, Sim mode toggle)
   keep working unchanged. Per Backbase Colour Rule: dark background
   lightness < 25% means white text is permitted here. */
.lt-splash{
  position:absolute;inset:0;
  /* The CTA is pinned as a fixed action bar (see .lt-splash .lt-cta below);
     the splash scrolls as one page behind it. Reserve bottom padding equal
     to the pinned CTA footprint (its bottom offset + button height + a top
     gap) so the LAST route card is reachable above the bar and never hidden
     behind it. --lt-cta-h is the measured CTA height. */
  display:flex;flex-direction:column;justify-content:flex-start;
  /* Horizontal padding is 0 here: the .lt-splash-card below owns the 24px
     gutter via the canonical .bb-page box, so the content column + its left
     edge line up EXACTLY with the Routes page (captain 2026-06-03). */
  padding:calc(64px + var(--safe-top) + 24px) 0
          calc(var(--bb-nav-h-mobile, 60px) + var(--safe-bottom)
                + var(--lt-cta-h, 52px) + 44px);
  color:#fff;overflow-y:auto;
  background:
    radial-gradient(120% 80% at 0% 0%,
      rgba(105,254,255,0.22) 0%, transparent 60%),
    radial-gradient(120% 80% at 100% 30%,
      rgba(51,102,255,0.30) 0%, transparent 65%),
    linear-gradient(180deg,
      #091C35 0%, #061224 60%, #03070F 100%);
}
.lt-splash::before{
  /* Subtle canal-grain so the gradient mesh feels organic. */
  content:'';position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(2px 2px at 12% 18%, rgba(255,255,255,0.06), transparent 60%),
    radial-gradient(2px 2px at 64% 72%, rgba(255,255,255,0.05), transparent 60%),
    radial-gradient(2px 2px at 38% 88%, rgba(255,255,255,0.04), transparent 60%),
    radial-gradient(2px 2px at 82% 22%, rgba(255,255,255,0.05), transparent 60%);
}
.lt-splash-card{
  /* Card-on-card shell is gone - the card just flows on the dark bg.
     Existing JS still targets .lt-splash-card child elements by id; no
     structural change. Position relative so children sit above ::before. */
  position:relative;
  /* Canonical .bb-page box (captain 2026-06-03: the live tour page width +
     title must be IDENTICAL to the Routes page - same 1304 max-width + 24px
     gutter so the title's left edge tracks the wordmark exactly like
     .bb-route-cards). One shared width standard, no per-page value. */
  width:100%;max-width:1304px;margin:0 auto;padding:0 24px;box-sizing:border-box;
  background:transparent;border:none;border-radius:0;box-shadow:none;
}
.lt-splash h1{
  /* Same size as the Routes page title "Kies een route" - the canonical
     page-header values from shared-prototype.css (captain 2026-06-02:
     "zelfde fontsize als Kies een route"). */
  font-size:clamp(1.6rem, 4.4vw, 2.4rem);font-weight:500;line-height:1.18;letter-spacing:-0.018em;
  color:#fff;text-align:left;margin:0 0 6px;
}
.lt-splash p{
  color:rgba(255,255,255,0.72);text-align:left;
  font-size:0.95rem;margin-bottom:1.25rem;
}
.lt-perm-list{list-style:none;margin:0 0 1.5rem 0;padding:0;border-top:1px solid var(--bb-border)}
.lt-perm-list li{
  padding:12px 4px;border-bottom:1px solid var(--bb-border);
  font-size:0.875rem;color:var(--bb-text);
}
.lt-perm-list strong{color:var(--bb-navy);font-weight:600;margin-right:4px}
.lt-perm-list span{color:var(--bb-muted)}
.lt-cta{
  /* Pattern 3: glossy gradient pill with inset highlight + soft drop shadow.
     Sits at the bottom of the dark splash, snaps on press. */
  width:100%;padding:16px 20px;font-size:1.05rem;font-weight:600;letter-spacing:0.02em;
  background:linear-gradient(180deg, #3F7BFF 0%, #2855E0 100%);
  color:#fff;border-radius:16px;
  box-shadow:0 14px 32px rgba(51,102,255,0.40),
             inset 0 1px 0 rgba(255,255,255,0.25);
  transition:transform var(--t-fast) var(--spring-snap),
             box-shadow var(--t-base) var(--spring);
}
.lt-cta:hover{background:linear-gradient(180deg, #4884FF 0%, #2D5BE8 100%)}
.lt-cta:active{transform:scale(0.97)}
.lt-cta:disabled{background:rgba(255,255,255,0.16);color:rgba(255,255,255,0.55);
  box-shadow:none;opacity:1}
/* Captain 2026-06-01: PIN the START-screen CTA as an action bar that is
   always fully visible above the floating bottom tab bar. The route list
   now flows so the whole .lt-splash scrolls as one page; the CTA used to
   flow at the end of the list and slid partly behind .bb-mobile-nav on tall
   phones. Pinned bottom offset clears the nav (mobile) / safe-area
   (desktop). Scoped to .lt-splash so the active full-screen tour (.lt-active,
   which has no .lt-cta) is untouched. The proto variant in pages/live.html
   (body.lt-proto .lt-splash .lt-cta) wins on specificity and carries the
   live values; this base rule is the fallback when the proto class is
   absent. The matching scroll-content bottom padding lives on .lt-splash
   above so the last route card stays reachable above the pinned bar. */
.lt-splash .lt-cta{
  position:fixed;
  left:20px;right:20px;
  /* +28px cushion: the floating nav renders ~77px from the viewport bottom,
     taller than the 60px token, so clear its real footprint. */
  bottom:calc(var(--safe-bottom) + var(--bb-nav-h-mobile, 60px) + 28px);
  width:auto;max-width:480px;margin:0 auto;
  z-index:75;
}
@media (min-width:960px){
  .lt-splash .lt-cta{ bottom:calc(var(--safe-bottom) + 16px); }
  /* Desktop: lift the splash title to the SAME vertical position as the Routes
     page title "Kies een route" so the title never jumps when switching tabs
     (captain 2026-06-20). Routes desktop clears safe-top + nav-h-desktop(64) +
     32 = 96; the splash mobile padding (64 + 24 = 88) already matches Routes
     mobile (nav-h-mobile 60 + 28 = 88), so only desktop needs the +8. */
  .lt-splash{ padding-top:calc(64px + var(--safe-top) + 32px); }
}
.lt-fine{
  text-align:center;font-size:0.75rem;color:rgba(255,255,255,0.55);
  margin-top:0.75rem;line-height:1.4;
}

/* Dev toggle on the splash - dark variant for Pattern 3. No longer
   sits as a flush footer (no card edge to flush against); just a
   tinted pill below the CTA. The :hover/:active behaviour is unchanged. */
.lt-splash-sim{
  display:flex;align-items:center;gap:10px;
  margin:14px 0 0;padding:10px 14px;
  background:rgba(255,255,255,0.05);
  border:1px solid rgba(255,255,255,0.12);
  border-radius:12px;color:#fff;
  cursor:pointer;
}
.lt-splash-sim-toggle{
  width:18px;height:18px;accent-color:var(--bb-blue);cursor:pointer;flex-shrink:0;
}
.lt-splash-sim-text{display:flex;flex-direction:column;line-height:1.3}
.lt-splash-sim-label{font-size:0.8rem;font-weight:600;color:#fff}
.lt-splash-sim-hint{font-size:0.7rem;color:rgba(255,255,255,0.6)}

/* Inline route picker - sits directly above the Start button. Pattern 3
   makes it a translucent glass tile on the dark splash. */
.lt-splash-route-inline{
  display:flex;flex-direction:column;gap:4px;
  margin:14px 0 16px;text-align:left;
  padding:12px 14px;
  background:rgba(255,255,255,0.08);
  backdrop-filter:blur(14px) saturate(180%);
  -webkit-backdrop-filter:blur(14px) saturate(180%);
  border:1px solid rgba(255,255,255,0.16);
  border-radius:16px;
}
.lt-splash-route-inline-label{
  font-size:0.7rem;font-weight:600;letter-spacing:0.08em;
  text-transform:uppercase;color:rgba(255,255,255,0.6);
}
.lt-splash-route-inline-select{
  width:100%;padding:8px 0;font-family:var(--font);
  font-size:0.95rem;font-weight:500;
  background:transparent;color:#fff;border:none;
  appearance:none;-webkit-appearance:none;cursor:pointer;
}
.lt-splash-route-inline-select option{
  background:#091C35;color:#fff;
}

/* ── Splash route CARDS (captain 2026-05-31: pick a route the same way as on
   the Routes page, replacing the dropdown). A grid of glass tiles; the
   selected one gets a cyan ring + check. Captain 2026-06-01: the grid no
   longer scrolls inside its own box - it flows at natural height and the
   whole splash (.lt-splash) scrolls as one page instead. ── */
.lt-splash-route-pick{ margin:0; text-align:left; }
.lt-splash-route-pick-label{
  /* Identical to the Routes page .bb-section-label (captain 2026-06-03 "zelfde
     als routes"): 0.72rem / 0.12em / weight 600 / 24px top + 12px bottom.
     Colour stays theme-aware white-60 (dark splash) / navy-60 (light splash,
     via the override below), which matches --bb-fg-muted per theme. */
  display:block;font-size:0.72rem;font-weight:600;letter-spacing:0.12em;
  text-transform:uppercase;color:rgba(255,255,255,0.6);margin:24px 0 12px;
}
/* Captain 2026-06-01 ("live tour routes moeten er net zoals uitzien als bij
   routes"): the splash route picker now uses the SAME card shape as the
   Routes-page cards (.bb-route-card in pages/index.html) - large, full-width,
   single-column cards: a 16/9 aquarel route-outline cover on top, then a
   card-surface info block with the title (h3-weight), a meta line, and a
   short teaser. All values below are copied from the .bb-route-card /
   .bb-route-card-cover / .bb-route-card-inner rules so the two read as ONE
   component. Scoped to .lt-splash-route* so nothing leaks onto other pages,
   and the shared .bb-route-cards selectors (the Routes page reference) are
   left untouched. Card surface uses the --bb-* tokens, which flip with the
   theme, so the card is dark #0E2240 on the dark splash and white on the
   light splash - identical to how the Routes cards behave per theme. */
.lt-splash-routes{
  /* Multi-column card grid - identical pattern to the Routes page
     (.bb-route-cards-grid) so the Live picker reads the same way: compact
     cards in a responsive grid instead of one big stacked card per row.
     Captain feedback 2026-06-02: "live moet veel meer op routes lijken". */
  display:grid;grid-template-columns:repeat(auto-fit, minmax(260px, 1fr));gap:14px;
}
.lt-splash-route-card{
  position:relative;display:flex;flex-direction:column;text-align:left;width:100%;
  padding:0;overflow:hidden;border-radius:14px;cursor:pointer;font-family:var(--font);
  color:inherit;
  background:var(--bb-bg-card, #fff);
  border:1px solid var(--bb-border, rgba(9,28,53,0.10));
  transition:transform 240ms cubic-bezier(.2,.7,.3,1.4),
             box-shadow 240ms ease, border-color 240ms ease;
}
.lt-splash-route-card:hover{
  transform:translateY(-2px);
  border-color:rgba(51,102,255,0.45);
  box-shadow:0 6px 18px rgba(9,28,53,0.10), 0 0 0 1px rgba(51,102,255,0.20);
}
.lt-splash-route-card:active{ transform:scale(0.99); }
.lt-splash-route-card.is-selected{
  border-color:var(--bb-cyan, #69FEFF);
  box-shadow:0 0 0 1px var(--bb-cyan, #69FEFF), 0 10px 24px rgba(105,254,255,0.18);
}
/* Aquarel route-shape cover (rendered by BBRouteCover) - same 16/9 + top
   radius as the Routes-page .bb-route-card-cover. */
.lt-splash-route-cover{
  display:block;width:100%;aspect-ratio:16/9;overflow:hidden;
  border-radius:14px 14px 0 0;
  background:radial-gradient(circle at 30% 30%, #C5DAFC, #E5EBFF 70%);
}
.lt-splash-route-cover svg{ display:block;width:100%;height:100%; }

/* ── Route-line ink-in (captain 2026-06-02: "de animatie van routes wil ik
   ook bij live"). Mirrors the Routes-page draw: the polyline inks in when its
   splash card appears (.in-view, added by JS - a guaranteed first-batch
   cascade + IntersectionObserver), and replays on hover (pointer devices).
   --aq-len is set per polyline by BBRouteCover.renderPolyline; `both` fill
   back-fills the hidden `from` during the per-card --aq-delay stagger so it
   inks in (no flash) WITHOUT a persistent hidden rest state. Rest stays
   offset:0 (fully drawn) so a card that never gets .in-view is never blank.
   These keyframes live here because the Routes page defines its own inline
   (live.html doesn't load index.html's styles). */
.lt-splash-route-cover svg polyline.aq-line{
  stroke-dasharray:var(--aq-len, 2000);
  stroke-dashoffset:0;
}
.lt-splash-route-card.in-view .lt-splash-route-cover svg polyline.aq-line{
  animation:bb-aq-draw-on 1200ms cubic-bezier(.65,0,.35,1) var(--aq-delay, 0ms) both;
}
@media (hover:hover){
  .lt-splash-route-card:hover .lt-splash-route-cover svg polyline.aq-line{
    animation:bb-aq-draw-on 1200ms cubic-bezier(.65,0,.35,1) forwards;
  }
}
@keyframes bb-aq-draw-on{
  from{ stroke-dashoffset:var(--aq-len, 2000); }
  to  { stroke-dashoffset:0; }
}
.lt-splash-route-cover svg circle.aq-dot-start{ transform-box:fill-box; transform-origin:center; }
.lt-splash-route-card.in-view .lt-splash-route-cover svg circle.aq-dot-start{
  animation:bb-aq-dot-pulse 1400ms ease-in-out var(--aq-delay, 0ms) 3;
}
@media (hover:hover){
  .lt-splash-route-card:hover .lt-splash-route-cover svg circle.aq-dot-start{
    animation:bb-aq-dot-pulse 1400ms ease-in-out infinite;
  }
}
@keyframes bb-aq-dot-pulse{
  0%, 100%{ transform:scale(1);    opacity:1; }
  50%     { transform:scale(1.55); opacity:0.65; }
}
@media (prefers-reduced-motion: reduce){
  .lt-splash-route-cover svg polyline.aq-line,
  .lt-splash-route-cover svg circle.aq-dot-start{ animation:none !important; }
  .lt-splash-route-cover svg polyline.aq-line{ stroke-dashoffset:0 !important; }
}
/* Dark-mode cover (captain 2026-05-31 "dark mode klopt niet"): the light
   aquarel paper is wrong on the dark splash - recolor to the SAME navy aurora
   + glowing cyan route line as the Routes-page covers do in dark mode. */
:root[data-theme="dark"] .lt-splash-route-cover{
  background:
    radial-gradient(ellipse at 50% 50%, rgba(51,102,255,0.25), transparent 70%),
    linear-gradient(135deg, #0A1224 0%, #0E2240 100%);
}
:root[data-theme="dark"] .lt-splash-route-cover svg > rect[fill^="url(#aq-bg-"],
:root[data-theme="dark"] .lt-splash-route-cover svg > rect[fill^="url(#aqi-bg-"]{ fill:transparent; }
:root[data-theme="dark"] .lt-splash-route-cover svg circle[filter^="url(#aq-blur-"],
:root[data-theme="dark"] .lt-splash-route-cover svg circle[filter^="url(#aqi-blur-"]{ display:none; }
:root[data-theme="dark"] .lt-splash-route-cover svg polyline{
  stroke:#69FEFF;stroke-width:3;
  filter:drop-shadow(0 0 4px rgba(105,254,255,0.65)) drop-shadow(0 0 2px rgba(105,254,255,0.5));opacity:1;
}
:root[data-theme="dark"] .lt-splash-route-cover svg circle[fill="#091C35"][stroke="#FFFFFF"]{ fill:#69FEFF;stroke:#FFFFFF; }
:root[data-theme="dark"] .lt-splash-route-cover svg g[stroke="#091C35"],
:root[data-theme="dark"] .lt-splash-route-cover svg g path[stroke="#091C35"],
:root[data-theme="dark"] .lt-splash-route-cover svg g circle[stroke="#091C35"],
:root[data-theme="dark"] .lt-splash-route-cover svg g rect[stroke="#091C35"]{ stroke:#69FEFF; }
:root[data-theme="dark"] .lt-splash-route-cover svg g circle[fill="#091C35"],
:root[data-theme="dark"] .lt-splash-route-cover svg g rect[fill="#091C35"],
:root[data-theme="dark"] .lt-splash-route-cover svg g path[fill="#091C35"]{ fill:#69FEFF; }
/* Info block below the cover - matches .bb-route-card-inner padding. */
.lt-splash-route-body{ display:flex;flex-direction:column;padding:14px 18px 18px;min-width:0; }
/* Title styled like the Routes-card h3 (it is a <span>, not an <h3>, but the
   look is identical). Wraps onto two lines like the Routes cards instead of
   truncating with an ellipsis. */
.lt-splash-route-name{ font-size:1.02rem;font-weight:500;letter-spacing:-0.014em;
  line-height:1.25;color:var(--bb-fg-default); }
/* Meta line (duration · area) + teaser - matches .bb-route-card-meta /
   .bb-route-card-teaser on the Routes page (captain 2026-06-03). */
.lt-splash-route-meta{ display:flex;gap:10px;flex-wrap:wrap;font-size:0.78rem;color:var(--bb-fg-muted);
  font-variant-numeric:tabular-nums;margin:6px 0 8px; }
.lt-splash-route-meta span::before{ content:"· ";opacity:0.55; }
.lt-splash-route-meta span:first-child::before{ content:""; }
.lt-splash-route-teaser{ display:block;font-size:0.88rem;line-height:1.45;color:var(--bb-fg-muted);margin:0; }
.lt-splash-route-check{ position:absolute;top:8px;right:8px;width:24px;height:24px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:800;
  background:var(--bb-cyan, #69FEFF);color:var(--bb-navy, #091C35);box-shadow:0 2px 8px rgba(0,0,0,0.3);
  opacity:0;transform:scale(0.6);
  transition:opacity var(--t-fast) ease, transform var(--t-fast) var(--spring-snap); }
.lt-splash-route-card.is-selected .lt-splash-route-check{ opacity:1;transform:scale(1); }
/* Light theme: the card surface + text already flip via the --bb-* tokens
   (white card, navy text, muted-navy meta) exactly like the Routes cards in
   light mode, so no per-element colour override is needed. We only adjust the
   pick label, the selected-ring accent (blue instead of cyan, matching the
   Routes light accent), and the checkmark colour. */
:root[data-theme="light"] .lt-splash-route-pick-label{ color:rgba(9,28,53,0.6); }
:root[data-theme="light"] .lt-splash-route-card.is-selected{
  border-color:var(--bb-blue,#3366FF);
  box-shadow:0 0 0 1px var(--bb-blue,#3366FF), 0 10px 24px rgba(51,102,255,0.16);
}
:root[data-theme="light"] .lt-splash-route-check{ background:var(--bb-blue,#3366FF);color:#fff; }
/* Gear-panel Sim-mode row hint (the toggle moved here from the splash). */
.lt-sim-modehint{ display:block;font-size:0.7rem;color:rgba(243,246,249,0.5);margin-top:2px;flex-basis:100%; }

/* ── Splash: LIGHT-MODE variant (captain "dit is geen light mode" 2026-05-31) ──
   The base .lt-splash rules above hardcode an edge-to-edge dark-navy
   gradient with white text. That is correct for DARK mode but ignored
   theme entirely, so in LIGHT mode the splash stayed fully dark while
   the rest of the site went light. These [data-theme="light"] overrides
   flip the splash to a soft light surface with dark same-hue text per
   the Backbase Colour Rule (light tint bg + dark same-hue text, never
   white-on-light). Dark mode is untouched - it falls through to the
   base rules above. Only the splash (a full-screen PAGE surface) is
   flipped here; the on-map glass chrome (compass / status pills /
   mini-player / popups) stays dark-glass in both themes by design,
   since it floats over the live map and reads on any map imagery. */
:root[data-theme="light"] .lt-splash{
  /* Light gradient mesh: soft blue + cyan tints over the off-white page
     background. Mirrors the dark gradient's structure (two radial tints
     + a vertical base) but in light tones. */
  color:var(--bb-navy);
  background:
    radial-gradient(120% 80% at 0% 0%,
      rgba(105,254,255,0.20) 0%, transparent 60%),
    radial-gradient(120% 80% at 100% 30%,
      rgba(51,102,255,0.14) 0%, transparent 65%),
    linear-gradient(180deg,
      #F3F6F9 0%, #E9EFF8 55%, #E5EBFF 100%);
}
:root[data-theme="light"] .lt-splash::before{
  /* Soften the decorative grain so it does not read as dirt on the
     light surface (the dark grain dots used white at low alpha which
     would be invisible on light anyway). */
  background:
    radial-gradient(2px 2px at 12% 18%, rgba(9,28,53,0.05), transparent 60%),
    radial-gradient(2px 2px at 64% 72%, rgba(9,28,53,0.04), transparent 60%),
    radial-gradient(2px 2px at 38% 88%, rgba(9,28,53,0.03), transparent 60%),
    radial-gradient(2px 2px at 82% 22%, rgba(9,28,53,0.04), transparent 60%);
}
:root[data-theme="light"] .lt-splash h1{ color:var(--bb-navy); }
:root[data-theme="light"] .lt-splash p{ color:rgba(9,28,53,0.66); }
:root[data-theme="light"] .lt-fine{ color:rgba(9,28,53,0.50); }
/* Inline route picker: light glass tile (white tint + navy text). */
:root[data-theme="light"] .lt-splash-route-inline{
  background:rgba(255,255,255,0.72);
  border:1px solid rgba(9,28,53,0.10);
}
:root[data-theme="light"] .lt-splash-route-inline-label{
  color:rgba(9,28,53,0.55);
}
:root[data-theme="light"] .lt-splash-route-inline-select{
  color:var(--bb-navy);
}
:root[data-theme="light"] .lt-splash-route-inline-select option{
  background:#fff;color:var(--bb-navy);
}
/* Sim-mode toggle pill: light tint + navy text. */
:root[data-theme="light"] .lt-splash-sim{
  background:rgba(255,255,255,0.66);
  border:1px solid rgba(9,28,53,0.10);
  color:var(--bb-navy);
}
:root[data-theme="light"] .lt-splash-sim-label{ color:var(--bb-navy); }
:root[data-theme="light"] .lt-splash-sim-hint{ color:rgba(9,28,53,0.60); }
/* Disabled CTA: keep it readable on the light surface (the base
   disabled rule uses white-on-white-ish which vanishes on light). The
   enabled CTA stays the blue gradient with white text - that's a
   saturated brand fill, allowed in both themes. */
:root[data-theme="light"] .lt-cta:disabled{
  background:rgba(9,28,53,0.10);color:rgba(9,28,53,0.45);
}

/* ── Active mode layout (PWA bottom-bleed) ──
   The map fills the ENTIRE .lt-active area as the background
   (position:absolute, z-index:0). All UI children (status row, next
   card, popup, GPS card, End-tour button) stack at the bottom via
   flex justify-content:flex-end and float on top of the map (z-index:1).
   The .lt-active's padding-bottom is JUST the iOS safe-area, so the
   home-indicator zone visibly shows MAP through (not white) - that's
   the "map bleeds bottom" behaviour the captain asked for. */
.lt-active{
  position:absolute;inset:0;
  display:flex;flex-direction:column;justify-content:flex-end;
  /* padding-bottom = 2*safe-area + 8 because .lt-active extends through
     the safe-area (.lt-main has min-height +safe-area, .lt-active inset:0).
     Cards stack from content-area-bottom which is
       (border-box-bottom) - (padding-bottom)
       = (viewport_bottom + safe-area) - (2*safe-area + 8)
       = viewport_bottom - safe-area - 8 (= safe-area-line - 8)
     so floating cards sit clearly ABOVE the iPhone corner-radius zone.
     Captain spotted LOCATION OFF card getting its bottom corners clipped
     by the device curvature with single-safe-area padding. */
  padding-bottom:calc(env(safe-area-inset-bottom, 0px) * 2 + 8px);
}
.lt-map{
  position:absolute;inset:0;z-index:0;
  width:100%;height:100%;
  background:#dee5ee;
  /* Now that the viewport meta no longer locks user-scalable=no, the iOS
     double-tap-to-zoom gesture would fight Google Maps' own double-tap
     zoom. touch-action: manipulation tells Safari this region handles its
     own gestures - pinch + double-tap stay with the map, the page stops
     fielding them. Only applied to the map container, never to body/html
     (which would break in-app scroll-zoom on the rest of the page). */
  touch-action:manipulation;
}
/* All non-map children sit above the map. */
.lt-next,
.lt-popup,
.lt-gps-card,
.lt-log-wrap,
.lt-end{position:relative;z-index:1}

/* North-compass widget. Sits in the top-left of the map, only visible when
   Nav mode (heading-up) is active. The SVG inside rotates counter to the
   current map heading so the "N" always points to geographic north. Tap
   toggles compass-mode. */
.lt-compass{
  position:absolute;top:14px;left:14px;z-index:4;
  width:38px;height:38px;padding:0;border:none;border-radius:50%;
  /* Liquid Glass treatment (Pattern 1) - bumped from solid 0.92 white +
     thin shadow to translucent + 22px blur + inset highlight. Falls back
     to the old solid bg in @supports block at the bottom of the file. */
  background:var(--glass-bg);
  backdrop-filter:var(--glass-blur);
  -webkit-backdrop-filter:var(--glass-blur);
  border:var(--glass-border);
  box-shadow:var(--glass-shadow);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;
}
.lt-compass[hidden]{display:none}
.lt-compass-rose{display:block;will-change:transform;transition:transform 120ms linear}

/* Re-center FAB (wizard 5). Sits bottom-right of the map, clear of the
   status-row pill + the .lt-next / .lt-popup card stack at the bottom of
   .lt-active. Anchored inside #ltMap (absolute) so it follows the map
   geometry, with env(safe-area-inset-bottom) keeping it clear of the
   home indicator. The 120px offset accounts for status-row height (~44px)
   + popup card height (~64px) + a small gap. Default hidden; live-tour.js
   reveals it on map dragstart. */
.lt-recenter{
  position:absolute;
  right:calc(env(safe-area-inset-right, 0px) + 14px);
  bottom:calc(env(safe-area-inset-bottom, 0px) + 120px);
  z-index:5;
  width:44px;height:44px;padding:0;
  border:var(--glass-border);border-radius:50%;
  /* Liquid Glass treatment (Pattern 1). Commit K: --glass-bg now follows
     the themed --bb-glass-bg (navy in dark mode), so the icon ink follows
     --bb-glass-ink (navy on light glass, near-white on dark glass) instead
     of hard navy - otherwise the arrow disappears in dark theme. */
  background:var(--glass-bg);color:var(--bb-glass-ink, var(--bb-navy));
  backdrop-filter:var(--glass-blur);
  -webkit-backdrop-filter:var(--glass-blur);
  box-shadow:var(--glass-shadow);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;
  transition:opacity 160ms ease-out, transform 160ms ease-out;
}
.lt-recenter[hidden]{display:none}
.lt-recenter:active{transform:scale(0.92)}
.lt-recenter:hover{background:rgba(255,255,255,0.82)}
/* .lt-status-row + .lt-status-pill zijn vervallen met P3 (2026-07-26): er is
   geen balk meer boven de kaart. De GPS-staat zit nu op de dot-badge van de
   terug-chip (.lt-gps-badge) plus de exception-only toast (.lt-gps-toast),
   beide gestyled in pages/live.html. De .lt-dot-kleuren hieronder blijven -
   die zet setGpsState() op de badge. */
.lt-dot{width:8px;height:8px;border-radius:50%;background:#d0d4d9;flex-shrink:0;transition:background 0.3s}
.lt-dot-ok{background:#0F7B4F}
.lt-dot-warn{background:#D94F07}
.lt-dot-err{background:var(--bb-red)}
.lt-mini-btn{
  padding:6px 10px;font-size:1rem;line-height:1;
  background:var(--bb-offwhite);border:1px solid var(--bb-border);border-radius:8px;
}
/* position:relative draagt de count-badge (.lt-strem-count). */
#ltStremBtn{position:relative}
.lt-mini-btn[aria-pressed="true"]{background:var(--bb-light-blue);border-color:var(--bb-blue)}

/* Nav / Compass toggle. The "on" glyph is a triangle (▲) so it visually
   reads as "arrow pointing the direction of travel". The "off" glyph is
   the compass-rose emoji (🧭) which reads as north-up. Both share the same
   pill, and aria-pressed swaps the background tint via the rule above. */
.lt-nav-btn{margin-left:8px;display:inline-flex;align-items:center;gap:2px}
.lt-nav-btn .lt-nav-on{color:var(--bb-blue);font-size:0.85rem;line-height:1}
.lt-nav-btn .lt-nav-off{font-size:0.95rem;line-height:1}

/* Stremmingen toggle - red accent when active, count badge bottom-right */
.lt-strem-btn[aria-pressed="true"]{background:#FFE8E4;border-color:var(--bb-red)}
.lt-strem-count{
  position:absolute;bottom:-4px;right:-4px;
  min-width:14px;height:14px;padding:0 3px;
  font-size:0.55rem;font-weight:700;line-height:14px;text-align:center;
  background:#B45309;color:#fff;border-radius:8px;
  display:none;
}
.lt-strem-btn[data-count]:not([data-count="0"]) .lt-strem-count{display:inline-block}

/* ── Canal-name pill under the own-boat marker ─────────────────────────────
   The Google-nav "current street" pattern, on water (captain 2026-07-26).
   Lives INSIDE the .lt-me-marker AdvancedMarkerElement content, so Google
   places it through the rotated/tilted projection while the DOM itself stays
   screen-upright - no manual lat/lng-to-pixel maths (which is unreliable on
   vector maps anyway, see boats-labels.js).
   Deliberately the QUIET glass variant: same light glass as .lt-status-pill,
   no pulse, no glow. Those belong to .lt-approach-card, which has to shout.
   pointer-events:none so it can never eat a map tap (the boat-tap sheet). */
.lt-canal-pill{
  position:absolute;
  top:100%;left:50%;
  transform:translate(-50%,6px);
  pointer-events:none;
  max-width:44vw;
  padding:3px 10px;
  background:var(--glass-bg);
  color:var(--bb-glass-ink, var(--bb-navy));
  backdrop-filter:var(--glass-blur);
  -webkit-backdrop-filter:var(--glass-blur);
  border:var(--glass-border);
  border-radius:999px;
  box-shadow:0 2px 8px rgba(9,28,53,0.16);
  font-size:0.72rem;font-weight:600;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:opacity 160ms ease-out;
}
.lt-canal-pill[hidden]{display:none}
@media (prefers-reduced-motion:reduce){
  .lt-canal-pill{transition:none}
}

/* ── Next highlight card ── */
.lt-next{
  /* Liquid Glass card (Pattern 1). Radius bumped from 12 to 24px for
     the proper iOS card look. */
  margin:0 8px 8px;border-radius:var(--glass-radius);
  padding:8px 14px 10px;
  background:var(--glass-bg);
  backdrop-filter:var(--glass-blur);
  -webkit-backdrop-filter:var(--glass-blur);
  border:var(--glass-border);
  box-shadow:var(--glass-shadow);
}
.lt-next-label{
  font-size:0.625rem;font-weight:600;text-transform:uppercase;letter-spacing:0.12em;
  color:var(--bb-blue);margin-bottom:2px;
}
.lt-next-title{font-size:0.95rem;font-weight:500;color:var(--bb-navy);line-height:1.25}
.lt-next-dist{font-size:0.75rem;color:var(--bb-muted);margin-top:1px}

/* ── Log ── */
.lt-log-wrap{
  background:#fff;border-top:1px solid var(--bb-border);
  max-height:14vh;min-height:60px;display:flex;flex-direction:column;
}
.lt-log-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:6px 16px;font-size:0.625rem;font-weight:600;text-transform:uppercase;
  letter-spacing:0.12em;color:var(--bb-muted);
}
.lt-reset{
  font-size:0.7rem;font-weight:600;color:var(--bb-blue);letter-spacing:0.04em;
  text-transform:uppercase;padding:4px 8px;
}
.lt-log{list-style:none;overflow-y:auto;padding:0 16px 8px}
.lt-log li{
  padding:5px 0;border-top:1px solid var(--bb-border);
  font-size:0.8rem;color:var(--bb-text);
  display:flex;gap:8px;align-items:baseline;
}
.lt-log li:first-child{border-top:none}
.lt-log li time{font-size:0.65rem;color:var(--bb-muted);flex-shrink:0;font-variant-numeric:tabular-nums}
.lt-log-empty{color:var(--bb-muted);font-style:italic;font-size:0.8rem;text-align:center;padding:8px 0}

/* ── End-tour button ──
   Flex-end child of .lt-active. Sits flush above the iOS safe-area
   zone (the .lt-active padding-bottom is env(safe-area-inset-bottom)).
   The home-indicator zone BELOW the button shows the map - that's the
   PWA bottom-bleed. The button itself is a compact rounded pill with
   a small margin so the map peeks slightly around it. */
/* End-tour icon button. Lives in .lt-nav (top bar), so the bottom of
   the screen is free for the map. 36 px circle to match the back arrow
   and the lang-toggle pill. Red border + red X glyph for unambiguous
   "exit" affordance. */
.lt-end-btn{
  width:36px;height:36px;border-radius:50%;
  background:rgba(255,80,60,0.16);
  border:1px solid rgba(255,80,60,0.55);
  color:var(--bb-red);
  display:inline-flex;align-items:center;justify-content:center;
  flex-shrink:0;
  transition:background 0.15s ease, transform 0.15s ease;
}
.lt-end-btn:hover{background:rgba(255,80,60,0.24)}
.lt-end-btn:active{background:var(--bb-red);color:#fff;transform:scale(0.94)}

/* Share button - same 36 px circle pattern as the back arrow and the
   end-tour button. Always visible in the nav so the captain can hand
   the passenger-view URL out at any time. Captain feedback 2026-05-29.
   Lives between lang-toggle and end-tour in the .lt-nav header. */
.lt-share-btn{
  width:36px;height:36px;border-radius:50%;
  background:rgba(255,255,255,0.08);
  border:1px solid rgba(255,255,255,0.18);
  color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  flex-shrink:0;cursor:pointer;
  transition:background 0.15s ease, transform 0.15s ease, color 0.18s ease;
}
.lt-share-btn:hover{background:rgba(105,254,255,0.18);color:var(--bb-cyan, #69FEFF)}
.lt-share-btn:active{transform:scale(0.94)}
/* Brief cyan flash to confirm the link was copied on desktop (where the
   navigator.share() Web Share Sheet doesn't fire). */
.lt-share-btn-copied{background:var(--bb-cyan, #69FEFF);color:var(--bb-navy, #091C35);border-color:transparent}

/* ── Passenger share sheet ──
   Modal opened by the .lt-share-btn nav button. Centered card with a
   QR code (rendered to SVG by the vendored qrcode-generator), the URL
   in monospace, plus Copy/Share buttons. Backdrop dims the live tour
   so the QR is the focus.
   Captain feedback 2026-05-29: "it should show a QR code". */
.lt-share-sheet{
  position:fixed;inset:0;z-index:1200;
  display:flex;align-items:center;justify-content:center;
  padding:24px 16px;
  animation:lt-share-fade 0.18s ease-out;
}
.lt-share-sheet[hidden]{display:none}
.lt-share-backdrop{
  position:absolute;inset:0;
  background:rgba(5,14,31,0.62);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:0;padding:0;cursor:pointer;
}
.lt-share-card{
  position:relative;
  background:#fff;
  border-radius:24px;
  padding:24px 22px 20px;
  width:min(360px, 100%);
  /* 100vh fallback for older iOS, 100dvh for the dynamic viewport so the
     share card cap matches the actual visible area when Safari's URL bar
     collapses. */
  max-height:calc(100vh - 48px);
  max-height:calc(100dvh - 48px);
  overflow-y:auto;
  box-shadow:0 24px 64px rgba(5,14,31,0.5),
             0 4px 12px rgba(5,14,31,0.3);
  display:flex;flex-direction:column;align-items:stretch;gap:14px;
  animation:lt-share-pop 0.24s cubic-bezier(0.2,0.9,0.3,1);
}
.lt-share-close{
  position:absolute;top:10px;right:10px;
  width:32px;height:32px;border-radius:50%;
  background:rgba(6,18,35,0.06);border:0;
  color:var(--bb-navy, #091C35);font-size:1.4rem;line-height:1;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  transition:background 0.15s ease, transform 0.15s ease;
}
.lt-share-close:hover{background:rgba(6,18,35,0.12)}
.lt-share-close:active{transform:scale(0.94)}
.lt-share-title{
  margin:0;font-family:var(--font);font-size:1.05rem;font-weight:600;
  color:var(--bb-navy, #091C35);padding-right:32px;
}
.lt-share-sub{
  margin:0;font-family:var(--font);font-size:0.85rem;font-weight:400;
  color:var(--bb-muted, #475569);line-height:1.4;
}
.lt-share-qr{
  background:#fff;border-radius:16px;
  padding:14px;align-self:center;
  width:min(240px, 80%);
  /* Subtle border so the QR's quiet zone reads visually as part of the
     card even when the card is on a light background. */
  border:1px solid rgba(6,18,35,0.08);
}
.lt-share-qr svg{display:block;width:100%;height:auto}
.lt-share-qr-fallback{font-family:var(--font);font-size:0.75rem;color:var(--bb-muted);word-break:break-all}
.lt-share-url{
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:0.72rem;line-height:1.4;
  color:var(--bb-muted, #475569);
  background:rgba(6,18,35,0.04);
  border-radius:10px;padding:8px 10px;
  word-break:break-all;
  user-select:all;
  max-height:64px;overflow-y:auto;
}
.lt-share-actions{display:flex;gap:8px;flex-wrap:wrap}
.lt-share-actions button{
  flex:1 1 auto;min-width:120px;
  padding:10px 14px;border-radius:999px;
  font-family:var(--font);font-size:0.85rem;font-weight:600;
  cursor:pointer;border:0;
  transition:background 0.15s ease, transform 0.12s ease;
}
.lt-share-copy{
  background:var(--bb-navy, #091C35);color:#fff;
}
.lt-share-copy:hover{background:#1a2d4a}
.lt-share-copy:active{transform:scale(0.97)}
.lt-share-copy-done{background:var(--bb-cyan, #69FEFF) !important;color:var(--bb-navy, #091C35) !important}
.lt-share-system{
  background:rgba(6,18,35,0.06);color:var(--bb-navy, #091C35);
}
.lt-share-system:hover{background:rgba(6,18,35,0.1)}
.lt-share-system:active{transform:scale(0.97)}

/* ── Inline highlight detail panel ──
   Lives in the same bottom slot as .lt-next - they swap visibility.
   Floating glass-card so the map bleeds around it. */
.lt-popup{
  /* Liquid Glass card (Pattern 1). Same recipe as .lt-next so they swap
     visually identically when the proximity loop fires. */
  margin:0 8px 8px;border-radius:var(--glass-radius);
  background:var(--glass-bg);
  backdrop-filter:var(--glass-blur);
  -webkit-backdrop-filter:var(--glass-blur);
  border:var(--glass-border);
  box-shadow:var(--glass-shadow);
  animation:lt-slide-up 0.25s cubic-bezier(0.2,0.9,0.3,1);
  overflow:hidden;
}
@keyframes lt-slide-up{from{transform:translateY(12px);opacity:0}to{transform:translateY(0);opacity:1}}
.lt-popup-card{
  position:relative;display:flex;gap:12px;padding:10px 16px 12px;align-items:stretch;
  max-height:28vh;
}
.lt-popup-img{
  flex-shrink:0;width:96px;height:96px;border-radius:8px;
  object-fit:cover;display:block;background:#dee5ee;
}
.lt-popup-img[hidden]{display:none}
.lt-popup-body{
  /* No fixed padding-right - only the sub + title need to clear the
     close/play buttons in the top-right. The detail text below can
     use the full body width. */
  flex:1;min-width:0;
  display:flex;flex-direction:column;
}
.lt-popup-sub,
.lt-popup-title{
  /* These two rows sit BESIDE the close/play buttons (top-right of the
     card) - reserve 72 px so their text wraps before reaching them. The
     detail body below has no such constraint and uses full width. */
  padding-right:72px;
}
.lt-popup-sub{
  font-size:0.625rem;font-weight:600;text-transform:uppercase;letter-spacing:0.12em;
  color:var(--bb-blue);margin-bottom:2px;
}
.lt-popup-title{
  font-size:0.95rem;font-weight:600;color:var(--bb-navy);line-height:1.25;margin-bottom:4px;
  /* Balance wrap so short tails like "#18" on "SWEETS hotel suite #18"
     don't sit alone on a second line. Captain feedback 2026-05-28. */
  text-wrap:balance;hyphens:none;word-break:normal;
}
.lt-popup-detail{
  font-size:0.78rem;color:var(--bb-text);line-height:1.45;
  flex:1;overflow-y:auto;
  /* Hide the scrollbar visually - on touch devices it's not needed (drag
     to scroll), on desktop the popup is short enough that scrolling is
     rare. Removes the "overlap" perception where the bar visually sat in
     the text column. */
  scrollbar-width:none;
}
.lt-popup-detail::-webkit-scrollbar{display:none}
.lt-popup-close{
  position:absolute;top:8px;right:8px;width:26px;height:26px;
  background:#F3F6F9;color:var(--bb-navy);
  border-radius:50%;font-size:18px;line-height:1;display:flex;align-items:center;justify-content:center;
}
.lt-popup-close:active{background:#E0E6EE}
.lt-popup-play{
  position:absolute;top:8px;right:40px;width:26px;height:26px;
  background:#F3F6F9;color:var(--bb-navy);
  border-radius:50%;font-size:11px;line-height:1;display:flex;align-items:center;justify-content:center;
}
.lt-popup-play:active{background:#E0E6EE;transform:scale(0.95)}

/* ── Highlight map markers: glass-disc + Cyan focus halo ──────────────────
   Consolidation 2026-05-31. Captain: "stop markers zijn nu goed bij routes
   maar niet bij live tour, is weer niet consistent." The live tour now
   renders its highlight markers as AdvancedMarkerElement DOM content using
   the SAME .gmaps-stop-pin class as the Routes page. tour.css (which owns
   the canonical .gmaps-stop-pin) is NOT loaded on live.html, so the spec is
   mirrored here VERBATIM from src/tour/tour.css (navy GLASS disc = radial
   cyan top-sheen + navy gradient + 5px backdrop blur, wrapped in a
   concentric cyan halo ring in box-shadow; rest = 0-width ring, hover
   expands + brightens, the SELECTED pin (.is-active) gets a gentle pulsing
   halo). Keep these two specs in lock-step if either ever changes. */
.gmaps-stop-pin{
  width:28px;height:28px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font);font-size:11px;font-weight:700;letter-spacing:-0.01em;
  color:#fff;cursor:pointer;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(105,254,255,0.18) 0%, rgba(9,28,53,0) 45%),
    linear-gradient(180deg, rgba(20,42,76,0.88), rgba(9,28,53,0.94));
  -webkit-backdrop-filter:blur(5px);
  backdrop-filter:blur(5px);
  border:1.5px solid rgba(105,254,255,0.50);
  box-shadow:
    0 1px 4px rgba(0,0,0,0.35),
    0 0 0 0 rgba(105,254,255,0),
    inset 0 1.5px 1.5px rgba(255,255,255,0.26);
  transition:transform 200ms cubic-bezier(.2,.7,.3,1.4),box-shadow 220ms ease,border-color 200ms ease;
}
.gmaps-stop-pin:hover{
  transform:scale(1.04);
  border-color:rgba(105,254,255,0.8);
  box-shadow:
    0 2px 7px rgba(0,0,0,0.38),
    0 0 0 5px rgba(105,254,255,0.22),
    inset 0 1.5px 1.5px rgba(255,255,255,0.26);
}
.gmaps-stop-pin.is-active{
  border-color:#69FEFF;
  box-shadow:
    0 2px 8px rgba(0,0,0,0.40),
    0 0 0 4px rgba(105,254,255,0.55),
    0 0 16px rgba(105,254,255,0.45),
    inset 0 1.5px 1.5px rgba(255,255,255,0.26);
  animation:gmaps-pin-pulse 1.8s ease-in-out infinite;
}
@keyframes gmaps-pin-pulse{
  0%,100%{
    box-shadow:
      0 2px 8px rgba(0,0,0,0.40),
      0 0 0 4px rgba(105,254,255,0.55),
      0 0 16px rgba(105,254,255,0.40),
      inset 0 1.5px 1.5px rgba(255,255,255,0.26);
  }
  50%{
    box-shadow:
      0 2px 8px rgba(0,0,0,0.40),
      0 0 0 7px rgba(105,254,255,0.30),
      0 0 22px rgba(105,254,255,0.55),
      inset 0 1.5px 1.5px rgba(255,255,255,0.26);
  }
}
@media (prefers-reduced-motion: reduce){
  .gmaps-stop-pin.is-active{animation:none}
}
/* 3-digit support: shrink the digit so it still fits inside the 28px disc. */
.gmaps-stop-pin[data-len="3"]{font-size:9px}

/* Live-tour-only variants of the shared pin (no equivalent on the Routes
   page, which numbers every stop). These ride on top of the base
   .gmaps-stop-pin so the glass-disc look is identical:
   - .lt-hl-context: unnumbered cross-route highlight surfaced for context.
     Smaller secondary dot, same colour family, no digit.
   - .lt-hl-announced: a stop the proximity loop has already fired - dims
     the disc to grey so the captain sees at a glance it's been passed,
     while keeping the cyan ring + (if numbered) the digit. */
.gmaps-stop-pin.lt-hl-context{
  width:16px;height:16px;
  border-width:1.25px;
  border-color:rgba(105,254,255,0.45);
}
.gmaps-stop-pin.lt-hl-announced{
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(105,254,255,0.10) 0%, rgba(9,28,53,0) 45%),
    linear-gradient(180deg, rgba(120,128,138,0.80), rgba(96,104,114,0.88));
  border-color:rgba(105,254,255,0.30);
  color:rgba(255,255,255,0.78);
}

/* ── Sailing settings (Lookahead / Show vessels / Include 't IJ / AIS
   update / Debug overlay + the sim Play/Speed rows). Consolidation
   2026-05-31: these used to live in a standalone floating .lt-sim-panel.
   buildSimPanel() now injects them into #ltSettingsMount inside the single
   control panel (#ltLogoPanel), so the floating-card chrome + the
   collapse-header were dropped; only the inner control styles below remain.
   The mount carries .lt-sim-live (when NOT in sim mode) so the sim-only
   rows hide themselves. ── */
.lt-sim-section-label{
  font-size:0.62rem;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;
  color:rgba(105,254,255,0.88);margin:12px 0 5px;
}
.lt-sim-live [data-sim-only]{display:none}
/* Checkbox rows are iOS-style switch rows now (shared .glass-switch from
   styles/shared-prototype.css - the exact rows vaarinfo/vaarverkeer use).
   live-tour.css loads AFTER the shared sheet, so .lt-sim-row's 6px gap +
   8px margin would stomp the switch-row rhythm - restore it here. The
   .lt-sim-row class STAYS on these labels because live-tour.js show/hides
   the closures row via stremToggle.closest('.lt-sim-row'). */
.lt-logo-panel .lt-sim-row.glass-switch{gap:10px;margin-top:0;padding:6px 2px}
/* .lt-sim-preset-seg / .lt-sim-look-preset hoorden bij de vooruitkijken-slider
   met zijn 200/300/500-presets; die is met P3 (2026-07-26) vervallen - de
   afstand staat vast op 300 m, dus zowel de balk als zijn opmaak zijn weg. */
.lt-sim-select,.lt-sim-range{
  width:100%;font-family:var(--font);font-size:0.75rem;
  background:rgba(255,255,255,0.08);color:#fff;border:1px solid rgba(255,255,255,0.18);
  border-radius:6px;padding:4px 6px;
}
.lt-sim-select option{background:#091C35;color:#fff}
.lt-sim-row{display:flex;gap:6px;margin-top:8px;align-items:center}
.lt-sim-btn{
  flex:1;padding:6px 8px;font-size:0.7rem;font-weight:600;
  background:var(--bb-blue);color:#fff;border-radius:6px;letter-spacing:0.02em;
}
.lt-sim-btn:active{background:#2855e0}
.lt-sim-label{
  display:flex;justify-content:space-between;width:100%;
  font-size:0.7rem;color:rgba(255,255,255,0.7);margin-bottom:4px;
}
.lt-sim-label span{color:var(--bb-cyan);font-weight:600}
.lt-sim-progress{
  margin-top:6px;font-size:0.7rem;color:rgba(255,255,255,0.7);
  font-variant-numeric:tabular-nums;
}

/* ── Pickup-nav card: floating ETA + share-location button ──
   Shown after the captain long-presses the map. Stacks above the approach
   card so a pickup-in-progress is always visible. */
.lt-pickup-card{
  position:fixed;
  bottom:calc(280px + var(--safe-bottom));
  left:12px;
  z-index:1500;
  width:240px;
  background:#fff;
  border:2px solid var(--bb-blue);
  border-radius:10px;
  box-shadow:0 4px 14px rgba(51,102,255,0.35);
  padding:10px 12px;
  font-family:var(--font);
}
.lt-pickup-row{
  display:flex;align-items:center;justify-content:space-between;
  font-size:0.8rem;color:var(--bb-navy);
  margin-bottom:6px;
}
.lt-pickup-row strong{font-weight:600}
.lt-pickup-close{
  background:none;border:none;cursor:pointer;
  font-size:1.2rem;line-height:1;color:var(--bb-muted);
  padding:0 4px;
}
.lt-pickup-close:active{color:var(--bb-navy)}
.lt-pickup-eta{
  font-size:0.95rem;color:var(--bb-navy);
  margin-bottom:8px;
}
.lt-pickup-eta b{font-weight:700;color:var(--bb-blue)}
/* De omweg-regel onder de resterende afstand: "300 m om vanwege eenrichting
   Prinsengracht". Zachter dan de afstand zelf, want het is de uitleg. */
.lt-pickup-sub{
  font-size:0.8rem;color:var(--bb-muted);
  margin:-4px 0 8px;line-height:1.35;
}
.lt-pickup-err{
  font-size:0.85rem;color:#8A1C0F;
}
.lt-pickup-share{
  width:100%;padding:9px 12px;
  font-family:var(--font);font-size:0.85rem;font-weight:600;
  color:#fff;background:var(--bb-blue);border:none;border-radius:8px;
  cursor:pointer;
}
.lt-pickup-share:active{background:#2855e0}

/* ── Approach pill: compact one-line glass chip for the closest red (in-lookout)
   vessel (captain "optie B" 2026-05-30 - replaces the old big photo card).
   Slides in when one or more vessels enter the user's lookout corridor.
   Dark navy glass like the other live-tour overlays, with a red/orange accent
   dot (the vessel-alert hue) and a soft pulsing glow.
   TOP-aligned since 2026-07-11 (captain): the pill lived in the lower third
   and collided with the detail sheet / mini-player stack. Sinds P3
   (2026-07-26) staat hij NAAST de terug-chip in de knoppenband (rapport 5a:
   left 64, top base + 5); positionApproachCard() meet de chip - of de
   GPS-toast als die aanstaat - op elke tick, dit is de first-paint-waarde. */
.lt-approach-card{
  position:fixed;
  top:calc(var(--lt-top-base, 12px) + 5px);
  left:64px;
  z-index:1400;
  display:inline-flex;align-items:center;gap:7px;
  max-width:70vw;
  padding:7px 13px;
  background:var(--glass-bg-dark);color:#fff;
  backdrop-filter:var(--glass-blur);
  -webkit-backdrop-filter:var(--glass-blur);
  border:1px solid rgba(255,80,60,0.45);
  border-radius:999px;
  box-shadow:0 6px 20px rgba(0,0,0,0.4),
             inset 0 1px 0 rgba(255,255,255,0.08),
             0 0 12px rgba(255,80,60,0.35);
  font-size:0.82rem;line-height:1.1;white-space:nowrap;
  animation:lt-approach-pulse 1.4s ease-in-out infinite, lt-approach-slidein 0.25s ease-out;
}
@keyframes lt-approach-pulse{
  0%,100%{box-shadow:0 6px 20px rgba(0,0,0,0.4),inset 0 1px 0 rgba(255,255,255,0.08),0 0 10px rgba(255,80,60,0.28)}
  50%{box-shadow:0 6px 22px rgba(0,0,0,0.4),inset 0 1px 0 rgba(255,255,255,0.08),0 0 18px rgba(255,80,60,0.6)}
}
@keyframes lt-approach-slidein{
  from{transform:translateY(-14px);opacity:0}
  to{transform:translateY(0);opacity:1}
}
.lt-approach-dot{
  flex:0 0 auto;width:9px;height:9px;border-radius:50%;
  background:var(--bb-red);box-shadow:0 0 6px rgba(255,96,71,0.9);
}
/* Paars bolletje wanneer de curated tabel een foto van de boot heeft
   (captain 2026-07-11); rood (default hierboven) = geen foto. */
.lt-approach-dot--photo{
  background:#5E35B1;box-shadow:0 0 6px rgba(94,53,177,0.95);
}
.lt-approach-name{
  font-weight:700;letter-spacing:0.02em;
  overflow:hidden;text-overflow:ellipsis;min-width:0;
}
.lt-approach-sep{opacity:0.5;flex:0 0 auto}
.lt-approach-dist{
  flex:0 0 auto;font-weight:600;color:rgba(255,255,255,0.85);
  font-variant-numeric:tabular-nums;
}
.lt-approach-eta{
  flex:0 0 auto;font-weight:600;color:var(--bb-cyan);
  font-variant-numeric:tabular-nums;
}
.lt-approach-eta[hidden]{display:none}

/* ── Boat-detection debug overlay (sim only) ───────────────────────── */
.lt-debug-panel{
  position:fixed;top:90px;left:16px;width:340px;max-width:calc(100vw - 32px);
  max-height:70vh;overflow:auto;
  background:rgba(9,28,53,0.96);color:#fff;border-radius:10px;
  box-shadow:0 4px 18px rgba(0,0,0,0.35);
  font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;
  z-index:9999;
  padding:0 0 8px;
}
.lt-debug-head{
  display:flex;justify-content:space-between;align-items:center;
  padding:8px 12px;background:rgba(255,255,255,0.08);
  border-radius:10px 10px 0 0;font-weight:700;font-size:11px;
  letter-spacing:0.06em;text-transform:uppercase;
}
.lt-debug-close{
  background:none;border:0;color:#fff;font-size:18px;line-height:1;
  cursor:pointer;padding:0 4px;opacity:0.7;
}
.lt-debug-close:hover{opacity:1}
.lt-debug-body{padding:10px 12px}
.lt-debug-line{margin-bottom:4px;color:rgba(255,255,255,0.85);font-size:11px}
.lt-debug-line b{color:#69FEFF;font-weight:600;margin-right:4px}
.lt-debug-table{width:100%;border-collapse:collapse;margin-top:6px;font-size:10.5px}
.lt-debug-table th{
  text-align:left;padding:4px 6px;color:rgba(255,255,255,0.55);
  font-weight:500;text-transform:uppercase;letter-spacing:0.04em;
  border-bottom:1px solid rgba(255,255,255,0.15);
}
.lt-debug-table td{
  padding:4px 6px;border-bottom:1px solid rgba(255,255,255,0.06);
  font-variant-numeric:tabular-nums;
}
/* Narrow screens: stack the debug panel BELOW the sim panel so they don't
   collide. Sim panel stays in the corner; debug pulls to full width. */
@media (max-width: 720px) {
  .lt-debug-panel{
    top:auto;bottom:120px;left:8px;right:8px;width:auto;
    max-height:50vh;
  }
  /* Map gets more vertical room on mobile by shrinking everything below.
     min-height 40vh leaves ~60% of viewport for bottom block (status row +
     LOCATION OFF info card + End-tour button + safe-area), which is the
     worst case when GPS is denied. Previously 60vh squeezed the bottom
     block off-screen on iPhone PWA - End-tour button was clipped by the
     home indicator. */
  .lt-map{ min-height:40vh }

  /* Basis-maat voor knoppen BUITEN de stack; de stack-knoppen krijgen hun
     40px-recept in pages/live.html (P3 2026-07-26). De marge-helpers van de
     oude balk zijn vervallen met de balk zelf. */
  .lt-mini-btn{padding:5px 7px;font-size:0.95rem;flex-shrink:0}
}

/* AIS vessel-label pill rules live in /styles/shared-overlays.css so the
   live tour and standard tour can't drift. Loaded BEFORE this stylesheet
   from pages/live.html. Fade-in hook (.lt-ais-label--just-added) stays in
   live-polish.css since that's where the rAF tween + transition pair up. */

/* App-views sheet (in-shell overview / boat-info / quiz) - shares the
   shape with the trips + share sheets. The sheet is full-screen so the
   embedded page content has room to breathe. */
.app-sheet{
  position:fixed;inset:0;z-index:5500;
  display:flex;align-items:stretch;justify-content:center;
}
.app-sheet-backdrop{
  position:absolute;inset:0;
  background:rgba(9,28,53,0.65);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:lt-share-fade 0.18s ease-out;
}
.app-sheet-card{
  position:relative;z-index:1;
  width:100%;max-width:760px;height:100%;
  background:#fff;display:flex;flex-direction:column;
  box-shadow:0 6px 30px rgba(9,28,53,0.4);
}
.app-sheet-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:14px 18px;border-bottom:1px solid var(--bb-border);
  background:#091C35;color:#fff;flex-shrink:0;
  padding-top:calc(14px + var(--safe-top, 0px));
}
.app-sheet-title{font-family:var(--font);font-size:1rem;font-weight:600;margin:0}
.app-sheet-close{background:none;border:none;cursor:pointer;font-size:1.6rem;
  color:#fff;padding:0 6px;line-height:1}
.app-sheet-body{flex:1;overflow-y:auto;background:#fff;
  padding-bottom:calc(20px + var(--safe-bottom, 0px))}
.app-sheet-loading{padding:24px;color:var(--bb-muted);text-align:center}

/* Past-trips sheet. */
.lt-trips-sheet{
  position:fixed;inset:0;z-index:5000;
  display:flex;align-items:flex-end;justify-content:center;
  padding:16px;
}
.lt-trips-backdrop{
  position:absolute;inset:0;
  background:rgba(9,28,53,0.55);
  backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  animation:lt-share-fade 0.18s ease-out;
}
.lt-trips-card{
  position:relative;z-index:1;
  background:#fff;width:100%;max-width:480px;
  border-radius:14px;padding:18px 20px 20px;
  box-shadow:0 6px 30px rgba(9,28,53,0.4);
  max-height:80vh;overflow-y:auto;
  animation:lt-share-pop 0.22s cubic-bezier(0.2,0.9,0.3,1);
}
.lt-trips-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.lt-trips-title{font-family:var(--font);font-size:1rem;font-weight:600;color:var(--bb-navy);margin:0}
.lt-trips-close{background:none;border:none;cursor:pointer;font-size:1.5rem;
  color:var(--bb-muted);padding:0 6px;line-height:1}
.lt-trips-empty{color:var(--bb-muted);font-size:0.9rem;text-align:center;padding:24px 0}
.lt-trips-list{list-style:none;margin:0;padding:0}
.lt-trips-item{padding:10px 0;border-bottom:1px solid var(--bb-border)}
.lt-trips-item:last-child{border-bottom:none}
.lt-trips-item-head{display:flex;justify-content:space-between;align-items:baseline;
  font-size:0.85rem;color:var(--bb-navy)}
.lt-trips-item-head strong{font-weight:600}
.lt-trips-meta{font-size:0.8rem;color:var(--bb-muted)}
.lt-trips-item-meta{font-size:0.7rem;color:var(--bb-muted);margin-top:2px}
.lt-trips-item-actions{display:flex;gap:6px;margin-top:6px}
.lt-trips-btn{padding:6px 10px;font-family:var(--font);font-size:0.75rem;font-weight:500;
  background:var(--bb-offwhite);border:1px solid var(--bb-border);border-radius:6px;
  color:var(--bb-navy);cursor:pointer}
.lt-trips-btn:active{background:#D6E0FF}
.lt-trips-btn-danger{color:#8A1C0F}
.lt-trips-btn-secondary{margin-top:10px;width:100%;text-align:center}

/* Shared modal animations: consumed by .app-sheet-backdrop and the
   .lt-trips-* sheet. Named lt-share-* for legacy reasons (the passenger
   share sheet originally introduced them; that feature was archived but
   the keyframes remained the shared primitive). */
@keyframes lt-share-fade{from{opacity:0}to{opacity:1}}
@keyframes lt-share-pop{
  from{transform:translateY(18px);opacity:0}
  to{transform:translateY(0);opacity:1}
}

/* Source icon row at the bottom of the InfoWindow popup. Same visual
   language as src/tour/tour.css .pp-links - 32px circles in BB Light Blue
   tint, hover into BB Blue. Renders Wikipedia + Ommetje met Tom +
   Aan de Grachten + Stadsarchief icons, one per populated source field. */
.pp-links{display:flex;flex-wrap:wrap;gap:8px}
.pp-icon-link{
  display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;border-radius:50%;
  background:#E5EBFF;color:#091C35;
  text-decoration:none;transition:background 0.15s ease,color 0.15s ease;
}
.pp-icon-link:hover,.pp-icon-link:focus-visible{background:#3366FF;color:#fff;outline:none}
.pp-icon-link svg{width:16px;height:16px;display:block}

/* ── D2 V1: live-tour route-highlight InfoWindow content in DARK theme ─────
   2026-06-08: in dark theme the InfoWindow chrome flips to Deep Navy Glass
   (styles/shared-overlays.css). The live highlight popup is built by
   live-tour.js as a .gmaps-popup whose title / sub / detail carry INLINE
   colors (#091C35 / #3366FF / #4B5563) straight in the HTML, so this CSS uses
   !important to recolour them LIGHT / CYAN for legibility on the navy glass
   (a CSS-only override - the JS builder is out of this lane). The strem +
   opstap bubbles use the .gmaps-popup--strem / --opstap modifiers and stay
   LIGHT in every theme, so they are excluded via :not(); their content is
   styled by their own injected stylesheet, not this bare .gmaps-popup. The
   direct-child `> strong` / `> div` target the inline-styled anonymous title /
   sub / detail rows the live builder emits. */
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap){
  color:rgba(243,246,249,0.70)!important;
}
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap) > strong{
  color:rgba(243,246,249,0.96)!important;
}
/* The sub row is the only direct child <div> the builder tints brand-blue;
   the detail <div> is tinted grey (#4B5563). Recolour the sub cyan and the
   detail light-muted. Both are inline-styled anonymous divs - match on the
   inline color so we recolour the right one without a class hook. */
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap) > div[style*="3366FF"]{
  color:var(--bb-cyan,#69FEFF)!important;
}
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap) > div[style*="4B5563"]{
  color:rgba(243,246,249,0.70)!important;
}
/* Source-icon discs -> navy-glass chip + cyan glyph (mirrors .pp-icon). */
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap) .pp-icon-link{
  background:rgba(255,255,255,0.06);
  border:1px solid rgba(255,255,255,0.12);
  color:rgba(243,246,249,0.78);
}
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap) .pp-icon-link:hover,
:root[data-theme="dark"] .gmaps-popup:not(.gmaps-popup--strem):not(.gmaps-popup--opstap) .pp-icon-link:focus-visible{
  background:rgba(105,254,255,0.16);
  color:var(--bb-cyan,#69FEFF);
}


/* ════════════════════════════════════════════════════════════════════
   Pattern 4 - iOS segmented control
   UI audit 2026-05-28. Replaces the three radio rows inside the SIM
   panel (Show vessels / AIS update). The visual indicator slides
   between options via JS-driven left+width; the underlying inputs use
   the original `data-value` so the existing change handlers in
   live-tour.js around lines 2611+2625 still fire on the same values.

   Dark variant: lives inside .lt-sim-panel (dark glass) so the track
   bg is light + the indicator is a thin white pill.
   ════════════════════════════════════════════════════════════════════ */
/* 2026-06-09 (task 165): values aligned to the D5 P2 segmented-tab spec die
   vaarinfo en vaarverkeer destijds gebruikten (hun tabs zijn 2026-07-26
   vervallen; deze .lt-segmented leeft nog): faint off-white
   track tint + hairline border + 11px radius, 11px/600 options on the muted
   dark-glass ink, and a cyan-tint sliding indicator that matches the
   selected-tab fill (rgba(105,254,255,0.16)). The slide animation stays. */
.lt-segmented{
  position:relative;
  display:inline-flex;align-self:stretch;width:100%;
  background:rgba(243,246,249,0.10);
  border:1px solid var(--bb-glass-dark-hairline, rgba(255,255,255,0.12));
  border-radius:11px;padding:3px;
  font-size:0.72rem;
  margin:2px 0 0;
}
.lt-segmented-track{
  position:absolute;top:3px;bottom:3px;
  background:rgba(105,254,255,0.16);border-radius:8px;
  box-shadow:0 1px 4px rgba(9,28,53,0.3);
  transition:left var(--t-base) var(--spring),
             width var(--t-base) var(--spring);
  z-index:0;left:0;width:0;
}
.lt-segmented-option{
  position:relative;z-index:1;
  flex:1 1 0;padding:6px 2px;
  text-align:center;font-weight:600;
  color:var(--bb-glass-dark-ink-muted, rgba(243,246,249,0.66));
  cursor:pointer;user-select:none;
  transition:color var(--t-fast) var(--spring-fast);
  white-space:nowrap;font-size:11px;line-height:1.1;
  border-radius:8px;
  -webkit-user-select:none;
}
.lt-segmented-option.is-on{color:#fff;font-weight:600}

/* ════════════════════════════════════════════════════════════════════
   Pattern 5 - Skeleton shimmer loaders
   UI audit 2026-05-28. Reusable shimmer primitives. The keyframe is
   prefixed `lt-skel-shimmer` to avoid clashing with the info-weetjes
   `iw-shimmer` defined separately. The shimmer applies via gradient
   background-position animation; works in iOS Safari 16+ unprefixed.
   ════════════════════════════════════════════════════════════════════ */
.lt-skel-card{
  display:flex;background:#fff;border:1px solid var(--bb-border);
  border-radius:14px;overflow:hidden;margin-bottom:10px;
  box-shadow:0 1px 3px rgba(6,18,35,0.06);
}
.lt-skel-img{
  flex-shrink:0;width:120px;aspect-ratio:1;
  background:linear-gradient(90deg, #EEF1F4 0%, #F8F9FB 50%, #EEF1F4 100%);
  background-size:200% 100%;
  animation:lt-skel-shimmer 1.4s linear infinite;
}
.lt-skel-body{
  flex:1;padding:12px 14px;display:flex;flex-direction:column;gap:8px;
}
.lt-skel-line{
  height:10px;border-radius:5px;
  background:linear-gradient(90deg, #EEF1F4 0%, #F8F9FB 50%, #EEF1F4 100%);
  background-size:200% 100%;
  animation:lt-skel-shimmer 1.4s linear infinite;
}
.lt-skel-line:nth-child(1){width:35%;height:8px}
.lt-skel-line:nth-child(2){width:85%}
.lt-skel-line:nth-child(3){width:60%}
@keyframes lt-skel-shimmer{
  from{background-position:200% 0}
  to{background-position:-200% 0}
}
.lt-skel-fade-out{
  opacity:0;transition:opacity var(--t-base) var(--spring);
}

/* ════════════════════════════════════════════════════════════════════
   Liquid Glass fallback (Pattern 1 + Pattern 2)
   Browsers without backdrop-filter (very rare in 2026 - IE11, old
   Android WebView) get near-solid backgrounds so legibility is
   preserved. iOS Safari 9+, Chrome 76+, Firefox 103+ all support
   backdrop-filter; this block is genuinely a fallback, not a hot path.
   ════════════════════════════════════════════════════════════════════ */
@supports not (backdrop-filter: blur(1px)){
  .lt-next,.lt-popup,
  .lt-recenter,.lt-compass{
    background:rgba(255,255,255,0.96);
  }
  .lt-logo-panel{background:rgba(9,28,53,0.96)}
}

/* Reduced-motion respect for the new spring transitions added in this
   batch. CSS-level honour - matches CLAUDE.md spirit (and the
   prefers-reduced-motion override already used in live-polish.css). */
@media (prefers-reduced-motion:reduce){
  .lt-cta,
  .lt-segmented-track,.lt-segmented-option{
    transition-duration:0.01ms !important;
  }
  .lt-skel-img,.lt-skel-line{animation-duration:3s !important}
}

/* ── V5 sticky bottom start-bar (captain-approved 2026-06-09) ──────────────
   Reference: pages/proto/bk-livestart-5.html (.lt-startbar markup + skin).
   A quiet sticky bar that stays hidden (translated off-screen, no pointer
   events) until a route card is selected on the splash, then slides up. It
   carries the primary blue "Start GPS tour" button + a small amber ghost pill
   "or simulate from home" beneath it. Built once in init() (live-tour.js) and
   mounted inside #ltSplash; revealed via body.lt-startbar-on, hidden again in
   endTour(). Scoped to body.lt-proto (the live page) so it never leaks into
   the shared overlay stylesheet used by other pages.

   Variable fallbacks: --bb-nav-h-mobile / --bb-safe-bottom / --bb-spring /
   --bb-font are defined in pages/live.html's inline :root; the fallbacks below
   keep the bar correct even if a page loads this stylesheet without them. */
body.lt-proto .lt-startbar{
  position:fixed; left:12px; right:12px;
  bottom:calc(var(--bb-safe-bottom, env(safe-area-inset-bottom, 0px)) + var(--bb-nav-h-mobile, 60px) + 24px);
  z-index:78;
  display:flex; flex-direction:column; align-items:stretch; gap:6px;
  max-width:480px; margin:0 auto;
  padding:12px 14px 12px;
  background:rgba(9,28,53,0.92);
  -webkit-backdrop-filter:blur(20px) saturate(180%);
  backdrop-filter:blur(20px) saturate(180%);
  border:1px solid rgba(255,255,255,0.10);
  border-radius:18px;
  box-shadow:0 -8px 32px rgba(9,28,53,0.30);
  transform:translateY(140%); opacity:0;
  transition:transform 320ms var(--bb-spring, cubic-bezier(.2,.7,.3,1.4)), opacity 220ms ease;
  pointer-events:none;
}
/* Reveal only while the splash is visible (the bar lives on <body>, so this
   :has gate auto-hides it the instant the tour starts and #ltSplash hides). */
body.lt-proto.lt-startbar-on:has(#ltSplash:not([hidden])) .lt-startbar{
  transform:translateY(0); opacity:1; pointer-events:auto;
}
body.lt-proto .lt-startbar-primary{
  appearance:none; -webkit-appearance:none; cursor:pointer; border:0;
  font-family:var(--bb-font, var(--font)); font-size:0.98rem; font-weight:600; letter-spacing:0.01em;
  color:#fff; background:var(--bb-blue);
  padding:13px 18px; border-radius:12px; line-height:1;
  box-shadow:0 4px 14px rgba(51,102,255,0.42);
  display:flex; align-items:center; justify-content:center; gap:8px;
  transition:filter 160ms ease, transform 160ms ease;
}
body.lt-proto .lt-startbar-primary:hover{ filter:brightness(1.06); }
body.lt-proto .lt-startbar-primary:active{ transform:scale(0.98); }
body.lt-proto .lt-startbar-primary svg{ width:16px; height:16px; stroke:#fff; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
body.lt-proto .lt-startbar-sim{
  appearance:none; -webkit-appearance:none; cursor:pointer; align-self:center;
  display:inline-flex; align-items:center; gap:7px; line-height:1;
  border:1px solid rgba(245,178,90,0.42); border-radius:999px;
  background:rgba(245,178,90,0.12);
  font-family:var(--bb-font, var(--font)); font-size:0.82rem; font-weight:600;
  color:#FFD7A0; text-decoration:none; padding:8px 14px;
  transition:background 160ms ease, border-color 160ms ease, transform 120ms ease;
}
body.lt-proto .lt-startbar-sim[hidden]{ display:none; }
body.lt-proto .lt-startbar-sim svg{ width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; }
body.lt-proto .lt-startbar-sim svg .play{ fill:currentColor; stroke:none; }
body.lt-proto .lt-startbar-sim:hover{ background:rgba(245,178,90,0.20); border-color:rgba(245,178,90,0.62); }
body.lt-proto .lt-startbar-sim:active{ transform:scale(0.97); }
/* Light mode: soft tint glass (Backbase light-blue) with navy ink, amber pill
   re-tinted to the readable warm token (#8A4B12 on a light amber tint). */
[data-theme="light"] body.lt-proto .lt-startbar{
  background:rgba(229,235,255,0.92);
  border-color:rgba(51,102,255,0.20);
  box-shadow:0 -8px 32px rgba(9,28,53,0.14);
}
[data-theme="light"] body.lt-proto .lt-startbar-sim{ color:#8A4B12; background:rgba(180,83,9,0.09); border-color:rgba(180,83,9,0.32); }
[data-theme="light"] body.lt-proto .lt-startbar-sim:hover{ color:#8A4B12; background:rgba(180,83,9,0.15); border-color:rgba(180,83,9,0.5); }
@media (min-width:960px){
  body.lt-proto .lt-startbar{ left:auto; right:24px; bottom:24px; width:420px; margin:0; }
}
/* Reduced-motion: drop the slide spring (visibility still toggles instantly). */
@media (prefers-reduced-motion:reduce){
  body.lt-proto .lt-startbar{ transition-duration:0.01ms !important; }
}

