/* bb-sheet.css - the ONE sheet skin (variant A)
 *
 * Single source of truth for every bb-sheet surface. No page may declare its
 * own sheet CSS: all sizes, colours, radii, blur, typography and the grab
 * handle come from the tokens below. Per marker type only a .bbs--<type> skin
 * class may vary the thumb gradient + accent; nothing structural.
 *
 * Everything is namespaced .bbs* so it can never cascade into a page's generic
 * .hero / .card / .chip (CSS Cascade Scoping Rule). Theme via [data-theme];
 * the sheet is its own DOM so no :not(:has()) dark-guards are needed. Safe-area
 * is respected on notch devices.
 */

:root {
  --bbs-radius: 24px;
  /* "rd-glass look" (captain 2026-07-12): the translucent Liquid-Glass recipe
     from the routes rd-glass panel, adopted for every sheet - navy 0.66 with a
     heavier blur+saturate so the map reads softly through the glass. */
  --bbs-bg: rgba(9, 28, 53, 0.66);
  --bbs-fg: #ffffff;
  --bbs-fg-dim: rgba(255, 255, 255, 0.72);
  --bbs-fg-body: rgba(255, 255, 255, 0.86);
  --bbs-border: rgba(255, 255, 255, 0.12);
  --bbs-hairline: rgba(255, 255, 255, 0.12);
  --bbs-grab: rgba(255, 255, 255, 0.34);
  --bbs-shadow: 0 18px 48px rgba(0, 0, 0, 0.46), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  --bbs-blur: blur(22px) saturate(180%);

  --bbs-accent: #69FEFF;                    /* cyan info accent */
  --bbs-chip-bg: rgba(255, 255, 255, 0.10);
  --bbs-chip-fg: var(--bbs-fg);
  --bbs-chip-cyan-bg: rgba(105, 254, 255, 0.14);
  --bbs-chip-cyan-fg: #69FEFF;
  --bbs-chip-warn-bg: #FFF4D6;
  --bbs-chip-warn-fg: #5C3A00;

  --bbs-ctrl-bg: rgba(255, 255, 255, 0.10);
  --bbs-ctrl-border: rgba(255, 255, 255, 0.16);

  --bbs-ease: cubic-bezier(.25, .8, .3, 1);
  --bbs-dur: 380ms;

  --bbs-dock-w: 420px;
  /* Docked-panel top offset so the panel head clears the fixed top nav. Every
     map page has the ~64px .bb-header (and the app-shell overlays its own nav on
     the embedded page), so default to clearing it; pages can override. */
  --bbs-dock-top: calc(env(safe-area-inset-top, 0px) + 90px);
  --bbs-safe-bottom: env(safe-area-inset-bottom, 0px);
  /* Sticky-header fill (filter chips): a near-opaque match of the sheet's
     COMPOSITED interior tone (a medium slate, not another navy tint - stacking
     navy over the glass just darkens it), so pinned chips read as one surface and
     the list rows scrolling under are fully hidden. */
  --bbs-sticky: rgb(44, 69, 96);

  --bbs-font: 'Libre Franklin', -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
}

/* Light theme: a genuine LIGHT liquid-glass (captain 2026-07-12: "de bar is niet
 * light mode / de tekst is niet leesbaar"). Frosted off-white, opaque ENOUGH that
 * the bright map can't wash out the text (dark-glass-in-light left white body text
 * at ~3:1 contrast over the light map - unreadable). Navy text throughout, blue
 * accent. Keeps the liquid-glass feel via the blur + a hint of translucency. */
