
  span.svelte-114kfx9 svg {
    width: 100%;
    height: 100%;
    display: block;
  }

.driver-popover{all:unset;font-family:var(--driver-popover-font-family,"Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif);box-sizing:border-box;color:#2d2d2d;z-index:1000000000;background-color:#fff;border-radius:5px;min-width:250px;max-width:300px;margin:0;padding:15px;position:fixed;top:0;right:0;box-shadow:0 1px 10px #0006}.driver-popover-title{zoom:1;margin:0;font-size:19px;font-weight:700;line-height:1.5;display:block;position:relative}.driver-popover-close-btn{all:unset;cursor:pointer;color:#d2d2d2;z-index:1;text-align:center;width:32px;height:28px;font-size:18px;font-weight:500;transition:color .2s;position:absolute;top:0;right:0}.driver-popover-close-btn:hover,.driver-popover-close-btn:focus{color:#2d2d2d}.driver-popover-title[style*=block]+.driver-popover-description{margin-top:5px}.driver-popover-description{zoom:1;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.5}.driver-popover-footer{text-align:right;zoom:1;justify-content:space-between;align-items:center;margin-top:15px;display:flex}.driver-popover-progress-text{color:#727272;zoom:1;font-size:13px;font-weight:400}.driver-popover-footer-btn{all:unset;box-sizing:border-box;color:#2d2d2d;cursor:pointer;zoom:1;background-color:#fff;border:1px solid #ccc;border-radius:3px;outline:0;padding:3px 7px;font-size:12px;line-height:1.3;text-decoration:none;display:inline-block}.driver-popover-footer .driver-popover-btn-disabled{opacity:.5;pointer-events:none}.driver-popover-footer-btn:hover,.driver-popover-footer-btn:focus{background-color:#f7f7f7}.driver-popover-navigation-btns{flex-grow:1;justify-content:flex-end;display:flex}.driver-popover-navigation-btns button+button{margin-left:4px}.driver-popover-arrow{content:"";border:5px solid #fff;position:absolute}.driver-popover-arrow-side-over{display:none}.driver-popover-arrow-side-left{border-top-color:#0000;border-bottom-color:#0000;border-right-color:#0000;left:100%}.driver-popover-arrow-side-right{border-top-color:#0000;border-bottom-color:#0000;border-left-color:#0000;right:100%}.driver-popover-arrow-side-top{border-bottom-color:#0000;border-left-color:#0000;border-right-color:#0000;top:100%}.driver-popover-arrow-side-bottom{border-top-color:#0000;border-left-color:#0000;border-right-color:#0000;bottom:100%}.driver-popover-arrow-side-center,.driver-popover-arrow-none{display:none}.driver-active .driver-overlay{pointer-events:none}.driver-active.driver-no-scroll{overflow:hidden}.driver-active *{pointer-events:none}.driver-active .driver-active-element,.driver-active .driver-active-element *,.driver-popover,.driver-popover *{pointer-events:auto}@keyframes animate-fade-in{0%{opacity:0}to{opacity:1}}.driver-fade .driver-overlay{animation:animate-fade-in var(--driver-animation-duration,.4s) ease-in-out}.driver-fade .driver-popover{animation:animate-fade-in var(--driver-animation-duration,.4s)}.driver-active-element-parent-no-scroll{overflow:hidden!important}.driver-no-interaction,.driver-no-interaction *{pointer-events:none!important}
.driver-popover {
  padding: 16px 18px;
  color: #0f172a;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  box-shadow: 0 10px 40px rgb(15 23 42 / 15%);
}

.driver-popover-title {
  margin-bottom: 6px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.4;
}

.driver-popover-description {
  font-size: 14px;
  line-height: 1.6;
  color: #475569;
}

.driver-popover-progress-text {
  font-weight: 600;
  color: #64748b;
}

.driver-popover-footer {
  margin-top: 16px;
}

.driver-popover-footer button {
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  color: #0f172a;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 9999px;
  box-shadow: 0 1px 2px rgb(15 23 42 / 8%);
  transition: transform 120ms ease, box-shadow 150ms ease, background-color 120ms ease, border-color 120ms ease;
  -webkit-font-smoothing: antialiased;
}

.driver-popover-footer button:hover,
.driver-popover-footer button:focus {
  background: #f8fafc;
  border-color: #cbd5e1;
  box-shadow: 0 4px 14px rgb(15 23 42 / 12%);
}

.driver-popover-navigation-btns button:last-child {
  color: #fff;
  text-shadow: 0 0 1px rgb(0 0 0 / 15%);
  background: #2563eb;
  border-color: #1d4ed8;
  box-shadow: 0 4px 12px rgb(37 99 235 / 28%);
}

.driver-popover-navigation-btns button:last-child:hover,
.driver-popover-navigation-btns button:last-child:focus {
  background: #1e4dcc;
  border-color: #1e4dcc;
  box-shadow: 0 6px 16px rgb(37 99 235 / 32%);
}

.driver-popover-navigation-btns button:first-child {
  background: #f8fafc;
}

.driver-popover-navigation-btns button:first-child:hover,
.driver-popover-navigation-btns button:first-child:focus {
  background: #e2e8f0;
}

/* Dark mode */
:where(.dark, .dark *) .driver-popover {
  color: #f1f5f9;
  background: #1e293b;
  border-color: #334155;
  box-shadow: 0 10px 40px rgb(0 0 0 / 40%);
}

:where(.dark, .dark *) .driver-popover-description {
  color: #94a3b8;
}

:where(.dark, .dark *) .driver-popover-progress-text {
  color: #94a3b8;
}

:where(.dark, .dark *) .driver-popover-footer button {
  color: #f1f5f9;
  background: #1e293b;
  border-color: #334155;
}

:where(.dark, .dark *) .driver-popover-footer button:hover,
:where(.dark, .dark *) .driver-popover-footer button:focus {
  background: #334155;
  border-color: #475569;
}

:where(.dark, .dark *) .driver-popover-navigation-btns button:first-child {
  background: #334155;
}

:where(.dark, .dark *) .driver-popover-navigation-btns button:first-child:hover,
:where(.dark, .dark *) .driver-popover-navigation-btns button:first-child:focus {
  background: #475569;
}

:where(.dark, .dark *) .driver-popover-close-btn {
  color: #cbd5e1;
}

:where(.dark, .dark *) .driver-popover-close-btn:hover,
:where(.dark, .dark *) .driver-popover-close-btn:focus {
  color: #f8fafc;
}

  /* Default: hide all label variants; the wrapper's data-size attribute
     reveals one. JS-driven (see $effect) so the chosen variant tracks
     the SearchBar's actual left edge, not just viewport breakpoints. */
  .skipper-label.svelte-ua27qz {
    display: none;
  }
  [data-size="full"].svelte-ua27qz .skipper-label-full:where(.svelte-ua27qz),
  [data-size="short"].svelte-ua27qz .skipper-label-short:where(.svelte-ua27qz),
  [data-size="compact"].svelte-ua27qz .skipper-label-compact:where(.svelte-ua27qz),
  [data-size="tight"].svelte-ua27qz .skipper-label-tight:where(.svelte-ua27qz) {
    display: inline;
  }
  /* Tightest size hides the premium badge to free up horizontal space so
     "Help" fits when the search bar is most aggressively pushing — but the
     badge still participates in the flex row's cross-axis sizing, so the
     button keeps the same height it has with the badge visible. The
     negative margin counters the parent's gap-2 (0.5rem) that would
     otherwise leave a phantom 8px gap next to the collapsed badge. */
  [data-size="tight"].svelte-ua27qz .skipper-badge:where(.svelte-ua27qz) {
    visibility: hidden;
    width: 0;
    overflow: hidden;
    margin-inline-start: -0.5rem;
  }


  /* The caret that ties a beside-placed panel to the button that opened it.

     It STEMS FROM THE BUTTON: the wide base sits against the trigger and the
     apex meets the panel. The taper is the whole signal — a tail is read as
     belonging to the end it is WIDE at — so this direction says "this button
     opened that panel" where the mirror image said "this panel came from over
     there", which is the weaker of the two claims when the ambiguity being
     resolved is WHICH of five near-identical pills is the source.

     A border triangle rather than a rotated square: it needs no clipping
     against the panel's ring, and at this size the missing 1px hairline is
     invisible. */
  .mfm-menu-caret.svelte-1cehtyd {
    /* Half the caret's height. Its WIDTH is derived, not chosen: the caret
       spans the whole trigger-to-panel gap, so it bridges the two rather than
       floating in between with a gap at each end. */
    --mfm-caret-half: 6px;
    /* The panel's own `ml-3` (`beside-right`) / `mr-3` (`beside-left`). */
    --mfm-caret-gap: 12px;
    /* How far MfmControlButton's `.is-on` ring spreads outside the pill. The
       caret starts where the ring ends and wears its colour, so the two read as
       one continuous shape — the ring growing a tail — rather than as a
       separate mark that happens to touch the button. */
    --mfm-caret-ring: 2.5px;
    --mfm-caret-width: calc(var(--mfm-caret-gap) - var(--mfm-caret-ring));
    /* Half of MfmControlButton's 44px pill. The panel's bottom is pinned to the
       trigger's bottom, so this puts the caret on the trigger's centreline —
       which is why it needs no measurement and never drifts as the panel's
       height changes. A consumer with a differently-sized trigger overrides
       this one value through the `triggerHalfPx` prop, which lands on the
       caret as an inline style and so outranks this declaration (U8). */
    --mfm-trigger-half: 22px;
    position: absolute;
    left: calc(-1 * var(--mfm-caret-width));
    bottom: calc(var(--mfm-trigger-half) - var(--mfm-caret-half));
    width: 0;
    height: 0;
    border-top: var(--mfm-caret-half) solid transparent;
    border-bottom: var(--mfm-caret-half) solid transparent;
    /* `border-left`, so the base lands on the BUTTON and the apex points at the
       panel.

       The colour is MfmControlButton's `.is-on` RING, not the panel's surface:
       the caret belongs to the button it grows from, and the ring is the only
       part of that button whose colour is fixed — the pill's own fill inverts
       between green and white depending on state, while the ring is `#2bbe4a`
       whenever it is drawn at all, which is exactly whenever a caret exists. */
    border-left: var(--mfm-caret-width) solid #2bbe4a;
  }

  html.dark .mfm-menu-caret.svelte-1cehtyd {
    border-left-color: #35d357;
  }

  /* `beside-left` (U8): the same caret hung off the panel's RIGHT edge, its
     base against a trigger that now sits to the right. Only the horizontal
     half changes — the vertical offset above is shared, since both placements
     pin the panel's bottom to the trigger's. `border-left: 0` rather than
     `transparent` so the triangle's apex, not a doubled base, is what meets
     the panel. */
  .mfm-menu-caret.is-mirrored.svelte-1cehtyd {
    left: auto;
    right: calc(-1 * var(--mfm-caret-width));
    border-left: 0;
    border-right: var(--mfm-caret-width) solid #2bbe4a;
  }

  html.dark .mfm-menu-caret.is-mirrored.svelte-1cehtyd {
    border-right-color: #35d357;
  }


  /* 44px — the WCAG 2.5.5 floor the whole mfm cluster is held to, and the size
     the Havens menu's star buttons already use. A stepper on a moving boat is
     the last control that should be fiddly. */
  .crew-step.svelte-1k3ucnk {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid #d1d5db;
    border-radius: 999px;
    background: transparent;
    color: #374151;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    transition: border-color 0.15s ease, opacity 0.15s ease;
  }

  .crew-step.svelte-1k3ucnk:hover:not(:disabled) {
    border-color: #6b7280;
  }

  .crew-step.svelte-1k3ucnk:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }

  .crew-step.svelte-1k3ucnk:focus-visible {
    outline: 2px solid #18a33a;
    outline-offset: -2px;
  }

  html.dark .crew-step.svelte-1k3ucnk {
    border-color: #4b5563;
    color: #e5e7eb;
  }

  html.dark .crew-step.svelte-1k3ucnk:hover:not(:disabled) {
    border-color: #9ca3af;
  }


  /* The chrome's band height, published globally so siblings that must clear
     it can key off ONE number instead of a second hard-coded copy that drifts.
     `MapControls.svelte`'s `.search-results-panel` is the current consumer:
     its old `top: 60px` was tuned to sit below Google's Map/Satellite toggle,
     which A2/U1 turned off (`mapTypeControl: false`), leaving that offset
     arbitrary. Declared rather than measured — one number, no measurement
     race, and nothing for jsdom to read as 0. */
  :root {
    --map-chrome-h: 60px;
  }

  /* Absolutely positioned inside `.mapWrapper` (position: relative), the same
     containing block the two control clusters and the search-results panel
     use. z-index comes from the `z-mapchrome` Tailwind token on the element,
     NOT from here, so the ladder stays readable in one place. */
  .map-chrome.svelte-ozfspw {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    /* 8px vertical, 10px horizontal. The horizontal 10px is load-bearing —
       it puts the left cluster in the same column as `.search-results-panel`
       (left: 10px) and mirrors `.map-controls-container` (right: 10px).
       The vertical 8px absorbs the logo pill's growth to 44px so the band
       still measures 60px — i.e. exactly what `--map-chrome-h` has always
       claimed. */
    padding: 8px 10px;
    min-height: var(--map-chrome-h);
    /* The band spans the map's full width but is mostly empty. Letting it
       swallow pointer events there would make the top strip of the map
       undraggable, so events pass through the band and are re-enabled on the
       controls themselves. */
    pointer-events: none;
  }

  /* Batch 3 — invisible in single-row mode: `display: contents` hands the two
     clusters straight to the root's flex row, so nothing about the one-row
     layout changed when this wrapper appeared. In two-row mode it becomes the
     top row proper. It never sets `pointer-events` of its own — on the map
     variant the value inherits `none` from the band through it, and
     `.map-chrome-cluster > *` keeps re-enabling exactly one level below the
     clusters, same as always. */
  .map-chrome-row-top.svelte-ozfspw {
    display: contents;
  }

  .two-row.svelte-ozfspw .map-chrome-row-top:where(.svelte-ozfspw) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
  }

  /* The rows stack. `align-items: stretch` is what hands the search row the
     band's full width. Wins over the white variant's `items-start` utility on
     specificity (two class selectors plus the scope class). */
  .map-chrome.two-row.svelte-ozfspw,
  .app-chrome-white.two-row.svelte-ozfspw {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
  }

  .map-chrome-search-row.svelte-ozfspw {
    width: 100%;
  }

  /* The keyboard slide: with the on-screen keyboard up and focus in the search
     row, the top row leaves and the search bar becomes the top visible row.
     `display: none` rather than a transform — the white variant is sticky and
     in-flow, so only a real height change lets the page reclaim the space; on
     the map variant the band is absolute and the search row simply lands at
     the top. The keyboard's own show animation covers the transition. */
  .keyboard-slide.svelte-ozfspw .map-chrome-row-top:where(.svelte-ozfspw) {
    display: none;
  }

  .map-chrome-cluster.svelte-ozfspw {
    display: flex;
    align-items: center;
    gap: 12px;
    /* Shrink to content so the empty middle stays click-through. */
    min-width: 0;
  }

  /* Below the ladder's 368px floor the row is over-budget and something has
     to give. It must be the search slot's content, which has `min-width: 0`
     and (on /map) a text field designed to shrink, and NOT the profile menu:
     measured at a 320px map, a shrinkable right cluster took 6px out of the
     avatar (40px → 34px), squashing the one control on this row that has no
     smaller form. */
  .map-chrome-right.svelte-ozfspw {
    flex: 0 0 auto;
  }

  .map-chrome-cluster.svelte-ozfspw > * {
    pointer-events: auto;
  }

  /* A3/U2 — Menu.svelte's own wrapper (`relative inline-block`, unstyled
     here) is now `.map-chrome-left`'s direct flex child in the logo's place;
     this carries `.map-chrome-logo`'s "never shrink" contract (below)
     forward to that wrapper, since a flex property on a non-child has no
     effect. */
  .map-chrome-logo-wrap.svelte-ozfspw {
    flex: 0 0 auto;
  }

  /* The map's floating-surface shadow, copied from MapControlButton /
     MfmControlButton so the logo reads as one of the map's own controls.
     In scoped CSS rather than an arbitrary Tailwind value because the dark
     variant is toggled by `html.dark` (see $lib/utils/theme.ts) and the two
     values then sit side by side, which is how they stay in step. */
  .map-chrome-logo.svelte-ozfspw {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    /* Never shrink. Without this the pill is a flex item beside the search
       slot's content and gets squashed long before the ladder decides to
       swap it. The ladder replaces the logo deliberately at 531px; below
       that it must not also be quietly deformed on the way down. */
    flex: 0 0 auto;
  }

  html.dark .map-chrome-logo.svelte-ozfspw {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
  }

  /* Shortens "Talk to a real skipper" to "Skipper Help" at the
     `skipper-shortened` rung. `SkipperButton` already has a four-size label
     ladder; what it does NOT have on its own is anything driving it here.
     Its own `$effect` measures against `[data-testid="topbar-search-bar"]`,
     which this chrome never renders, so it bails and the button sits at
     `full` forever. Reaching in with CSS rather than a prop because the size
     lives in that component's private `$state` and its root carries
     `data-size` as a literal attribute — there is no seam to pass through
     without editing it.

     THE FOUR-CLASS PREFIX IS LOAD-BEARING, not habit. SkipperButton's own
     rule compiles to `[data-size="full"].s-X .skipper-label-full:where(.s-X)`
     — specificity (0,3,0), since `:where()` contributes nothing. Two classes
     here plus Svelte's scope class would only tie it, and a tie is settled by
     stylesheet order, which nothing in this repo pins. Three named classes
     plus the scope class clears it outright. */
  .map-chrome-cluster.map-chrome-right.skipper-short.svelte-ozfspw .skipper-label-full {
    display: none;
  }

  .map-chrome-cluster.map-chrome-right.skipper-short.svelte-ozfspw .skipper-label-short {
    display: inline;
  }