:root[data-theme="light"] {
  --bbs-bg: rgba(240, 244, 250, 0.90);
  --bbs-sticky: rgb(228, 235, 244);
  --bbs-fg: #091C35;
  --bbs-fg-dim: rgba(9, 28, 53, 0.62);
  --bbs-fg-body: rgba(9, 28, 53, 0.90);
  --bbs-border: rgba(9, 28, 53, 0.10);
  --bbs-hairline: rgba(9, 28, 53, 0.10);
  --bbs-grab: rgba(9, 28, 53, 0.26);
  --bbs-shadow: 0 18px 48px rgba(9, 28, 53, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  --bbs-accent: #3366FF;
  --bbs-chip-bg: rgba(9, 28, 53, 0.06);
  --bbs-chip-fg: #091C35;
  --bbs-chip-cyan-bg: rgba(51, 102, 255, 0.12);
  --bbs-chip-cyan-fg: #3366FF;
  --bbs-ctrl-bg: rgba(9, 28, 53, 0.06);
  --bbs-ctrl-border: rgba(9, 28, 53, 0.12);
}
:root[data-theme="light"] .bbs-bar { background: rgba(9, 28, 53, 0.12); }
:root[data-theme="light"] .bbs-pbtn--stop { background: rgba(9, 28, 53, 0.08); }

/* ── Shell ────────────────────────────────────────────────────────────────── */
.bbs {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 96;
  display: flex;
  flex-direction: column;
  height: 30vh;
  box-sizing: border-box;
  border-radius: var(--bbs-radius) var(--bbs-radius) 0 0;
  background: var(--bbs-bg);
  -webkit-backdrop-filter: var(--bbs-blur);
  backdrop-filter: var(--bbs-blur);
  border: 1px solid var(--bbs-border);
  border-bottom: none;
  box-shadow: var(--bbs-shadow);
  color: var(--bbs-fg);
  font-family: var(--bbs-font);
  overflow: hidden;
  transform: translateY(110%);
  visibility: hidden;
  transition: transform var(--bbs-dur) var(--bbs-ease),
              height 300ms var(--bbs-ease),
              visibility 0s linear var(--bbs-dur);
  /* Safe-area padding so the body never tucks under the home indicator. */
  padding-bottom: var(--bbs-safe-bottom);
}
.bbs[hidden] { display: none; }
.bbs.bbs--open {
  transform: translateY(0);
  visibility: visible;
  transition: transform var(--bbs-dur) var(--bbs-ease),
              height 300ms var(--bbs-ease);
}
.bbs.bbs--dragging,
.bbs.bbs--noanim { transition: none; }

/* Grab handle */
.bbs-grab {
  flex: 0 0 auto;
  height: 22px;
  display: flex; align-items: center; justify-content: center;
  cursor: grab;
  touch-action: none;
}
.bbs-grab::before {
  content: "";
  width: 44px; height: 5px;
  border-radius: 999px;
  background: var(--bbs-grab);
}
.bbs.bbs--dragging .bbs-grab { cursor: grabbing; }

/* ── Head ─────────────────────────────────────────────────────────────────── */
.bbs-head {
  flex: 0 0 auto;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 6px 16px 12px;
  cursor: grab;
  touch-action: none;
}
.bbs.bbs--dragging .bbs-head { cursor: grabbing; }
/* Visueel 30px (de navy-glas-badge-familie), maar het TIKDOEL wordt hieronder
   opgerekt naar 44px via een transparante ::after - hetzelfde recept als de
   back/route-chips in shared-prototype.css. Audit 2026-07-28 mat hier 28x28
   effectief met elementFromPoint, ruim onder de 44pt uit Apple's HIG, op de
   twee drukst gebruikte knoppen van de app (elke bottom-sheet heeft ze). */
.bbs-back, .bbs-close {
  flex: 0 0 auto;
  position: relative;
  width: 30px; height: 30px;
  border-radius: 999px;
  background: var(--bbs-ctrl-bg);
  border: 1px solid var(--bbs-ctrl-border);
  color: var(--bbs-fg);
  font-size: 15px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
}
/* Het tikdoel-verlengstuk: onzichtbaar, gecentreerd, rekt 30px op naar 44px.
   Geen achtergrond en geen eigen z-index, dus puur hitbox - het uiterlijk van
   de knop verandert niet. pointer-events:none op de ::after zou de hele truc
   opheffen, dus die staat er bewust NIET. */
.bbs-back::after, .bbs-close::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 44px; height: 44px;
  transform: translate(-50%, -50%);
}
.bbs-back { margin-top: 2px; }
.bbs-close { margin-left: auto; color: var(--bbs-fg-dim); }
.bbs-back:active, .bbs-close:active { transform: scale(0.94); }
/* Subtle stack-depth affordance: a faint layered edge behind the back button +
   a small muted count, shown only 2+ layers deep (captain 2026-07-13). */
.bbs-back--stacked { position: relative; box-shadow: -3px 3px 0 -1px var(--bbs-ctrl-border), -6px 6px 0 -2px var(--bbs-ctrl-border); }
.bbs-back-depth {
  position: absolute; top: -4px; right: -4px;
  min-width: 15px; height: 15px; padding: 0 3px; box-sizing: border-box;
  border-radius: 8px; background: var(--bbs-chip-bg); color: var(--bbs-fg-dim);
  font: 700 9.5px/15px var(--bbs-font); text-align: center;
  box-shadow: 0 0 0 2px var(--bbs-bg);
}
/* Peek mini-player thumbnail + audio progress-ring (captain-approved 4.1). Only
   shows on peek; once the sheet expands the body photo takes over. */
.bbs-pthumb { position: relative; width: 48px; height: 48px; flex: 0 0 auto; margin-top: 2px; }
.bbs-pthumb-img { position: absolute; inset: 5px; width: 38px; height: 38px; border-radius: 50%; object-fit: cover; }
.bbs-pthumb-ring { position: absolute; inset: 0; width: 48px; height: 48px; transform: rotate(-90deg); overflow: visible; }
.bbs-pthumb-track { fill: none; stroke: var(--bbs-hairline); stroke-width: 3; }
.bbs-pthumb-prog { fill: none; stroke: var(--bbs-accent, #3366FF); stroke-width: 3; stroke-linecap: round; transition: stroke-dashoffset 0.25s linear; }
.bbs:not(.bbs--peek) .bbs-pthumb { display: none; }

.bbs-thumb {
  flex: 0 0 auto;
  width: 58px; height: 58px;
  border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; line-height: 1;
  background: linear-gradient(135deg, #274B8F, #3366FF);
  border: 1px solid var(--bbs-hairline);
  color: #fff;
  overflow: hidden;
}
.bbs-thumb img { width: 100%; height: 100%; object-fit: cover; }
/* Stop-list foto-thumb (captain 2026-07-13): kleine highlight-foto in de rij
   met het stopnummer als hoek-badge eroverheen. Zonder foto rendert de rij de
   klassieke nummer-tegel (geen extra class). Badge = klein verzadigd schijfje
   (Colour Rule: saturated alleen voor badges), leesbaar op elke foto door de
   witte hairline + schaduw. min-width vangt 2-cijferige nummers. */
.bbs-thumb--img { position: relative; }
.bbs-thumb--img img { position: absolute; inset: 0; }
.bbs-thumb-badge {
  position: absolute; top: 3px; left: 3px; z-index: 1;
  min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; line-height: 1; color: #fff;
  background: linear-gradient(135deg, #274B8F, #3366FF);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.bbs-list-item .bbs-thumb-badge { font-size: 10px; min-width: 17px; height: 17px; }

.bbs-headtext { min-width: 0; flex: 1 1 auto; }
.bbs-title {
  font-size: 17px; font-weight: 600;
  letter-spacing: -0.018em; line-height: 1.2;
  color: var(--bbs-fg);
  text-wrap: balance;
}
.bbs-sub {
  font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--bbs-accent);
  margin-top: 3px;
}
.bbs-meta {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin-top: 7px;
}
.bbs-chip {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.2px;
  padding: 4px 10px; border-radius: 999px;   /* pill, matching the app's chip language */
  background: var(--bbs-chip-bg); color: var(--bbs-chip-fg);
  /* nowrap houdt de pill-vorm, maar zonder vangnet loopt een lange chip
     de sheet uit (toilet-openingstijden: 874 px in een 375 px viewport,
     captain 2026-07-27). De bron kort de tekst nu in; dit is de vangrail
     voor elke volgende chip die dat vergeet. */
  white-space: nowrap;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}
.bbs-chip--cyan { background: var(--bbs-chip-cyan-bg); color: var(--bbs-chip-cyan-fg); }
.bbs-chip--warn { background: var(--bbs-chip-warn-bg); color: var(--bbs-chip-warn-fg); }

/* ── Controls row (audio transport - stays visible at peek) ─────────────────── */
.bbs-controls {
  flex: 0 0 auto;
  padding: 0 16px 10px;
}
.bbs-controls[hidden] { display: none; }
.bbs-player {
  display: flex; align-items: center; gap: 12px;
  /* Ankerpunt voor de volume-popover (.bbs-vol), die absoluut boven de rij hangt. */
  position: relative;
}
.bbs-pbtn {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 0;
  background: #3366FF;
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(51, 102, 255, 0.42);
  transition: transform 180ms var(--bbs-ease);
}
.bbs-pbtn:active { transform: scale(0.94); }
.bbs-pbtn:disabled { opacity: 0.5; cursor: default; box-shadow: none; }
.bbs-pbtn--stop { width: 34px; height: 34px; background: rgba(255,255,255,0.12); color: var(--bbs-fg); box-shadow: none; }
.bbs-pbtn--stop[hidden] { display: none; }
/* Play/pause icon morph driven by .is-playing on the button. */
.bbs-pbtn .bbs-ic-pause { display: none; }
.bbs-pbtn.is-playing .bbs-ic-play { display: none; }
.bbs-pbtn.is-playing .bbs-ic-pause { display: inline; }
.bbs-bar {
  flex: 1 1 auto;
  height: 4px; border-radius: 2px;
  background: rgba(255, 255, 255, 0.15);
  overflow: hidden;
}
.bbs-bar-fill {
  display: block; height: 100%; width: 0;
  background: var(--bbs-accent);
  border-radius: 2px;
}
.bbs-time {
  flex: 0 0 auto;
  font-size: 10.5px; color: var(--bbs-fg-dim);
  font-variant-numeric: tabular-nums;
}
.bbs-controls.is-disabled { opacity: 0.5; pointer-events: none; }
/* Mute is een GLOBALE instelling, geen transport-knop: als de rij ooit
   uitgeschakeld wordt (geen clip bij het huidige hoogtepunt) moet hij
   bruikbaar blijven - in de oude topbalk was hij dat ook altijd. */
.bbs-controls.is-disabled .bbs-mute,
.bbs-player.is-disabled .bbs-mute { opacity: 1; pointer-events: auto; }
/* Mute hoort bij de speler (P3, captain 2026-07-26): #ltMuteBtn wordt door
   lt-sheet.js uit de live-tour chrome hierheen verplaatst en staat links van
   play. 28px rond, stil van kleur - de blauwe disc blijft de play-knop. */
.bbs-player .bbs-mute {
  flex: 0 0 auto;
  width: 28px; height: 28px; padding: 0; margin: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.10);
  color: var(--bbs-fg);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: none;
}
:root[data-theme="light"] .bbs-player .bbs-mute {
  border-color: rgba(9, 28, 53, 0.12);
  background: rgba(9, 28, 53, 0.06);
}
.bbs-player .bbs-mute:active { transform: scale(0.92); }
.bbs-player .bbs-mute .lt-mute-on,
.bbs-player .bbs-mute .lt-mute-off { font-size: 14px; line-height: 1; display: block; }
.bbs-player .bbs-mute .lt-mute-on[hidden],
.bbs-player .bbs-mute .lt-mute-off[hidden] { display: none; }

/* ── Volume-popover (variant B, captain 2026-07-27) ────────────────────────
   Een tik op de speaker-knop opent deze verticale slider boven de speler-rij
   (Control Center-stijl): percentage boven, witte fill-track, mute-toggle
   onder. Donker glaspaneel in BEIDE thema's - het zweeft over de kaart en de
   sheet heen, dus een lichte variant zou op een lichte kaart verdwijnen.
   Wit op #091C35-glas voldoet aan de contrastregel. */
.bbs-vol {
  /* Portal-kind van document.body (zie ensureVolPopover): de sheet knipt met
     overflow:hidden + transform alles weg wat erbovenuit steekt. left/bottom
     worden per opening gezet door placeVolPopover(). */
  position: fixed;
  left: 16px;
  bottom: 96px;
  /* Boven de sheet (96) en de kaart-chrome, maar onder de paneel/modal-laag
     (1085+) - een openstaande popover mag nooit over een dialoog vallen. */
  z-index: 400;
  width: 58px;
  box-sizing: border-box;
  padding: 9px 8px 8px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(9, 28, 53, 0.88);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.42);
}
.bbs-vol[hidden] { display: none; }
.bbs-vol-val {
  font-size: 11px; font-weight: 700; line-height: 1;
  color: #fff; font-variant-numeric: tabular-nums;
}
.bbs-vol.is-muted .bbs-vol-val { opacity: 0.55; }
.bbs-vol-track {
  position: relative;
  width: 34px; height: 132px;
  border-radius: 17px;
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
  cursor: pointer;
  /* Zonder dit pakt iOS het verticale sleepgebaar als page-scroll en springt
     de slider terug. */
  touch-action: none;
}
/* Hairline op de 100%-stand (de track loopt tot 200%), zodat de captain de
   neutrale stand blind terugvindt. */
.bbs-vol-track::after {
  content: ''; position: absolute; left: 6px; right: 6px; bottom: 50%;
  height: 1px; pointer-events: none;
  /* difference-blend: donker op de witte fill (volume > 100%), licht op de
     lege track (volume < 100%). Een vaste kleur is in een van beide standen
     onzichtbaar. */
  background: #fff; mix-blend-mode: difference;
}
.bbs-vol-fill {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 100%;
  background: #fff;
  border-radius: 17px 17px 0 0;
}
.bbs-vol-track:focus-visible { outline: 2px solid var(--bbs-accent); outline-offset: 2px; }
.bbs-vol-mute {
  width: 30px; height: 30px; padding: 0; margin: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.bbs-vol-mute[aria-pressed="true"] { background: rgba(255, 80, 60, 0.22); border-color: rgba(255, 80, 60, 0.5); }
.bbs-vol-mute:active { transform: scale(0.92); }
.bbs-vol-mute .lt-mute-on,
.bbs-vol-mute .lt-mute-off { font-size: 14px; line-height: 1; display: block; }
.bbs-vol-mute .lt-mute-on[hidden],
.bbs-vol-mute .lt-mute-off[hidden] { display: none; }

/* On-demand "Luister"/"Listen" pill in a TAPPED highlight's detail body
   (captain 2026-07-15). Blue play/pause disc (matches the mini-player button)
   + accent progress bar; navy-glass in dark, navy-tint in light. */
.bbs-hl-audio {
  display: flex; align-items: center; gap: 10px;
  width: 100%; box-sizing: border-box;
  margin: 2px 0 10px; padding: 9px 12px;
  border: 0; border-radius: 12px; cursor: pointer;
  background: rgba(255, 255, 255, 0.08); color: var(--bbs-fg);
  font: 600 0.85rem/1.2 inherit; text-align: left;
  position: relative; overflow: hidden;
}
:root[data-theme="light"] .bbs-hl-audio { background: rgba(9, 28, 53, 0.06); }
.bbs-hl-audio .bbs-hl-audio-ico {
  flex: 0 0 auto; display: inline-grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%;
  background: #3366FF; color: #fff;
  box-shadow: 0 3px 10px rgba(51, 102, 255, 0.4);
}
.bbs-hl-audio .bbs-hl-audio-ico::before { content: "\25B6"; font-size: 0.7rem; margin-left: 1px; }
.bbs-hl-audio.is-playing .bbs-hl-audio-ico::before { content: "\23F8"; margin-left: 0; }
.bbs-hl-audio .bbs-hl-audio-txt { flex: 1 1 auto; }
.bbs-hl-audio .bbs-hl-audio-bar {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: rgba(255, 255, 255, 0.14);
}
:root[data-theme="light"] .bbs-hl-audio .bbs-hl-audio-bar { background: rgba(9, 28, 53, 0.12); }
.bbs-hl-audio .bbs-hl-audio-fill {
  display: block; height: 100%; width: 0;
  background: var(--bbs-accent); transition: width 0.15s linear;
}

/* Rij rond de pill: speaker-knop links, pill vult de rest. Deze sheet heeft
   bewust geen transport-rij, dus zonder deze knop is volume/mute hier
   onbereikbaar (captain 2026-07-28). De pill hield zijn eigen marge, dus die
   verhuist naar de rij. */
.bbs-hl-audio-row {
  display: flex; align-items: center; gap: 8px;
  margin: 2px 0 10px;
}
.bbs-hl-audio-row .bbs-hl-audio { margin: 0; }
.bbs-hl-vol {
  flex: 0 0 auto; display: inline-grid; place-items: center;
  width: 38px; height: 38px; padding: 0;
  border: 0; border-radius: 12px; cursor: pointer;
  background: rgba(255, 255, 255, 0.08); color: var(--bbs-fg);
  font-size: 1rem; line-height: 1;
}
:root[data-theme="light"] .bbs-hl-vol { background: rgba(9, 28, 53, 0.06); }
.bbs-hl-vol[aria-expanded="true"] { background: rgba(51, 102, 255, 0.22); }
.bbs-hl-vol:active { transform: scale(0.94); }

/* ── Body (revealed at half+; scrolls) ─────────────────────────────────────── */
.bbs-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 16px 18px;
  font-size: 14px; line-height: 1.55;
  color: var(--bbs-fg-body);
  opacity: 0;
  transition: opacity 220ms var(--bbs-ease);
}
.bbs-body::-webkit-scrollbar { width: 0; height: 0; }
/* Mobile: the bottom tab-nav (page's own, or the app-shell's over the iframe)
   floats over the edge-to-edge sheet, so the LAST body content (actions, final
   lines) was hidden behind it. Reserve clearance so nothing tucks under the nav
   (audit 2026-07-12). Desktop dock has no bottom nav. */
.bbs:not(.bbs--desktop) .bbs-body { padding-bottom: calc(20px + var(--bbs-safe-bottom) + 84px); }

/* Inside the /app shell the floating bottom tab bar (.bb-mobile-nav) overlaps the
   bottom of the iframe, so at partial snaps the Routes filter chips + top stop-rows
   rendered BEHIND it (audit 2026-07-12). The sheet still starts from the screen
   bottom (glass runs seamlessly behind the floating nav - no detached gap), but a
   padding-bottom equal to the nav reserve pushes the CONTENT box up so it ends
   ABOVE the nav; .bbs is overflow:hidden + border-box so the body clips exactly at
   the nav top and nothing renders behind the bar (captain 2026-07-12). The shell
   measures its own nav and hands the reserve down as --bbs-shell-nav-h. Scoped to
   html.bb-embed per the CSS Cascade Scoping Rule - standalone pages keep their own
   84px body pad (below), since the var is unset (0) there. */
html.bb-embed .bbs:not(.bbs--desktop) { padding-bottom: var(--bbs-shell-nav-h, 0px); }
html.bb-embed .bbs:not(.bbs--desktop) .bbs-body { padding-bottom: calc(20px + var(--bbs-safe-bottom)); }
.bbs.bbs--half .bbs-body,
.bbs.bbs--full .bbs-body,
.bbs.bbs--fit .bbs-body,
.bbs.bbs--desktop .bbs-body { opacity: 1; }

/* Content-fit open: a detail opens at its natural height (body visible) instead
   of a fixed snap, so short content never leaves an empty void and the detail is
   readable without a drag-up. Capped at the full-snap height (then the body
   scrolls). Dragging converts back to the fixed snap model (see onDown). */
.bbs.bbs--fit {
  height: auto;
  /* fitOpen() always sets --bbs-fit-max in px; the fallback covers the frame
     before that runs. It keeps the historical 84vh when no page-level top
     reserve is declared, and honours the reserve when there is one (see
     topReservePx in src/shared/bb-sheet.js). */
  max-height: var(--bbs-fit-max, calc(100vh - max(16vh, var(--bbs-top-reserve, 0px))));
}
.bbs-body p + p { margin-top: 10px; }
.bbs-body img { max-width: 100%; }

/* ── Content scaling (captain 2026-07-12: "tekst en plaatje schalen niet goed") ─
   The reused Google-InfoWindow markup (.gmaps-popup) was capped at 312px, so on a
   wide sheet (tablet bottom-sheet, desktop dock) the content sat in a tiny left
   column with a big empty void and a small image. Let it FILL the sheet, cap the
   text column at a readable width centred, and make images responsive + larger. */
.bbs-body > .bbs-maps-body,
.bbs-body > .bbs-hl-body,
.bbs-body > .bbs-boat,
.bbs-body > .gmaps-popup { max-width: 680px; margin-inline: auto; }
.bbs .gmaps-popup { max-width: 100% !important; min-width: 0 !important; width: 100%; box-sizing: border-box; }
/* The reused .gmaps-popup body repeats the title (.pp-head) that the sheet head
   already shows - hide it so the title isn't duplicated (audit 2026-07-12). The
   rich eyebrow (.pp-sub) + detail stay. */
.bbs .gmaps-popup .pp-head { display: none; }
.bbs .gmaps-popup .pp-sub { margin-top: 0; }
/* The SWEETS booking link (.pp-link) rendered as a sharp, unpadded text link -
   make it a clean rounded button inside the sheet (audit 2026-07-12). */
.bbs .gmaps-popup .pp-link {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 14px; padding: 10px 16px;
  border-radius: 12px;
  background: var(--bbs-chip-cyan-bg); color: var(--bbs-chip-cyan-fg);
  font-weight: 600; font-size: 13px; text-decoration: none;
}
.bbs .gmaps-popup img,
.bbs .bbs-hl-img,
.bbs .bbs-photo {
  width: 100% !important; max-width: 100% !important; height: auto !important;
  aspect-ratio: 20 / 9; object-fit: cover; border-radius: 12px; margin-bottom: 12px;
}

/* ── Generic body helpers (shared by every map surface via bb-sheet-maps) ───── */
.bbs-maps-body { display: block; }
.bbs-photo {
  width: 100%; aspect-ratio: 20 / 9;
  object-fit: cover; border-radius: 12px;
  margin: 0 0 12px; display: block;
  background: rgba(127, 127, 127, 0.18);
}
.bbs-note {
  background: var(--bbs-chip-warn-bg); color: var(--bbs-chip-warn-fg);
  border: 1px solid rgba(180, 83, 9, 0.35);
  border-radius: 12px; padding: 10px 12px;
  font-size: 13px; line-height: 1.45; margin: 0 0 10px;
}
.bbs-rows { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 2px; }
.bbs-row {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid var(--bbs-hairline);
  font-size: 13.5px;
}
.bbs-row:last-child { border-bottom: none; }
.bbs-row .k { color: var(--bbs-fg-dim); }
.bbs-row .v { color: var(--bbs-fg); font-weight: 600; text-align: right; }
.bbs-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.bbs-links a { color: var(--bbs-accent); font-size: 13px; font-weight: 600; text-decoration: none; }
.bbs-act-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.bbs-act {
  flex: 1 1 auto; min-width: 120px;
  border: none; border-radius: 12px; padding: 11px 14px;
  font-size: 13.5px; font-weight: 600; cursor: pointer;
  font-family: var(--bbs-font);
}
.bbs-act--primary { background: #3366FF; color: #fff; }
.bbs-act--ghost { background: var(--bbs-chip-bg); color: var(--bbs-fg); }
.bbs-act--on { background: var(--bbs-chip-cyan-bg); color: var(--bbs-chip-cyan-fg); }
.bbs-act:active { transform: scale(0.98); }

/* ── Boat stat card (vaarverkeer / live-tour vessel detail) ─────────────────── */
.bbs-boat-photo {
  margin: 2px 0 10px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bbs-chip-bg);
}
.bbs-boat-photo img {
  display: block; width: 100%;
  aspect-ratio: 20 / 9; object-fit: cover;
}
/* Operator lockup (captain-approved 2026-07-13, variant A): a readable logo +
   name that replaces the old 'Rederij' stat cell. Sits between the photo and the
   stat grid. operatorColor is applied inline to the eyebrow + dot. */
/* Operator logo chip. Lives in the sheet HEAD (left of the vessel title) on the
   operator's brand colour, so light AND dark wordmarks read (captain 2026-07-13).
   The old body "Rederij" lockup card was folded into the head - the rederij name
   is now the head subtitle - so the body is just photo + stats, a much smaller
   panel. Wide wordmarks (e.g. "Flagship Amsterdam") keep their aspect: fixed 44px
   tall, width follows up to a cap; the mono-initials fallback stays square. */
.bbs-op-logo {
  height: 44px; width: auto; min-width: 44px; max-width: 104px; flex: 0 0 auto;
  border-radius: 11px; background: #fff; overflow: hidden; margin-top: 1px;
  display: grid; place-items: center; box-sizing: border-box;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18), inset 0 0 0 1px rgba(9, 28, 53, 0.06);
}
.bbs-op-logo img { height: 100%; width: auto; max-width: 92px; object-fit: contain; padding: 6px 8px; box-sizing: border-box; }
.bbs-op-logo--mono { width: 44px; box-shadow: none; }
.bbs-op-mono { color: #fff; font-weight: 800; font-size: 16px; letter-spacing: 0.5px; }
.bbs-boat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  margin-top: 4px;
}
/* Finish-moment completion card (captain 2026-07-17). Reuses .bbs-boat-* chips
   for the stat tiles; only the wrapper + the check circle need styling. Theme-
   aware via the sheet tokens. */
.lt-finish { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 2px 0; }
.lt-finish-check {
  width: 48px; height: 48px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; font-weight: 800; line-height: 1;
  background: var(--bbs-chip-bg); color: #3366FF;
}
.lt-finish .bbs-boat-grid { margin-top: 0; width: 100%; }
/* Vessel detail packs length + beam into one "Afmeting" cell, so the three core
   stats (afmeting / snelheid / koers) sit on ONE compact row instead of a tall
   2x2 (captain 2026-07-13). Destination, when present, spans the full width. */
.bbs-boat-grid--3 { grid-template-columns: repeat(3, 1fr); }
.bbs-boat-cell--wide { grid-column: 1 / -1; }
.bbs-boat-cell {
  background: var(--bbs-chip-bg);
  border-radius: 11px;
  padding: 7px 10px;
}
.bbs-boat-k {
  font-size: 9.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--bbs-fg-dim);
}
.bbs-boat-v {
  font-size: 14px; font-weight: 600;
  color: var(--bbs-fg);
  font-variant-numeric: tabular-nums;
  margin-top: 1px;
}
.bbs-boat-age {
  margin-top: 10px;
  font-size: 11.5px; color: var(--bbs-fg-dim);
}
.bbs-boat-age[hidden] { display: none; }
.bbs-boat-mmsi {
  margin-top: 6px;
  font-size: 11px; color: var(--bbs-fg-dim);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.bbs-boat-lost {
  margin-top: 8px;
  background: var(--bbs-chip-warn-bg); color: var(--bbs-chip-warn-fg);
  border: 1px solid rgba(180, 83, 9, 0.35);
  border-radius: 12px; padding: 9px 11px;
  font-size: 12.5px; font-weight: 600;
}

/* ── List template (cluster) ───────────────────────────────────────────────── */
.bbs-list-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px; border-radius: 12px;
  cursor: pointer;
}
.bbs-list-item:hover { background: var(--bbs-chip-bg); }
.bbs-list-item .bbs-thumb { width: 42px; height: 42px; font-size: 19px; border-radius: 10px; }
.bbs-list-item .bbs-li-title { font-size: 13.5px; font-weight: 600; color: var(--bbs-fg); }
.bbs-li-sub { font-size: 11px; color: var(--bbs-fg-dim); }
.bbs-li-go { margin-left: auto; color: var(--bbs-fg-dim); }

/* ── Type skins (thumb gradient + accent only) ─────────────────────────────── */
.bbs--stop   .bbs-thumb, .bbs--player .bbs-thumb { background: linear-gradient(135deg, #274B8F, #3366FF); }
.bbs--boot   .bbs-thumb { background: linear-gradient(135deg, #0D2440, #14538A); }
.bbs--strem  .bbs-thumb { background: linear-gradient(135deg, #8a5a10, #B45309); }
.bbs--opstap .bbs-thumb { background: linear-gradient(135deg, #0F5132, #1B7A4E); }
.bbs--toilet .bbs-thumb { background: linear-gradient(135deg, #3a4350, #4B5563); }
.bbs--regels .bbs-thumb { background: linear-gradient(135deg, #3E2A6E, #5E35B1); }
.bbs--dine   .bbs-thumb { background: linear-gradient(135deg, #7d0a1e, #C8102E); }
.bbs--cluster .bbs-thumb { background: linear-gradient(135deg, #1D3566, #274B8F); }

/* ── Desktop: right-docked 420px CONTENT-FIT floating card ─────────────────────
   Suggestion 1 (captain-approved 2026-07-12): the panel used to be full-height,
   leaving a big empty void under short content. It now grows to its content
   height (capped at the available height, then the body scrolls) as a floating
   rounded card - no void. */
@media (min-width: 960px) {
  .bbs.bbs--desktop {
    left: auto; right: 16px; top: var(--bbs-dock-top); bottom: auto;
    width: var(--bbs-dock-w);
    height: auto;
    max-height: calc(100% - var(--bbs-dock-top) - 20px);
    border-radius: 20px;
    border: 1px solid var(--bbs-border);
    transform: translateX(calc(100% + 24px));
    transition: transform var(--bbs-dur) var(--bbs-ease), visibility 0s linear var(--bbs-dur);
    padding-bottom: 12px;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.40);
  }
  .bbs.bbs--desktop.bbs--open {
    transform: translateX(0);
    transition: transform var(--bbs-dur) var(--bbs-ease);
  }
  /* No drag on desktop; the panel scrolls. Hide the grab handle, show a plain
     head, and let the body always show. */
  .bbs.bbs--desktop .bbs-grab { display: none; }
  .bbs.bbs--desktop .bbs-head { cursor: default; }
}

@media (prefers-reduced-motion: reduce) {
  .bbs, .bbs.bbs--open, .bbs.bbs--desktop { transition: none; }
  .bbs-body { transition: none; }
}
