@import url('https://fonts.googleapis.com/css2?family=Assistant:wght@200..800&family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
    .poi-action-icons.svelte-10larau {
      display: flex;
      flex-direction: column;
      gap: 4px;
      padding: 8px 0;
      width: 100%;
      box-sizing: border-box;
    }

    .action-row.svelte-10larau {
      display: flex;
      flex-direction: row;
      align-items: center;
      gap: 12px;
      padding: 4px 12px;
      background-color: transparent;
      color: var(--color-text);
      cursor: pointer;
      transition: background-color 0.2s ease-in-out;
      border: 0;
      margin: 0;
      text-align: left;
      width: 100%;
    }

    .action-row.svelte-10larau:hover {
      background-color: var(--color-background-mute);
    }

    .icon-wrapper.svelte-10larau {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      flex-shrink: 0;
    }

    .action-title.svelte-10larau {
      font-size: 14px;
      color: var(--color-indigo-600);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;

      &:hover {
        text-decoration: underline;
      }
    }

    .action-row.svelte-10larau .logo:where(.svelte-10larau) {
      width: 32px;
      height: 32px;
      background-size: contain;
      background-repeat: no-repeat;
      background-position: center;
    }

    .action-row.youtube.svelte-10larau .logo:where(.svelte-10larau) {
      background-image: url('../../../map-graphics/youtube.png');
      background-size: 28px;
    }

    .action-row.navily.svelte-10larau .logo:where(.svelte-10larau) {
      background-image: url('../../../map-graphics/navily.png');
      background-size: 160px;
      background-position: -14px -6px;
    }

    .action-row.google-maps.svelte-10larau .logo:where(.svelte-10larau) {
      background-image: url('../../../map-graphics/maps.png');
      background-size: 58px;
    }

    .action-row.external.svelte-10larau .logo:where(.svelte-10larau) {
      background-image: url('../../../map-graphics/external.png');
      background-size: 22px;
    }

    @media (max-width: 600px) {
    }

    /* Dark mode (class-based — html.dark) */
    html.dark .action-row.svelte-10larau {
      color: #f3f4f6;
    }
    html.dark .action-row.svelte-10larau:hover {
      background-color: #374151;
    }
    html.dark .action-title.svelte-10larau {
      color: #93c5fd;
    }
    /* The external-link logo is a single-colour black PNG that vanishes on
       the dark panel; invert it to white. The Navily/YouTube/Google-Maps
       logos are full-colour bitmaps and stay untouched. */
    html.dark .action-row.external.svelte-10larau .logo:where(.svelte-10larau) {
      filter: invert(1);
    }


  .button-container.svelte-6v9ve9 {
    display: flex;
    justify-content: center;
    width: 100%;
    margin: 8px 0;
  }

  .google-place-button.svelte-6v9ve9 {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    background-color: #e8f0fe;
    color: #1a73e8;
    border: none;
    border-radius: 20px;
    cursor: pointer;
    font-family: 'Google Sans', Roboto, Arial, sans-serif;
    font-size: 14px;
    font-weight: 400;
    transition: background-color 0.2s ease-in-out;
  }

  .google-place-button.svelte-6v9ve9:hover {
    background-color: #d2e3fc;
  }

  .google-place-button.svelte-6v9ve9:active {
    background-color: #c4d7f5;
  }

  .google-maps-logo.svelte-6v9ve9 {
    width: 20px;
    height: 20px;
    background-image: url('../../../map-graphics/maps.png');
    background-size: 52px;
    background-repeat: no-repeat;
    background-position: center;
    flex-shrink: 0;
  }

  .button-text.svelte-6v9ve9 {
    white-space: nowrap;
  }

  .button-text.svelte-6v9ve9 strong:where(.svelte-6v9ve9) {
    font-weight: 600;
  }

  /* Class-based dark mode toggled by $lib/utils/theme.ts on <html class="dark">. */
  html.dark .google-place-button.svelte-6v9ve9 {
    background-color: #1e3a8a;
    color: #93c5fd;
  }
  html.dark .google-place-button.svelte-6v9ve9:hover {
    background-color: #1e40af;
  }
  html.dark .google-place-button.svelte-6v9ve9:active {
    background-color: #2563eb;
  }


  /* 1h/3h/6h/12h/1d forecast cadence toggle (moved from PoiFacilities, U4). */
  .resolution-toggle.svelte-a42hs2 {
      display: inline-flex;
      flex-shrink: 0;
      border: 1px solid var(--color-gray-200, #e5e7eb);
      border-radius: 9999px;
      overflow: hidden;
      background: var(--card-background, #fff);
  }

  .res-btn.svelte-a42hs2 {
      border: 0;
      background: transparent;
      padding: 2px 8px;
      font-size: 12px;
      font-weight: 600;
      line-height: 1.5;
      color: #6b7280;
      cursor: pointer;
      transition: background 0.15s, color 0.15s;
  }

  .res-btn.active.svelte-a42hs2 {
      background: #1976d2;
      color: #fff;
  }

  html.dark .resolution-toggle.svelte-a42hs2 {
      border-color: #374151;
      background: #1f2937;
  }
  html.dark .res-btn.svelte-a42hs2 {
      color: #9ca3af;
  }
  html.dark .res-btn.active.svelte-a42hs2 {
      background: #60a5fa;
      color: #0b1220;
  }


  .contact-details.svelte-d5o650 {
    padding: 4px 10px;
    display: flex;
    flex-direction: column;
    row-gap: 12px;

    .contact-item:where(.svelte-d5o650) {
      display: flex;
      align-items: center;
      column-gap: 12px;
      font-size: 14px;
      color: var(--color-text);

      /* Phone/email fields: keep the original text inline with the swapped-in
         tokens, wrapping as a unit rather than stacking each on its own row. */
      .phone-field:where(.svelte-d5o650),
      .email-field:where(.svelte-d5o650) {
        display: inline-flex;
        flex-wrap: wrap;
        align-items: center;
        white-space: pre-wrap;
      }

      /* R29 — a `.contact-item a` rule used to live here, forcing every link
         in this component (email, website, tel fallback) to `#0b57d0` with
         no underline. Its selector (0,1,1) out-specifies the single-class
         `.a-normal` (0,1,0) now on those anchors, so keeping the rule
         alongside the class would have made adding the class a no-op — the
         link would still render with this rule's colour. Removed outright
         rather than merged into `a-normal`, since nothing else in this
         component's markup wants an unstyled link. */
    }
  }

  /* Dark mode (class-based — html.dark) */
  html.dark .contact-details.svelte-d5o650 .contact-item:where(.svelte-d5o650) {
    color: #f3f4f6;
  }
  html.dark .contact-details.svelte-d5o650 .material-symbols-outlined:where(.svelte-d5o650) {
    color: #d1d5db;
  }


  .haven-score-graph.svelte-1ges2s0 {
    touch-action: none;
    user-select: none;
    cursor: grab;
    /* The score pill always floats above the line; at high scores it extends
       past the top of the plot frame. Let it draw there (it may overlap the
       slider above — acceptable) rather than being clipped. */
    overflow: visible;
  }

  .haven-score-graph.grabbing.svelte-1ges2s0 {
    cursor: grabbing;
  }

  .curve-layer.svelte-1ges2s0 {
    transition: transform 0.2s ease-out;
  }

  .curve-layer.dragging.svelte-1ges2s0 {
    transition: none;
  }

  /* Fill comes from the per-band alpha-ramp gradient (black); the theme strength
     is applied here as element opacity (× the gradient's 0→1→0 edge ramp). */
  .night-rect.svelte-1ges2s0 {
    opacity: 0.14;
  }

  .gridline.svelte-1ges2s0 {
    stroke: rgba(100, 116, 139, 0.35);
    stroke-width: 1;
  }

  .grid-label.svelte-1ges2s0 {
    font-size: 9px;
    font-family: sans-serif;
    fill: #64748b;
  }

  .axis-title.svelte-1ges2s0 {
    font-size: 9px;
    font-family: sans-serif;
    font-weight: 600;
    letter-spacing: 0.3px;
    fill: #94a3b8;
  }

  .marker-line.svelte-1ges2s0 {
    stroke: rgba(100, 116, 139, 0.6);
    stroke-width: 1;
    stroke-dasharray: 3 3;
  }

  .score-pill-text.svelte-1ges2s0 {
    font-size: 11px;
    font-family: sans-serif;
    font-weight: 700;
    fill: #fff;
  }

  /* Dot + pill glide vertically between steps; instant while actively scrolling
     (mirrors .curve-layer so the dot tracks the line frame-for-frame mid-drag). */
  .marker-dot.svelte-1ges2s0 {
    transition: transform 0.2s ease-out;
  }

  .marker-dot.dragging.svelte-1ges2s0 {
    transition: none;
  }

  /* Dark mode overrides */
  html.dark .night-rect.svelte-1ges2s0 {
    /* Stronger on dark so the night band stays visible against dark bands. */
    opacity: 0.30;
  }

  html.dark .gridline.svelte-1ges2s0 {
    stroke: rgba(148, 163, 184, 0.25);
  }

  html.dark .grid-label.svelte-1ges2s0 {
    fill: #94a3b8;
  }

  html.dark .axis-title.svelte-1ges2s0 {
    fill: #64748b;
  }

  html.dark .marker-line.svelte-1ges2s0 {
    stroke: rgba(148, 163, 184, 0.5);
  }


    .poi-facilities-container.svelte-1l73rip {
        width:100%;
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        font-size: 14px;
        color: var(--text-color);
        padding: 4px 0;
        box-sizing: border-box;
        max-height: 140px;
        overflow: hidden;

        .more:where(.svelte-1l73rip) {
            position:absolute;
            right: 12px;
            top: 50%;
            transform: translateY(-50%);
            display:flex;
            align-items: center;
            justify-content: flex-end;

            button:where(.svelte-1l73rip) {
                height: 36px;
                width: 36px;
                border:0;
                background-color: var(--color-gray-200);
                border-radius: 9999px;
                display:flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;

                .material-symbols-outlined:where(.svelte-1l73rip) {
                    font-size: 24px;
                    color: var(--icon-color);
                }
            }
        }

        .poi-facilities:where(.svelte-1l73rip) {
            border:0;
            background:transparent;
            width: 100%;
            text-align: left;
            line-height: 0;
            padding-right: 40px;

            &::-webkit-scrollbar {
                display: none;
            }

            .facility-item:where(.svelte-1l73rip) {
                display: inline-flex;
                vertical-align: middle;
                align-items: center;
                gap: 4px;
                background-color: var(--card-background);
                padding: 4px 8px;
                border-radius: 4px;

                .material-symbols-outlined:where(.svelte-1l73rip) {
                    padding:2px 0;
                }

                .facility-icon:where(.svelte-1l73rip) {
                    width: 28px;
                    height: 28px;
                    min-width: 28px;
                    min-height: 28px;
                    fill: var(--icon-color);
                }
            }
        }

        &.is-open {
            max-height: none;
            align-items: flex-start;
            column-gap: 0;
            padding: 11px 3px;

            .more:where(.svelte-1l73rip) {
                top: 10px;
                transform: none;
            }

            .more-info:where(.svelte-1l73rip) {
                width:100%;
                display: flex;
                flex-direction: row;
                /* When there isn't room for the facilities beside the weather
                   section, the weather section wraps as a WHOLE onto its own
                   full-width row (its internal weather|wind-rose columns stay
                   side by side — R12: temp/humidity never above the rose). */
                flex-wrap: wrap;
                justify-content: space-between;
                align-items: flex-start;
                gap: 8px;
                /* Size container so the weather section can compress its
                   internal gap at narrow widths (see @container below). */
                container-type: inline-size;
            }

            .facilities-column:where(.svelte-1l73rip) {
                display: flex;
                flex-direction: column;
                /* basis:auto (not 0) so the column's natural width drives the
                   flex line-break: if the labels can't fit beside the weather
                   section, the weather section wraps instead of crowding them. */
                flex: 1 1 auto;
                min-width: 0;
            }

            .poi-facilities:where(.svelte-1l73rip) {
                display: flex;
                text-align: initial;
                line-height: normal;
                padding-right: 0;
                width: auto;
                flex-shrink: 0;
                flex-direction: column;
                align-items: flex-start;
                row-gap:8px;

                .facility-item:where(.svelte-1l73rip) {
                    column-gap:12px;
                }
            }

            .weather-wind-section:where(.svelte-1l73rip) {
                display: flex;
                flex-direction: row;
                /* stretch so the weather column spans the wind-rose height; that
                   lets the 1h/3h toggle (item 13) pin to the bottom, level with
                   the wind-rose legend, while the readout stays vertically centered. */
                align-items: stretch;
                gap: 35px; /* 40px to account for wind rose arrow length */
                flex-shrink: 0;
                /* Centered when it wraps onto its own row; inert while sharing
                   a row (the facilities column's flex-grow absorbs free space). */
                margin-inline: auto;
            }

            /* Narrow panels: once the weather section is on its own row and
               space is still tight, compress the inter-column gap (the weather
               column already renders above the rose arrows via z-index) —
               but NEVER stack the two columns. */
            @container (max-width: 410px) {
                .weather-wind-section:where(.svelte-1l73rip) {
                    gap: 12px;
                }
            }

            .weather-column:where(.svelte-1l73rip) {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                position: relative;
                z-index: 1; /* Render above wind rose arrows */
            }

            /* Wraps the WeatherDisplay so it centers in the space above the
               bottom-pinned 1h/3h toggle when the column is stretched. */
            .weather-display-wrap:where(.svelte-1l73rip) {
                flex: 1;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .wind-rose-column:where(.svelte-1l73rip) {
                flex-shrink: 0;
            }
        }
    }

    .time-slider-container.svelte-1l73rip {
        width: 100%;
    }

    /* Item 14: haven score graph (havens only) */
    .haven-graph-container.svelte-1l73rip {
        width: 100%;
        padding: 2px 0 0;
    }

    /* Worst-gust note for coarse cadences (explains a low worst-case score) */
    .max-gust-note.svelte-1l73rip {
        display: inline-flex;
        align-items: center;
        gap: 3px;
        font-size: 11px;
        font-weight: 600;
        color: #b45309; /* amber-700 */
        white-space: nowrap;
    }
    .max-gust-note.svelte-1l73rip .material-symbols-outlined:where(.svelte-1l73rip) {
        font-size: 14px;
    }
    html.dark .max-gust-note.svelte-1l73rip {
        color: #fbbf24; /* amber-400 */
    }

    /* Forecast cadence toggle styles moved to CadenceControl.svelte (U4). */

    .weather-loading.svelte-1l73rip,
    .weather-error.svelte-1l73rip {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 16px;
        color: #666;
        font-size: 13px;
    }

    .weather-error.svelte-1l73rip {
        color: #999;
    }

    .spinning.svelte-1l73rip {
        animation: svelte-1l73rip-spin 1s linear infinite;
    }

    @keyframes svelte-1l73rip-spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }

    .weather-compact.svelte-1l73rip {
        display: inline-flex;
        vertical-align: middle;
        align-items: center;
        gap: 6px;
        padding: 4px 8px;
        border-radius: 4px;
        font-size: 12px;
        font-weight: 600;
    }

    .inline-windrose.svelte-1l73rip {
        display: inline-flex;
        vertical-align: middle;
    }

    .weather-compact-icon.svelte-1l73rip {
        width: 22px;
        height: 22px;
    }

    .temp-compact.svelte-1l73rip {
        color: #333;
    }

    .wind-compact.svelte-1l73rip {
        color: #1976d2;
    }

    /* Dark mode (class-based — html.dark) */
    html.dark .facility-icon.svelte-1l73rip {
        /* Facility SVGs ship as black-on-transparent — invert to white-on-
           transparent for dark mode rather than rebuilding the assets. */
        filter: invert(1);
    }
    html.dark .material-symbols-outlined.svelte-1l73rip,
    html.dark .temp-compact.svelte-1l73rip {
        color: #f3f4f6;
    }
    html.dark .wind-compact.svelte-1l73rip {
        color: #60a5fa;
    }
    html.dark .weather-compact.svelte-1l73rip .text-gray-400:where(.svelte-1l73rip) {
        color: #9ca3af;
    }
    /* Round chevron-up "collapse facilities" button uses --color-gray-200
       which the theme system doesn't remap; force a dark surface so it
       doesn't read as a flashlight on the dark panel. */
    html.dark .poi-facilities-container.svelte-1l73rip .more:where(.svelte-1l73rip) button:where(.svelte-1l73rip) {
        background-color: #374151;
    }
    html.dark .poi-facilities-container.svelte-1l73rip .more:where(.svelte-1l73rip) button:where(.svelte-1l73rip) .material-symbols-outlined:where(.svelte-1l73rip) {
        color: #f3f4f6;
    }


  .icon.share.svelte-1hj3f1v {
    border: 0;
    background: transparent;
    cursor: pointer;

    span:where(.svelte-1hj3f1v) {
      font-size: 28px;
    }
  }


  .locale-pill-wrapper.svelte-16vdizi {
    position: relative;
    display: inline-flex;
    /* RTL-safe right-align: sits at the logical end of the parent flex row
       in both LTR and RTL. */
    margin-inline-start: auto;
  }

  .locale-pill.svelte-16vdizi {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 9999px;
    border: 1px solid rgb(0 0 0 / 12%);
    background: rgb(255 255 255 / 80%);
    color: #374151;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 120ms ease, opacity 120ms ease;
  }

  .locale-pill.svelte-16vdizi:hover {
    background: rgb(255 255 255 / 100%);
  }

  .locale-pill-disabled.svelte-16vdizi {
    opacity: 0.5;
    pointer-events: none;
    cursor: wait;
  }

  .locale-pill-code.svelte-16vdizi {
    line-height: 1.2;
  }

  .locale-pill-chevron.svelte-16vdizi {
    width: 12px;
    height: 12px;
    color: rgb(0 0 0 / 50%);
  }

  .locale-pill-spinner.svelte-16vdizi {
    font-size: 12px;
    animation: svelte-16vdizi-locale-pill-spin 1s linear infinite;
  }

  @keyframes svelte-16vdizi-locale-pill-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }

  .locale-pill-popover.svelte-16vdizi {
    /* FIXED, not absolute: the pill's hosts live inside SlidePanel's
       overflow-hidden box, which clips an in-panel popover on the mobile
       bottom sheet whichever direction it opens. The inline style written by
       measurePopover() carries top/left (and max-height when capped);
       placeLocalePopover keeps the RTL-aware inline-end anchoring the old
       `inset-inline-end: 0` provided. */
    position: fixed;
    z-index: 1010;
    min-width: 180px;
    padding: 4px;
    background: #fff;
    border: 1px solid rgb(0 0 0 / 8%);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
  }

  .locale-pill-option.svelte-16vdizi {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 6px 10px;
    border: 0;
    background: transparent;
    color: #1f2937;
    font-size: 13px;
    text-align: start;
    cursor: pointer;
    border-radius: 4px;
  }

  .locale-pill-option.svelte-16vdizi:hover,
  .locale-pill-option.svelte-16vdizi:focus-visible {
    background: rgb(0 0 0 / 5%);
    outline: none;
  }

  .locale-pill-option-active.svelte-16vdizi {
    font-weight: 600;
  }

  .locale-pill-option-check.svelte-16vdizi {
    width: 14px;
    color: #2563eb;
  }

  .locale-pill-option-name.svelte-16vdizi {
    flex: 1;
  }

  .locale-pill-option-code.svelte-16vdizi {
    color: rgb(0 0 0 / 50%);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
  }

  /* Dark mode — match the rest of the map panels. */
  html.dark .locale-pill.svelte-16vdizi {
    background: rgb(31 41 55 / 80%);
    color: #e5e7eb;
    border-color: rgb(255 255 255 / 12%);
  }

  html.dark .locale-pill.svelte-16vdizi:hover {
    background: rgb(31 41 55 / 100%);
  }

  html.dark .locale-pill-chevron.svelte-16vdizi {
    color: rgb(255 255 255 / 50%);
  }

  html.dark .locale-pill-popover.svelte-16vdizi {
    background: #1f2937;
    border-color: rgb(255 255 255 / 12%);
    color: #e5e7eb;
  }

  html.dark .locale-pill-option.svelte-16vdizi {
    color: #e5e7eb;
  }

  html.dark .locale-pill-option.svelte-16vdizi:hover,
  html.dark .locale-pill-option.svelte-16vdizi:focus-visible {
    background: rgb(255 255 255 / 10%);
  }

.report-form {
  display: flex;
  flex-direction: column;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  font-family: "Open Sans", sans-serif;
}

.report-header {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e5e7eb;

  h3 {
    flex: 1;
    margin: 0;
    font-size: 18px;
    font-weight: 600;
  }

  .back-arrow,
  .close-x {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    cursor: pointer;
    background: #f0f0f0;
    border: none;
    border-radius: 50%;
  }
}

.report-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  overflow-y: auto;
}

.section-label {
  margin-top: 8px;
  font-size: 14px;
  font-weight: 600;
  color: #374151;
}

/* Severity cards */
.severity-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.severity-card {
  display: grid;
  grid-template-rows: auto auto;
  grid-template-columns: auto 1fr;
  column-gap: 10px;
  align-items: center;
  padding: 10px 12px;
  text-align: left;
  cursor: pointer;
  background: white;
  border: 2px solid #e5e7eb;
  border-radius: 10px;
  transition: border-color 0.15s, background-color 0.15s;

  &:hover {
    background: #f9fafb;
  }

  &.selected {
    background: color-mix(in srgb, var(--card-color) 6%, white);
    border-color: var(--card-color);
  }
}

.severity-emoji {
  grid-row: 1 / -1;
  align-self: center;
  font-size: 22px;
}

.severity-label {
  font-size: 14px;
  font-weight: 600;
  color: #1f2937;
}

.severity-sublabel {
  font-size: 12px;
  color: #6b7280;
}

/* Description textarea */
textarea#report-description {
  box-sizing: border-box;
  width: 100%;
  min-height: 80px;
  padding: 10px 12px;
  font-family: "Open Sans", sans-serif;
  font-size: 14px;
  resize: vertical;
  border: 1px solid #d1d5db;
  border-radius: 8px;

  &:focus {
    border-color: #3b82f6;
    outline: none;
    box-shadow: 0 0 0 2px rgb(59 130 246 / 20%);
  }
}

/* Photo upload */
.photo-buttons {
  display: flex;
  gap: 8px;
}

.upload-btn {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 500;
  color: #374151;
  cursor: pointer;
  background: #f3f4f6;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  transition: background 0.15s;

  &:hover {
    background: #e5e7eb;
  }

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

.photo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

@media (width <= 400px) {
  .photo-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.photo-preview {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 8px;

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .remove-photo {
    position: absolute;
    top: 4px;
    right: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    color: white;
    cursor: pointer;
    background: rgb(239 68 68 / 90%);
    border: none;
    border-radius: 50%;

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

/* Email field */
.email-subtitle {
  margin: 0;
  font-size: 12px;
  color: #6b7280;
}

/* Photo upload consent notice (shown under the photo buttons in both modes) */
.photo-consent {
  margin: 6px 0 0;
  font-size: 11px;
  line-height: 1.4;
  color: #6b7280;
}

.report-form input[type="text"],
.report-form input[type="email"] {
  box-sizing: border-box;
  width: 100%;
  padding: 10px 12px;
  font-family: "Open Sans", sans-serif;
  font-size: 14px;
  border: 1px solid #d1d5db;
  border-radius: 8px;

  &:focus {
    border-color: #3b82f6;
    outline: none;
    box-shadow: 0 0 0 2px rgb(59 130 246 / 20%);
  }
}

/* Error message */
.error-message {
  margin: 0;
  font-size: 13px;
  color: #ef4444;
}

/* Submit button */
.submit-button {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 12px 16px;
  margin-top: 8px;
  font-family: "Open Sans", sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: white;
  cursor: pointer;
  background: #3b82f6;
  border: none;
  border-radius: 10px;
  transition: background 0.15s;

  &:hover:not(:disabled) {
    background: #2563eb;
  }

  &:disabled {
    cursor: not-allowed;
    background: #9ca3af;
  }

  .spinning {
    font-size: 18px;
    animation: spin 1s linear infinite;
  }
}

/* Success view */
.success-view {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  text-align: center;

  .success-icon {
    font-size: 48px;
  }

  h3 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    color: #1f2937;
  }

  p {
    margin: 0;
    font-size: 14px;
    color: #6b7280;
  }

  .email-note {
    font-size: 13px;
    font-style: italic;
    color: #3b82f6;
  }
}

.back-button-full {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 240px;
  padding: 10px 20px;
  margin-top: 16px;
  font-family: "Open Sans", sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: #3b82f6;
  cursor: pointer;
  background: white;
  border: 2px solid #3b82f6;
  border-radius: 10px;
  transition: background 0.15s;

  &:hover {
    background: #eff6ff;
  }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

  /* Dark mode (class-based — html.dark) lives here so :global() compiles. */
  html.dark .report-form,
  html.dark .severity-label {
    color: #f3f4f6;
  }
  html.dark .report-header {
    border-bottom-color: rgb(255 255 255 / 10%);
  }
  html.dark .report-header .back-arrow,
  html.dark .report-header .close-x {
    color: #f3f4f6;
    background: #374151;
  }
  html.dark .section-label {
    color: #e5e7eb;
  }
  html.dark .severity-card {
    color: #f3f4f6;
    background: #374151;
    border-color: #4b5563;
  }
  html.dark .severity-card:hover {
    background: #4b5563;
  }
  html.dark .severity-card.selected {
    background: color-mix(in srgb, var(--card-color) 18%, #374151);
    border-color: var(--card-color);
  }
  html.dark .severity-sublabel,
  html.dark .email-subtitle,
  html.dark .photo-consent,
  html.dark .success-view p {
    color: #9ca3af;
  }
  html.dark .report-form textarea#report-description,
  html.dark .report-form input[type="text"],
  html.dark .report-form input[type="email"] {
    color: #f3f4f6;
    background: #374151;
    border-color: #4b5563;
  }
  html.dark .report-form textarea#report-description::placeholder,
  html.dark .report-form input[type="text"]::placeholder,
  html.dark .report-form input[type="email"]::placeholder {
    color: #9ca3af;
  }
  html.dark .report-form textarea#report-description:focus,
  html.dark .report-form input[type="text"]:focus,
  html.dark .report-form input[type="email"]:focus {
    border-color: #3b82f6;
    box-shadow: 0 0 0 2px rgb(59 130 246 / 35%);
  }
  html.dark .upload-btn {
    color: #f3f4f6;
    background: #374151;
    border-color: #4b5563;
  }
  html.dark .upload-btn:hover {
    background: #4b5563;
  }
  html.dark .error-message {
    color: #f87171;
  }
  html.dark .submit-button:disabled {
    background: #4b5563;
  }
  html.dark .success-view h3 {
    color: #f3f4f6;
  }
  html.dark .success-view .email-note,
  html.dark .back-button-full {
    color: #60a5fa;
  }
  html.dark .back-button-full {
    background: transparent;
    border-color: #60a5fa;
  }
  html.dark .back-button-full:hover {
    background: rgb(96 165 250 / 12%);
  }

.slide-panel {
  overflow: hidden;
  background-color: white;
  box-shadow: 0 -2px 10px rgb(0 0 0 / 10%);
  will-change: transform;
}

.slide-panel.portrait {
  border-radius: 20px 20px 0 0;
}

.slide-panel.landscape {
  border-radius: 0;
  box-shadow: -2px 0 10px rgb(0 0 0 / 10%);
}

/* Drag handle areas */
.drag-handle-area {
  flex-shrink: 0;
  touch-action: none;
  cursor: grab;
  user-select: none;
}

.drag-handle-area:active {
  cursor: grabbing;
}

/* Portrait: horizontal pill at top */
.portrait-handle {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 28px;
}

.portrait-collapse-btn {
  position: absolute;
  top: 50%;
  right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  color: #5f6368;
  touch-action: manipulation;
  cursor: pointer;
  background: transparent;
  border: none;
  border-radius: 50%;
  transform: translateY(-50%);
}

.portrait-collapse-btn:active {
  background-color: rgb(0 0 0 / 8%);
}

.portrait-collapse-btn .material-symbols-outlined {
  font-size: 22px;
}

.drag-pill {
  width: 36px;
  height: 4px;
  background-color: #dadce0;
  border-radius: 2px;
}

/* Landscape: vertical bar on left edge */
.landscape-handle {
  position: absolute;
  top: 0;
  left: -12px;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 100%;
}

.drag-bar {
  width: 4px;
  height: 48px;
  background-color: #dadce0;
  border-radius: 2px;
}

.landscape-handle:hover .drag-bar {
  background-color: #bbb;
}

.landscape-collapse-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  color: #5f6368;
  touch-action: manipulation;
  cursor: pointer;
  background: transparent;
  border: none;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.landscape-collapse-btn:active {
  background-color: rgb(0 0 0 / 8%);
}

.landscape-collapse-btn .material-symbols-outlined {
  font-size: 20px;
}

/* Inner layout */
.slide-panel-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.slide-panel.portrait .slide-panel-inner {
  height: calc(100% - 28px); /* subtract handle height */
}

.slide-panel-header {
  flex-shrink: 0;
}

.slide-panel-content {
  flex: 1;

  /* Contain scroll chaining so flinging past the end of the panel never
     scrolls the page/map behind it. */
  overflow: hidden auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Smooth max-height transition during snap animation */
.slide-panel.portrait.is-animating .slide-panel-inner {
  transition: max-height 0.3s cubic-bezier(0.77, 0, 0.175, 1);
}

/* Disable scrollbar flicker during drag */
.slide-panel.is-dragging .slide-panel-content {
  overflow: hidden;
}

/* Dark-mode rules live inside SlidePanel.svelte's \3c style> block so :global()
   compiles correctly. */

  /* Dark mode lives here in the Svelte \3c style> block (not the imported CSS
     file) so :global() reliably reaches the compiler. Selectors use the
     class-based dark mode set up by $lib/utils/theme.ts on <html class="dark">. */
  html.dark .slide-panel {
    background-color: #1f2937;
    color: #f3f4f6;
    box-shadow: 0 -2px 10px rgb(0 0 0 / 50%);
  }
  html.dark .slide-panel.landscape {
    box-shadow: -2px 0 10px rgb(0 0 0 / 50%);
  }
  html.dark .drag-pill,
  html.dark .drag-bar {
    background-color: #4b5563;
  }
  html.dark .landscape-handle:hover .drag-bar {
    background-color: #6b7280;
  }
  html.dark .portrait-collapse-btn,
  html.dark .landscape-collapse-btn {
    color: #d1d5db;
  }
  html.dark .portrait-collapse-btn:active,
  html.dark .landscape-collapse-btn:active {
    background-color: rgb(255 255 255 / 8%);
  }

/* InfoPanel content styles - positioning handled by SlidePanel */

.poi-header {
  position: relative;
  display: flex;
  flex-flow: column wrap;
  gap: 10px;
  row-gap: 2px;
  align-items: flex-start;
  font-family: "Open Sans", sans-serif;

  .back-button {
    position: absolute;
    top: 6px;
    left: 0;
  }

  .poi-title-row {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    width: 100%;
    padding: 12px 16px 0;
  }

  .poi-header-actions {
    display: flex;
    flex-shrink: 0;
    gap: 8px;
    align-items: center;
  }

  .close-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    cursor: pointer;
    background: #f0f0f0;
    border: none;
    border-radius: 50%;
  }

  .draft-tag {
    padding: 2px 8px;
    font-size: 12px;
    font-weight: 600;
    color: #b45309;
    background: #fef3c7;
    border: 1px solid #f59e0b;
    border-radius: 4px;
  }

  .edit-location-button {
    cursor: pointer;
    background: transparent;
    border: 0;
  }

  .edit-location-button .material-symbols-outlined {
    font-size: 28px;
  }

  .report-button {
    cursor: pointer;
    background: transparent;
    border: 0;
  }

  .report-button .material-symbols-outlined {
    font-size: 28px;
  }

  .add-to-itinerary-button {
    display: flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    width: calc(100% - 32px);
    padding: 8px 16px;
    margin: 0 16px;
    font-family: "Open Sans", sans-serif;
    font-size: 14px;
    font-weight: 500;
    color: white;
    cursor: pointer;
    background: #4caf50;
    border: none;
    border-radius: 8px;
    transition:
      background-color 0.2s ease,
      opacity 0.2s ease;
  }

  .add-to-itinerary-button:hover {
    background: #388e3c;
  }

  .add-to-itinerary-button .material-symbols-outlined {
    font-size: 20px;
  }

  .add-to-itinerary-button .button-text {
    white-space: nowrap;
  }

  .add-to-itinerary-button.add-again {
    background: #1976d2;
  }

  .add-to-itinerary-button.add-again:hover {
    background: #1565c0;
  }

  /* Split "Add to itinerary": main zone (direct add to the last day) +
     arrow zone (day dropdown). The two buttons share one pill silhouette —
     the split lives on the wrapper, each half dropping the outer margin and
     the facing corner radii, with a hairline divider between them. */
  .add-to-itinerary-wrap {
    position: relative;
  }

  .add-to-itinerary-split {
    display: flex;
    align-items: stretch;
    width: calc(100% - 32px);
    margin: 0 16px;
  }

  .add-to-itinerary-split .add-to-itinerary-button {
    width: auto;
    margin: 0;
  }

  .add-to-itinerary-split .add-to-itinerary-main {
    flex: 1;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  .add-to-itinerary-split .add-to-itinerary-arrow {
    flex: 0 0 auto;
    padding: 8px 6px;
    border-left: 1px solid rgb(255 255 255 / 35%);
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }

  .add-to-itinerary-button .day-menu-caret {
    margin-left: auto;
  }

  /* Keep the trigger above the click-away backdrop while the menu is open so
     it stays interactive (toggle-to-close) and shows hover/active states. */
  .add-to-itinerary-split.day-menu-open {
    position: relative;
    z-index: 12;
  }

  .day-menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10;
  }

  .day-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 16px;
    left: 16px;
    z-index: 11;
    display: flex;
    flex-direction: column;
    max-height: 240px;
    padding: 6px;
    overflow-y: auto;
    background: white;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
  }

  .day-menu-title {
    padding: 4px 8px 6px;
    font-family: "Open Sans", sans-serif;
    font-size: 12px;
    font-weight: 600;
    color: #6b7280;
  }

  .day-menu-item {
    padding: 8px 10px;
    font-family: "Open Sans", sans-serif;
    font-size: 14px;
    color: #1f2937;
    text-align: left;
    cursor: pointer;
    background: none;
    border: none;
    border-radius: 6px;
  }

  .day-menu-item:hover {
    background: #f3f4f6;
  }

  .day-menu-separator {
    height: 1px;
    margin: 4px 6px;
    background: #e5e7eb;
  }

  .back-button .material-symbols-outlined {
    font-size: 28px;
  }

  .poi-title {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-size: 24px;
    font-weight: 500;

    &.no-subtitle {
      padding-bottom: 12px;
    }
  }

  /* The right-hand end of the type/subtype row: the marina "More details"
     menu (havens only) and the locale pill. `margin-inline-start: auto`
     pushes the pair to the row's end and is RTL-safe; it lives here rather
     than on LocalePill so the two stay together when the menu is present. */
  .poi-type-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    margin-inline-start: auto;
  }

  .poi-type {
    display: flex;
    gap: 8px;
    align-items: center;
    width: 100%;
    padding: 0 16px 8px;
    font-size: 14px;
    color: rgb(1 1 1 / 60%);
    text-transform: capitalize;
    border-bottom: 1px solid rgb(0 0 0 / 8%);
  }

  .poi-tags-row {
    width: 100%;
    padding: 8px 16px;
  }

  .location-tags {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
  }

  .location-tag {
    display: inline-flex;
    padding: 3px 10px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    color: #fff;
    text-transform: none;
    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
    border: 1px solid #b45309;
    border-radius: 10px;
  }
}

.panel-body {
  flex-grow: 1;
  overflow: auto;

  .poi-additional-info {
    position: relative;
    font-family: "Open Sans", sans-serif;
  }

  .poi-about {
    box-sizing: border-box;
    width: 100%;
    padding: 12px 16px;
    font-family: "Open Sans", sans-serif;
    font-size: 16px;
    line-height: 1.5;
    color: #333;
    background: white;

    img {
      max-width: 100%;
      height: auto;
    }

    :global(img) {
      max-width: 100%;
      height: auto;
    }

    iframe {
      width: 100%;
      height: auto;
      aspect-ratio: 16 / 9;
    }

    :global(iframe) {
      width: 100%;
      height: auto;
      aspect-ratio: 16 / 9;
    }

    /* R29 — content links in this sanitized-HTML field get the a-normal
       treatment (blue-600, underlined) via CSS rather than a literal class:
       {@html} output has no template to add `a-normal` to, unlike the
       template-owned links in PoiContactDetails.svelte. Excludes the
       linkifyPhonesInHtml WhatsApp/dial pair (`.about-phone-wa` /
       `.about-phone-tel`), which keeps its own bespoke styling per R29.
       `!important` on colour guards against authored About HTML pinning its
       own inline anchor colour — the same problem the dark-mode rules below
       already have to fight. */
    a:not(.about-phone-wa, .about-phone-tel) {
      color: #2563eb !important;
      text-decoration: underline;
    }

    .google-place-loading {
      display: flex;
      flex-direction: column;
      gap: 12px;
      align-items: center;
      justify-content: center;
      height: 200px;
      font-family: "Open Sans", sans-serif;
      color: #666;

      .spinning {
        font-size: 32px;
        animation: spin 1s linear infinite;
      }
    }
  }

  .google-place-inline {
    flex: 1;
    overflow: auto;
    background: white;

    gmp-place-details {
      display: block;
      width: 100%;
      min-height: 400px;
    }

    .google-place-loading {
      display: flex;
      flex-direction: column;
      gap: 12px;
      align-items: center;
      justify-content: center;
      height: 200px;
      font-family: "Open Sans", sans-serif;
      color: #666;

      .spinning {
        font-size: 32px;
        animation: spin 1s linear infinite;
      }
    }
  }

  @keyframes spin {
    from {
      transform: rotate(0deg);
    }

    to {
      transform: rotate(360deg);
    }
  }
}

.google-place-view {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.google-place-floating-buttons {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 10;
  display: flex;
  gap: 8px;

  .back-button,
  .close-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    cursor: pointer;
    background: #f0f0f0;
    border: none;
    border-radius: 50%;
  }

  .add-location-button,
  .copy-url-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    cursor: pointer;
    background: #f0f0f0;
    border: none;
    border-radius: 50%;
  }
}

.google-place-body {
  flex: 1;
  height: 100%;
  overflow: auto;
  background: white;

  gmp-place-details {
    display: block;
    width: 100%;
    height: 100%;
  }

  .google-place-loading {
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: center;
    justify-content: center;
    height: 200px;
    font-family: "Open Sans", sans-serif;
    color: #666;

    .spinning {
      font-size: 32px;
      animation: spin 1s linear infinite;
    }
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* U9 — markdown view mode: a curated content page rendered inside the panel.
   Carta emits its own `.markdown-body` wrapper, whose nodes carry no Svelte
   scoping class, so these rules must live here (this file is imported, not
   compiled, and therefore unscoped) rather than in the component's \3c style>. */
.more-details-button {
  display: flex;
  gap: 2px;
  align-items: center;
  padding: 4px 6px 4px 10px;
  font-family: "Open Sans", sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: #333;
  cursor: pointer;
  background: #f0f0f0;
  border: none;
  border-radius: 16px;
}

.more-details-button:hover {
  background: #e4e4e4;
}

.more-details-button .material-symbols-outlined {
  font-size: 20px;
}

.poi-markdown {
  box-sizing: border-box;
  width: 100%;
  padding: 12px 16px;
  font-family: "Open Sans", sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: #333;
  background: white;
}

/* Carta's viewer defaults to a reading-width column; the panel is already
   narrow, so let it use the full width (the full content page does the same
   from its onMount). */
.poi-markdown .markdown-body {
  max-width: 100%;
}

.poi-markdown img {
  max-width: 100%;
  height: auto;
}

.poi-markdown iframe {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}

/* R29 — same a-normal-via-CSS treatment as `.poi-about a` above, for the
   Carta-rendered curated markdown page (also runtime HTML with no template
   to add `a-normal` to). No phone-pair exclusion needed here: linkifyPhones
   only runs on the About field, never on markdown content. */
.poi-markdown a {
  color: #2563eb !important;
  text-decoration: underline;
}

.markdown-notice {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  justify-content: center;
  padding: 48px 16px;
  color: #666;
  text-align: center;
}

.markdown-notice .material-symbols-outlined {
  font-size: 32px;
}

.markdown-retry {
  padding: 6px 16px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: #333;
  cursor: pointer;
  background: #f0f0f0;
  border: none;
  border-radius: 16px;
}

.markdown-shimmer {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0;
}

.markdown-shimmer .shimmer {
  background: linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%);
  background-size: 200% 100%;
  border-radius: 4px;
  animation: shimmer 1.5s infinite;
}

.markdown-shimmer .md-title {
  width: 60%;
  height: 24px;
}

.markdown-shimmer .md-line {
  width: 100%;
  height: 14px;
}

.markdown-shimmer .md-line.short {
  width: 70%;
}

@keyframes shimmer {
  0% {
    background-position: 200% 0;
  }

  100% {
    background-position: -200% 0;
  }
}

/* Dark-mode rules live inside InfoPanel.svelte's \3c style> block (:global()
   fully reaches the Svelte compiler there). */

  /* Coordinate mode — an arbitrary map position picked while editing. */
  .coordinate-latlng.svelte-1rw9vfk {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
  }

  /* The coordinates line every POI's details carry, under the type row.
     The horizontal padding matches .poi-title-row's 16px so the line
     starts where the name starts. */
  .poi-coords.svelte-1rw9vfk {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 0 16px;
    margin-top: 2px;
    font-size: 12px;
    color: #888;
  }

  .coords-copy-button.svelte-1rw9vfk {
    display: inline-flex;
    align-items: center;
    padding: 0;
    color: inherit;
    background: none;
    border: none;
    cursor: pointer;
  }

  .coords-copy-button.svelte-1rw9vfk:hover {
    color: #333;
  }

  .coords-copy-button.svelte-1rw9vfk .material-symbols-outlined:where(.svelte-1rw9vfk) {
    font-size: 14px;
  }
  /* Dark mode (class-based — :global(html.dark) ...) lives in the Svelte
     \3c style> block so the compiler processes :global() reliably. */
  html.dark .poi-header,
  html.dark .poi-header .close-button,
  html.dark .poi-header .edit-location-button,
  html.dark .poi-header .report-button {
    color: #f3f4f6;
  }
  html.dark .poi-header .close-button {
    background: #374151;
  }
  html.dark .poi-header .draft-tag {
    color: #fbbf24;
    background: #422006;
    border-color: #b45309;
  }
  html.dark .poi-header .poi-type {
    color: rgb(243 244 246 / 75%);
    border-bottom-color: rgb(255 255 255 / 10%);
  }
  /* Item 16: phone numbers detected in the about prose render with the Phone
     affordance (WhatsApp launch + dial link), inline within the sentence. */
  .poi-about .about-phone {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    vertical-align: baseline;
    white-space: nowrap;
  }
  .poi-about .about-phone-wa {
    display: inline-flex;
    align-items: center;
    line-height: 0;
  }
  .poi-about .about-phone-wa img {
    width: 16px;
    height: 16px;
  }
  html.dark .panel-body .poi-about {
    color: #f3f4f6;
    background: #1f2937;
  }
  /* Per-line white backgrounds and per-span black text colours
     occasionally creep into POI descriptions (e.g. the Salamis Battle
     entry stored HTML where the editor pinned `color: #000` and a
     white background on each line). Force every descendant to honour
     the panel's dark surface so the text doesn't end up as black on
     white ribbons. */
  html.dark .panel-body .poi-about * {
    background-color: transparent !important;
    color: #f3f4f6 !important;
  }
  /* R29 — content links get the a-normal dark colour (#60a5fa, matching
     `.a-normal`'s `dark:text-blue-400`), not the `#93c5fd` this rule used to
     apply to every link in the field. The linkifyPhonesInHtml WhatsApp/dial
     pair (`.about-phone-wa` / `.about-phone-tel`) is excluded here so the
     dedicated rule below — its own bespoke `#93c5fd`, unchanged — keeps
     winning for those two anchors specifically. */
  html.dark .panel-body .poi-about a:not(.about-phone-wa, .about-phone-tel),
  html.dark .panel-body .poi-about a:not(.about-phone-wa, .about-phone-tel):visited {
    color: #60a5fa !important;
  }
  /* The phone pair's pre-existing bespoke dark-mode colour, unchanged by
     R29 — narrowed off the rule above so it doesn't compete with the
     a-normal treatment now given to the field's other links. */
  html.dark .panel-body .poi-about a.about-phone-wa,
  html.dark .panel-body .poi-about a.about-phone-wa:visited,
  html.dark .panel-body .poi-about a.about-phone-tel,
  html.dark .panel-body .poi-about a.about-phone-tel:visited {
    color: #93c5fd !important;
  }
  html.dark .panel-body .poi-about .google-place-loading,
  html.dark .panel-body .google-place-inline .google-place-loading {
    color: #9ca3af;
  }
  html.dark .panel-body .google-place-inline {
    background: #1f2937;
  }
  /* The <gmp-place-details> Google web component renders inside its own
     shadow DOM and ships a light-only stylesheet, so it punches a white
     rectangle into the otherwise-dark panel. CSS-invert the embed (and
     re-rotate the hue) so it reads as dark while keeping its colours
     roughly the same. Photos rendered inside the embed get their hue
     inverted too — acceptable trade-off until Google ships a dark theme
     for the component. */
  html.dark .google-place-inline gmp-place-details,
  html.dark .google-place-body gmp-place-details {
    filter: invert(1) hue-rotate(180deg);
    background: transparent;
  }
  html.dark .google-place-inline gmp-place-details img,
  html.dark .google-place-body gmp-place-details img {
    /* Cancel out the parent invert/hue-rotate on photos so they render
       with their original colours. */
    filter: invert(1) hue-rotate(180deg);
  }
  html.dark .google-place-floating-buttons .back-button,
  html.dark .google-place-floating-buttons .close-button,
  html.dark .google-place-floating-buttons .add-location-button,
  html.dark .google-place-floating-buttons .copy-url-button {
    color: #f3f4f6;
    background: #374151;
  }
  html.dark .google-place-body {
    background: #1f2937;
  }
  html.dark .google-place-body .google-place-loading {
    color: #9ca3af;
  }
  /* U9 — markdown view mode. Same treatment, and same reason, as `.poi-about`
     above: authored content routinely carries per-line white backgrounds and
     pinned `color: #000`, which render as black-on-white ribbons across a dark
     panel. Force every descendant onto the panel's dark surface. Carta's own
     `.markdown-body` nodes are inside {@html} output, so all of this has to be
     `:global()`. */
  html.dark .poi-header .more-details-button {
    color: #f3f4f6;
    background: #374151;
  }
  html.dark .poi-header .more-details-button:hover {
    background: #4b5563;
  }
  html.dark .panel-body .poi-markdown {
    color: #f3f4f6;
    background: #1f2937;
  }
  html.dark .panel-body .poi-markdown * {
    background-color: transparent !important;
    color: #f3f4f6 !important;
  }
  /* R29 — a-normal dark colour (#60a5fa), replacing the ad-hoc #93c5fd.
     No phone-pair exclusion needed: linkifyPhones never runs on markdown
     content, only on the About field (see the .poi-about rule above). */
  html.dark .panel-body .poi-markdown a,
  html.dark .panel-body .poi-markdown a:visited {
    color: #60a5fa !important;
  }
  /* Code blocks and quotes need a surface, which the blanket `transparent`
     above strips; give them a dark one back. */
  html.dark .panel-body .poi-markdown pre,
  html.dark .panel-body .poi-markdown code {
    background-color: #111827 !important;
  }
  html.dark .panel-body .poi-markdown blockquote {
    border-left-color: #4b5563;
  }
  html.dark .panel-body .markdown-notice,
  html.dark .panel-body .markdown-notice * {
    color: #9ca3af !important;
  }
  html.dark .panel-body .markdown-retry {
    color: #f3f4f6 !important;
    background: #374151 !important;
  }
  html.dark .panel-body .markdown-shimmer .shimmer {
    background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%) !important;
    background-size: 200% 100%;
  }

  html.dark .day-menu.svelte-1rw9vfk {
    background: #1f2937;
    border-color: #374151;
  }
  html.dark .day-menu-title.svelte-1rw9vfk {
    /* Lighter than #9ca3af to clear WCAG AA (4.5:1) on the #1f2937 menu bg. */
    color: #cbd5e1;
  }
  html.dark .day-menu-item.svelte-1rw9vfk {
    color: #f3f4f6;
  }
  html.dark .day-menu-item.svelte-1rw9vfk:hover {
    background: #374151;
  }
  html.dark .day-menu-separator.svelte-1rw9vfk {
    background: #374151;
  }


  .shimmer-wrapper.svelte-1tm4o7z {
    position: relative;
    overflow: hidden;
    background-color: #e0e0e0;
    height:150px;
  }

  .shimmer.svelte-1tm4o7z {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(
      to right,
      transparent 0%,
      rgba(255, 255, 255, 0.6) 50%,
      transparent 100%
    );
    animation: svelte-1tm4o7z-shimmer 1.5s infinite;
  }

  @keyframes svelte-1tm4o7z-shimmer {
    0% {
      transform: translateX(-100%);
    }
    100% {
      transform: translateX(100%);
    }
  }

  html.dark .shimmer-wrapper.svelte-1tm4o7z {
    background-color: #374151;
  }
  html.dark .shimmer.svelte-1tm4o7z {
    background: linear-gradient(
      to right,
      transparent 0%,
      rgba(255, 255, 255, 0.08) 50%,
      transparent 100%
    );
  }


  .itineraries-grid.svelte-1444lfa {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: 150px;
    gap: 16px;
  }

  .itinerary-item-shimmer.svelte-1444lfa {
    width: 100%;
    height: 150px;
    position: relative;
  }

  .itinerary-item-shimmer.svelte-1444lfa .shimmer-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    border-radius: 8px;
  }


  .details-header.svelte-tarnde {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    gap: 16px;
  }

  .itinerary-title-container.svelte-tarnde {
    flex: 1;
    min-width: 0;
  }

  .itinerary-actions.svelte-tarnde {
    display: flex;
    gap: 8px;
  }

  .itinerary-separator.svelte-tarnde {
    height: 1px;
    background-color: #cacaca;
  }

  .itinerary-panel-body.svelte-tarnde {
    padding: 20px;
  }

  .itinerary-steps.svelte-tarnde {
    padding: 0 24px;
  }

  .step-shimmer.svelte-tarnde {
    display: flex;
    min-height: 120px;
    padding: 12px 0;
  }

  .step-shimmer.svelte-tarnde:last-child .step-line:where(.svelte-tarnde) {
    display: none;
  }

  .step-icon-container.svelte-tarnde {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-right: 8px;
  }

  .step-line.svelte-tarnde {
    width: 2px;
    background-color: #e0e0e0;
    flex-grow: 1;
    margin-top: 8px;
  }

  .step-content.svelte-tarnde {
    flex-grow: 1;
    padding-top: 12px;
  }

  .shimmer.svelte-tarnde {
    background: linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%);
    background-size: 200% 100%;
    animation: svelte-tarnde-shimmer 1.5s infinite;
    border-radius: 4px;
  }

  .shimmer.title.svelte-tarnde {
    height: 24px;
    width: 60%;
    margin-bottom: 8px;
  }

  .shimmer.subtitle.svelte-tarnde {
    height: 14px;
    width: 80px;
  }

  .shimmer.icon-button.svelte-tarnde {
    width: 32px;
    height: 32px;
    border-radius: 50%;
  }

  .shimmer.step-icon.svelte-tarnde {
    width: 48px;
    height: 48px;
    border-radius: 50%;
  }

  .shimmer.step-title.svelte-tarnde {
    height: 18px;
    width: 50%;
    margin-bottom: 12px;
  }

  .shimmer.step-text.svelte-tarnde {
    height: 14px;
    width: 100%;
    margin-bottom: 8px;
  }

  .shimmer.step-text.short.svelte-tarnde {
    width: 70%;
  }

  @keyframes svelte-tarnde-shimmer {
    0% {
      background-position: 200% 0;
    }
    100% {
      background-position: -200% 0;
    }
  }

  html.dark .itinerary-separator.svelte-tarnde {
    background-color: #374151;
  }
  html.dark .step-line.svelte-tarnde {
    background-color: #374151;
  }
  html.dark .shimmer.svelte-tarnde {
    background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%);
    background-size: 200% 100%;
  }


  /* Inherits styles from ItineraryPanel.css */
  .proposal-alert.svelte-1nwng5r {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 16px;
    margin: 12px 0;
    border-radius: 12px;
    animation: svelte-1nwng5r-slideDown 0.3s ease-out;
  }

  .proposal-alert.svelte-1nwng5r .material-symbols-outlined:where(.svelte-1nwng5r) {
    font-size: 24px;
    color: #2196f3;
  }

  .proposal-content.svelte-1nwng5r {
    flex: 1;
  }

  .proposal-card-content.svelte-1nwng5r {
    margin-bottom: 8px;
    font-size: 14px;
    color: #333;
  }

  .proposal-actions.svelte-1nwng5r {
    display: flex;
    gap: 8px;
  }

  .proposal-actions.svelte-1nwng5r button:where(.svelte-1nwng5r) {
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    border-radius: 6px;
    transition: opacity 0.2s;
  }

  .proposal-actions.svelte-1nwng5r button:where(.svelte-1nwng5r):hover {
    opacity: 0.8;
  }

  .accept-button.svelte-1nwng5r {
    color: white;
    background-color: #2196f3;
    border: none;
  }

  .ignore-button.svelte-1nwng5r {
    color: #666;
    background-color: transparent;
    border: 1px solid #ccc;
  }

  .extra-button.svelte-1nwng5r {
    color: #999;
    background-color: transparent;
    border: 1px solid #ddd;
  }

  .reorder-proposal.svelte-1nwng5r {
    border: 1px solid #2196f3;
  }

  .warning-proposal.svelte-1nwng5r {
    border: 1px solid #ff9800;
  }

  .warning-proposal.svelte-1nwng5r .material-symbols-outlined:where(.svelte-1nwng5r) {
    color: #ff9800;
  }

  .warning-proposal.svelte-1nwng5r .accept-button:where(.svelte-1nwng5r) {
    background-color: #ff9800;
  }

  .proposal-alert.compact.svelte-1nwng5r {
    padding: 8px 12px;
    margin: 4px 0 4px 42px;
    font-size: 13px;
    background-color: rgb(33 150 243 / 5%);
    border-style: dashed;
    box-shadow: none;

    .material-symbols-outlined:where(.svelte-1nwng5r) {
      font-size: 20px;
    }

    .proposal-card-content:where(.svelte-1nwng5r) {
      margin-bottom: 4px;
    }

    .proposal-actions:where(.svelte-1nwng5r) button:where(.svelte-1nwng5r) {
      padding: 4px 8px;
      font-size: 12px;
    }
  }

  .proposal-alert.compact.warning-proposal.svelte-1nwng5r {
    background-color: rgb(255 152 0 / 5%);
  }

  .insert-proposal.svelte-1nwng5r {
    background-color: rgb(255 183 77 / 20%);
    border: 1px solid #ffb74d;
  }

  .insert-proposal.svelte-1nwng5r .material-symbols-outlined:where(.svelte-1nwng5r) {
    color: #f57c00;
  }

  .insert-proposal.svelte-1nwng5r .accept-button:where(.svelte-1nwng5r) {
    background-color: #f57c00;
  }

  .proposal-alert.compact.insert-proposal.svelte-1nwng5r {
    background-color: rgb(255 183 77 / 15%);
  }

  @keyframes svelte-1nwng5r-slideDown {
    from {
      opacity: 0;
      transform: translateY(-10px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  /* Class-based dark mode (html.dark). The proposal alert lives inside
     the InfoPanel/ItineraryPanel surface, so all the dim grays here need
     light replacements. The brand blue / amber accents stay. */
  html.dark .proposal-card-content.svelte-1nwng5r {
    color: #f3f4f6;
  }
  html.dark .ignore-button.svelte-1nwng5r {
    color: #d1d5db;
    border-color: #4b5563;
  }
  html.dark .extra-button.svelte-1nwng5r {
    color: #9ca3af;
    border-color: #4b5563;
  }


  .day-date-calendar.svelte-12p3lq2 {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 30;
    width: 232px;
    padding: 0.5rem;
    font-size: 0.8125rem;
    color: #1f2937;
    cursor: default;
    background: #ffffff;
    border: 1px solid var(--color-slate-300, #cbd5e1);
    border-radius: 0.5rem;
    box-shadow: 0 8px 24px rgb(15 23 42 / 18%);
  }

  /* Anchored mode: escape the day group's / panel's overflow clipping. */
  .day-date-calendar.anchored.svelte-12p3lq2 {
    position: fixed;
    z-index: 1200;
  }
  .ddc-header.svelte-12p3lq2 {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.25rem;
  }
  .ddc-title.svelte-12p3lq2 {
    font-weight: 600;
  }
  .ddc-nav.svelte-12p3lq2 {
    background: none;
    border: none;
    padding: 0.125rem;
    cursor: pointer;
    color: inherit;
    border-radius: 0.25rem;
    display: inline-flex;
  }
  .ddc-nav.svelte-12p3lq2:hover {
    background: rgba(100, 116, 139, 0.15);
  }
  .ddc-nav.svelte-12p3lq2 .material-symbols-outlined:where(.svelte-12p3lq2) {
    font-size: 18px;
  }
  .ddc-grid.svelte-12p3lq2 {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
  }
  .ddc-weekday.svelte-12p3lq2 {
    text-align: center;
    font-size: 0.6875rem;
    color: #64748b;
    padding: 0.125rem 0;
  }
  .ddc-day.svelte-12p3lq2 {
    background: none;
    border: none;
    font: inherit;
    color: inherit;
    text-align: center;
    padding: 0.2rem 0;
    border-radius: 0.25rem;
    cursor: pointer;
  }
  .ddc-day.svelte-12p3lq2:hover {
    background: rgba(100, 116, 139, 0.15);
  }
  .ddc-day.selected.svelte-12p3lq2 {
    background: #0e7490;
    color: #ffffff;
    font-weight: 600;
  }
  .ddc-blank.svelte-12p3lq2 {
    cursor: default;
    pointer-events: none;
  }

  html.dark .day-date-calendar.svelte-12p3lq2 {
    background: #1f2937;
    border-color: #4b5563;
    color: #f3f4f6;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  }
  html.dark .ddc-weekday.svelte-12p3lq2 {
    color: #9ca3af;
  }
  html.dark .ddc-nav.svelte-12p3lq2:hover,
  html.dark .ddc-day.svelte-12p3lq2:hover {
    background: rgba(148, 163, 184, 0.2);
  }
  html.dark .ddc-day.selected.svelte-12p3lq2 {
    background: #22d3ee;
    color: #0f172a;
  }


  /* The menu's LOOK is the app's, not this component's: every `.share-menu-*`
     rule below the container lives in
     routes/[[t=t]]/(unlogged)/map/ItineraryPanel.css, which that panel
     @imports into a global sheet. Re-declaring them here would silently WIN
     (a Svelte-scoped selector outranks the plain global one) and restyle a
     shipped menu for no reason. So this block carries only what the global
     sheet has no rule for. */

  /* Anchored INSIDE the tile so the dropdown cannot be half-cut at the bottom
     edge of the scrolling list. `position: relative` is also in the global
     sheet; the inline-flex is what keeps the trigger sized to its icon when
     the menu sits in a tile's control cluster rather than a toolbar. */
  .share-menu-container.svelte-y3lorf {
    display: inline-flex;
  }

  /* Row 3: a status, not a button — so it gets the item's layout without the
     button affordances. */
  .share-menu-status.svelte-y3lorf {
    display: flex;
    gap: 12px;
    align-items: center;
    width: 100%;
    padding: 14px 16px;
    font-size: 14px;
    font-weight: 500;
    cursor: default;
    opacity: 0.75;
  }

  /* Per-itinerary failure copy. Inline rather than a toast: a toast is global
     state, and the whole point of U17 is that one tile's failure must not
     appear to belong to another's menu. */
  .share-menu-error.svelte-y3lorf {
    padding: 4px 16px 8px;
    color: #ef4444;
    font-size: 13px;
  }

  /* U18's touch-target floor, additive over the global padding. */
  .share-menu-item.svelte-y3lorf,
  .share-menu-toggle-item.svelte-y3lorf {
    min-height: 44px;
  }


  .weather-section.svelte-x97k5r {
    background: var(--color-slate-50, #f8fafc);
    border: 1px solid var(--color-slate-200, #e2e8f0);
    border-radius: 0.5rem;
    margin-bottom: 0.5rem;
    overflow: visible; /* allow popover to escape */
  }

  html.dark .weather-section.svelte-x97k5r {
    background: var(--color-slate-800, #1e293b);
    border-color: var(--color-slate-700, #334155);
  }

  .weather-section-summary.svelte-x97k5r {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    cursor: pointer;
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-slate-700, #334155);
    user-select: none;
  }

  /* The disclosure toggle — a real <button> so it is keyboard-reachable and
     carries aria-expanded. Reset to render exactly like the bare chevron
     span it replaced. align-self: flex-start so it stays on the title row
     when the legend wraps to a second line. */
  .weather-toggle.svelte-x97k5r {
    display: flex;
    flex-shrink: 0;
    align-self: flex-start;
    padding: 0;
    margin: 0;
    cursor: pointer;
    background: none;
    border: none;
  }

  /* Chevron rotates 90° when open. */
  .weather-chevron.svelte-x97k5r {
    font-size: 18px;
    color: var(--color-slate-400, #94a3b8);
    transition: transform 0.2s ease;
  }

  .weather-section.weather-open.svelte-x97k5r > .weather-section-summary:where(.svelte-x97k5r) .weather-chevron:where(.svelte-x97k5r) {
    transform: rotate(90deg);
  }

  .weather-summary-content.svelte-x97k5r {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
    flex: 1;
    min-width: 0;
  }

  .weather-title.svelte-x97k5r {
    font-weight: 600;
    color: var(--color-slate-700, #334155);
  }

  html.dark .weather-title.svelte-x97k5r {
    color: var(--color-slate-100, #f1f5f9);
  }

  .weather-historical-badge.svelte-x97k5r {
    font-size: 0.6875rem;
    color: var(--color-amber-700, #b45309);
    background: var(--color-amber-50, #fffbeb);
    border: 1px solid var(--color-amber-200, #fde68a);
    border-radius: 0.25rem;
    padding: 0 0.25rem;
  }

  .weather-shimmer-title.svelte-x97k5r {
    display: inline-block;
    height: 1rem;
    width: 7rem;
    border-radius: 0.25rem;
    background: var(--color-slate-200, #e2e8f0);
    opacity: 0.6;
    animation: svelte-x97k5r-pulse 1.5s ease-in-out infinite;
    vertical-align: middle;
  }

  @keyframes svelte-x97k5r-pulse {
    0%, 100% { opacity: 0.6; }
    50% { opacity: 0.3; }
  }

  /* ── Info icon + popover ── */

  .weather-info-anchor.svelte-x97k5r {
    position: relative;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    margin-inline-start: auto;
    align-self: flex-end;
    cursor: pointer;
  }

  .weather-info-anchor.svelte-x97k5r:focus {
    outline: none;
  }

  .weather-info-icon.svelte-x97k5r {
    font-size: 16px;
    color: var(--color-slate-400, #94a3b8);
    transition: color 0.15s;
  }

  .weather-info-anchor.svelte-x97k5r:hover .weather-info-icon:where(.svelte-x97k5r),
  .weather-info-anchor.svelte-x97k5r:focus-visible .weather-info-icon:where(.svelte-x97k5r) {
    color: var(--color-slate-600, #475569);
  }

  .weather-info-popover.svelte-x97k5r {
    position: absolute;
    top: calc(100% + 6px);
    inset-inline-end: 0;
    z-index: 50;
    width: 300px;
    background: white;
    border: 1px solid var(--color-slate-200, #e2e8f0);
    border-radius: 0.5rem;
    box-shadow: 0 4px 16px rgb(0 0 0 / 12%);
    padding: 0.625rem 0.75rem 0.625rem 0.75rem;
  }

  html.dark .weather-info-popover.svelte-x97k5r {
    background: var(--color-slate-800, #1e293b);
    border-color: var(--color-slate-600, #475569);
    box-shadow: 0 4px 16px rgb(0 0 0 / 40%);
  }

  .weather-info-close.svelte-x97k5r {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--color-slate-400, #94a3b8);
    padding: 0;
  }

  .weather-info-close.svelte-x97k5r .material-symbols-outlined:where(.svelte-x97k5r) {
    font-size: 14px;
  }

  .weather-info-close.svelte-x97k5r:hover {
    color: var(--color-slate-600, #475569);
  }

  .weather-info-text.svelte-x97k5r {
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--color-slate-600, #475569);
    padding-right: 1rem; /* space for × button */
  }

  .weather-info-text.svelte-x97k5r + .weather-info-text:where(.svelte-x97k5r) {
    margin-top: 0.6rem;
  }

  html.dark .weather-info-text.svelte-x97k5r {
    color: var(--color-slate-300, #cbd5e1);
  }

  /* ── Body ── */

  .weather-body.svelte-x97k5r {
    padding: 0.125rem 0.75rem 0.5rem;
  }

  /* Collapsed: hide the region (was <details>'s native behavior). Kept in
     the DOM so aria-controls always resolves and weather stays warm. */
  .weather-section.svelte-x97k5r:not(.weather-open) > .weather-body:where(.svelte-x97k5r) {
    display: none;
  }

  .weather-lines.svelte-x97k5r {
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--color-slate-600, #475569);
  }

  html.dark .weather-lines.svelte-x97k5r {
    color: var(--color-slate-300, #cbd5e1);
  }

  /* ── Legend ── */

  .weather-legend.svelte-x97k5r {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
    margin-inline-start: auto;
  }

  /* When the section is collapsed, render the legend as icon-only pills
     (no "Wind kts" / "Waves m/s" text) so the title row stays compact
     while still cueing the colour vocabulary. */
  .weather-section.svelte-x97k5r:not(.weather-open) > .weather-section-summary:where(.svelte-x97k5r) .legend-label:where(.svelte-x97k5r) {
    display: none;
  }

  .weather-legend-pill.svelte-x97k5r {
    font-size: 0.6875rem;
    padding: 0.0625rem 0.375rem;
  }

  .legend-icon.svelte-x97k5r {
    font-size: 11px;
    display: inline-block;
    line-height: 1;
    vertical-align: middle;
    margin-right: 0.125rem;
  }

  /* ── Lines ── */

  /* Stack of rows. Each row is its own flex container so it can carry a
     background tint (set from the per-block score). The row separator
     and inline padding live on .weather-row. */
  .weather-lines.svelte-x97k5r {
    display: flex;
    flex-direction: column;
  }

  .weather-row.svelte-x97k5r {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.5rem;
    padding: 0.375rem 0.5rem;
    border-radius: 0.375rem;
  }
  .weather-row.svelte-x97k5r + .weather-row:where(.svelte-x97k5r) {
    margin-top: 0.125rem;
    border-top: 1px solid var(--color-slate-200, #e2e8f0);
  }
  /* Tinted rows don't get the inter-row separator line — the tint already
     defines the row boundary visually. */
  .weather-row--low.svelte-x97k5r + .weather-row:where(.svelte-x97k5r),
  .weather-row.svelte-x97k5r + .weather-row--low:where(.svelte-x97k5r),
  .weather-row--very-low.svelte-x97k5r + .weather-row:where(.svelte-x97k5r),
  .weather-row.svelte-x97k5r + .weather-row--very-low:where(.svelte-x97k5r) {
    border-top: none;
  }

  html.dark .weather-row.svelte-x97k5r + .weather-row:where(.svelte-x97k5r) {
    border-top-color: var(--color-slate-700, #334155);
  }

  /* Per-block score tint. Score < 0.65 → light pink; < 0.5 → stronger pink. */
  .weather-row--low.svelte-x97k5r {
    background: #ffeef3; /* very pale rose-pink */
  }
  .weather-row--very-low.svelte-x97k5r {
    background: #fecdd3; /* rose-200 */
    color: #881337; /* rose-900 — strong contrast on the saturated pink */
  }
  html.dark .weather-row--low.svelte-x97k5r {
    background: rgba(244, 63, 94, 0.10);
  }
  html.dark .weather-row--very-low.svelte-x97k5r {
    background: rgba(244, 63, 94, 0.24);
    color: #fecdd3; /* rose-200 — strong contrast on the dark-rose backdrop */
  }

  .weather-sentence.svelte-x97k5r {
    flex: 1 1 0;
    min-width: 0;
  }

  .weather-pills.svelte-x97k5r {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 0.25rem;
    margin-inline-start: auto;
  }

  /* ── Pills ── */

  .weather-pill.svelte-x97k5r {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    padding: 0 0.375rem;
    border-radius: 9999px;
    border: 1px solid var(--color-slate-200, #e2e8f0);
    background: var(--color-slate-50, #f8fafc);
    font-size: 0.75rem;
    font-weight: 500;
    white-space: nowrap;
    line-height: 1.5;
    vertical-align: middle;
    flex-shrink: 0;
  }

  html.dark .weather-pill.svelte-x97k5r {
    border-color: var(--color-slate-600, #475569);
    background: var(--color-slate-800, #1e293b);
    color: var(--color-slate-300, #cbd5e1);
  }

  .wind-pill.svelte-x97k5r {
    color: var(--color-sky-700, #0369a1);
    border-color: var(--color-sky-200, #bae6fd);
    background: var(--color-sky-50, #f0f9ff);
  }

  html.dark .wind-pill.svelte-x97k5r {
    color: var(--color-sky-300, #7dd3fc);
    border-color: var(--color-sky-700, #0369a1);
    background: var(--color-sky-950, #082f49);
  }

  .wave-pill.svelte-x97k5r {
    color: var(--color-teal-700, #0f766e);
    border-color: var(--color-teal-200, #99f6e4);
    background: var(--color-teal-50, #f0fdfa);
  }

  html.dark .wave-pill.svelte-x97k5r {
    color: var(--color-teal-300, #5eead4);
    border-color: var(--color-teal-700, #0f766e);
    background: var(--color-teal-950, #042f2e);
  }

  .wind-arrow.svelte-x97k5r,
  .wave-arrow.svelte-x97k5r {
    font-size: 12px;
    display: inline-block;
    line-height: 1;
    vertical-align: middle;
  }

  .wave-icon.svelte-x97k5r {
    font-size: 12px;
    display: inline-block;
    line-height: 1;
    vertical-align: middle;
  }

  .weather-unavailable.svelte-x97k5r {
    font-size: 0.875rem;
    color: var(--color-slate-400, #94a3b8);
    margin: 0;
  }

  /* Align the Suggest-alternatives button to the inline-end of the card
     (right in LTR, left in RTL). Direction is read from the body content
     via the dir attribute on this row, so an English-locale card aligns
     right and a Hebrew/Arabic card aligns left. */
  .weather-suggest-alts-row.svelte-x97k5r {
    text-align: end;
  }

  .weather-suggest-alts-btn.svelte-x97k5r {
    display: inline-block;
    margin-top: 0.5rem;
    padding: 0.25rem 0.75rem;
    background: #fecdd3; /* rose-200 — matches .weather-row--very-low */
    border: 1px solid #fda4af; /* rose-300 — slight outline for definition */
    border-radius: 1rem;
    font-size: 0.8125rem;
    color: #881337; /* rose-900 — matches .weather-row--very-low text */
    cursor: pointer;
    transition: background 0.15s ease;
  }

  .weather-suggest-alts-btn.svelte-x97k5r:hover {
    background: #fda4af; /* rose-300 */
  }

  html.dark .weather-suggest-alts-btn.svelte-x97k5r {
    background: rgba(244, 63, 94, 0.24);
    border-color: rgba(244, 63, 94, 0.40);
    color: #fecdd3; /* rose-200 */
  }
  html.dark .weather-suggest-alts-btn.svelte-x97k5r:hover {
    background: rgba(244, 63, 94, 0.36);
  }

.itinerary-panel-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background-color: white;
}

.itinerary-panel-header {
  display: flex;
  flex-shrink: 0;
  gap: 6px;
  align-items: center;
  justify-content: space-between;
  padding: 10px;
}

.itinerary-title {
  min-width: 0;
  overflow: hidden;
  font-size: 18px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.itinerary-actions-wrapper {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-end;
}

.itinerary-actions {
  display: flex;
  gap: 8px;
}

.itinerary-undo-redo {
  display: flex;
  gap: 8px;
}

/* When the undo/redo group rides the length-line row (item 12 layout):
   - reset the icon color so it doesn't inherit the row's muted 60%-black text;
   - the 16px inline-start margin (matching the header's column gap) pushes the
     locale pill 16px left so its right edge lines up with the title field's
     right edge, while the group itself stays aligned under Discard/Done.

   U19 (R26) added the cover-picture button to this group as its FIRST child,
   which is what puts it between the locale control and undo. The group is now
   three buttons wide, so it starts 32px further left; nothing here needed to
   change for that (the auto-margin on the pill absorbs it), but the row is the
   first thing to check if the header ever starts wrapping on a narrow panel. */
.itinerary-total-distance .itinerary-undo-redo {
  margin-inline-start: 16px;
  color: rgb(0 0 0 / 87%);
}

/* U19 (R27) — the inline discard failure, under the action buttons it belongs
   to. `.itinerary-actions-wrapper` is a right-aligned column, so this sits
   directly beneath Discard/Done; `text-align: end` keeps a wrapped second line
   ragged on the same side. */
.itinerary-discard-error {
  max-width: 220px;
  font-size: 12px;
  line-height: 1.3;
  color: #c62828;
  text-align: end;
}

.itinerary-button {
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  background-color: #f0f0f0;
  border: none;
  border-radius: 20px;
  transition: background-color 0.2s;
}

.itinerary-button:hover {
  background-color: #e0e0e0;
}

.itinerary-icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  cursor: pointer;
  background-color: #f0f0f0;
  border: none;
  border-radius: 50%;
  transition: background-color 0.2s;
}

.itinerary-icon-button:hover:not(:disabled) {
  background-color: #e0e0e0;
}

.itinerary-icon-button:disabled {
  cursor: default;
  opacity: 0.4;
}

.itinerary-icon-button.save-button {
  color: white;
  background-color: #4caf50;
}

.itinerary-icon-button.save-button:hover {
  background-color: #45a049;
}

.itinerary-icon-button .material-symbols-outlined {
  font-size: 20px;
}

.itinerary-title-container {
  flex: 1;
  min-width: 0;
}

.itinerary-total-distance {
  display: flex;
  gap: 4px;
  align-items: center;

  /* F1 — explicit `width: 100%` so the flex row fills its grid cell
     (`.details-header { grid-template-columns: minmax(0, 1fr) auto }`).
     Without it the row collapsed to content width and the LocalePill's
     `margin-inline-start: auto` had no free space to consume, pinning the
     pill next to the "X days • Y nm" text instead of the row's logical-end
     edge. RTL-safe — auto-margin flips with direction. */
  width: 100%;
  font-size: 14px;
  color: rgb(1 1 1 / 60%);
}

.itinerary-close-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  cursor: pointer;
  background: #f0f0f0;
  border: none;
  border-radius: 50%;
}

.create-itinerary-row {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 8px 16px;
  cursor: pointer;
  background-color: #0369a1;
  border: none;
  border-bottom: 1px solid #075985;
}

.create-itinerary-row .create-itinerary-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 7px 20px;
  font-size: 14px;
  font-weight: 600;
  color: #0369a1;
  background-color: white;
  border-radius: 9999px;
  transition: background-color 0.15s;
}

.create-itinerary-row:hover .create-itinerary-pill {
  background-color: #e0f2fe;
}

.itinerary-separator {
  height: 1px;
  background-color: #cacaca;
}

.itinerary-panel-body {
  flex-grow: 1;
  height: 100%;
  padding: 12px;
  padding-bottom: 80px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.itineraries-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

.itinerary-item {
  position: relative;
  height: 150px;
  overflow: hidden;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: 15px;
}

/* U3 (pre-launch fixes) — like button overlay on each My-tab tile. Sits in
   the top-right corner over the cover photo; the wrapper stops click
   propagation so the underlying tile's "open details" handler doesn't fire. */
.itinerary-item-like {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  cursor: pointer;
  background: rgb(255 255 255 / 75%);
  backdrop-filter: blur(2px);
  border-radius: 999px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 15%);
}

.itinerary-item-like :global(.like-itinerary-button) {
  padding: 0;
}

.itinerary-item-like :global(.like-itinerary-button .material-symbols-outlined) {
  font-size: 22px;
}

.itinerary-item.selected {
  border-color: #007bff;

  &::before {
    position: absolute;
    inset: -2px;
    pointer-events: none;
    content: "";
    background: rgb(255 255 255 / 50%);
  }

  .itinerary-view-on-map {
  }

  .itinerary-item-title {
    color: black;
    text-shadow: none;

    .arrow-icon {
      /* visibility: visible; */
    }

    .itinerary-pill {
      color: white;
    }
  }
}

.itinerary-item.selected::after {
  position: absolute;
  inset: 0;
  pointer-events: none;
  content: "";
  background-color: rgb(0 123 255 / 10%);
  border-radius: 13px;
}

.itinerary-item.previewing {
  border-color: #7c7cbb;

  &::before {
    position: absolute;
    inset: -2px;
    pointer-events: none;
    content: "";
    background: rgb(255 255 255 / 50%);
  }

  .itinerary-item-title {
    color: black;
    text-shadow: none;

    .itinerary-pill {
      color: white;
    }
  }
}

.itinerary-item.previewing::after {
  position: absolute;
  inset: 0;
  pointer-events: none;
  content: "";
  background-color: rgb(124 124 187 / 10%);
  border-radius: 13px;
}

.itinerary-item.deselecting {
  animation: deselect 1.5s ease-out forwards;
}

.itinerary-item.deselecting::before {
  position: absolute;
  inset: -2px;
  pointer-events: none;
  content: "";
  animation: deselect-before 1.5s ease-out forwards;
}

.itinerary-item.deselecting::after {
  position: absolute;
  inset: 0;
  pointer-events: none;
  content: "";
  border-radius: 13px;
  animation: deselect-overlay 1.5s ease-out forwards;
}

@keyframes deselect {
  0% {
    border-color: #007bff;
    transform: scale(1.02);
  }

  10% {
    border-color: #007bff;
    transform: scale(1);
  }

  100% {
    border-color: transparent;
    transform: scale(1);
  }
}

@keyframes deselect-before {
  0%,
  10% {
    background: rgb(255 255 255 / 50%);
  }

  100% {
    background: transparent;
  }
}

@keyframes deselect-overlay {
  0%,
  10% {
    background-color: rgb(0 123 255 / 10%);
  }

  100% {
    background-color: transparent;
  }
}

.itinerary-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.itinerary-item-title {
  position: absolute;
  top: 10px;
  right: 10px;
  left: 10px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  padding: 5px 40px 5px 5px;
  font-size: 1.2em;
  font-weight: bold;
  color: white;
  text-shadow: 1px 1px 7px rgb(0 0 0 / 90%);
  border-radius: 5px;

  /* background: rgba(0, 0, 0, 0.5); */

  /* width: calc(100%); */
}

.itinerary-meta-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}

.itinerary-pill {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 500;
  text-shadow: none;
  background: rgb(0 0 0 / 50%);
  border-radius: 9999px;
}

.itinerary-pill .material-symbols-outlined {
  font-size: 14px;
}

/* U12 — action row hosting the fixed-function 'View on map' / 'View details'
   buttons. flex-wrap plus non-shrinking buttons make the pair wrap to a
   second line at narrow tile widths instead of shrinking below usable touch
   targets or overflowing the tile. */
.itinerary-tile-actions {
  position: absolute;
  right: 10px;
  bottom: 10px;
  left: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.itinerary-view-on-map {
  display: flex;
  flex: none;
  gap: 4px;
  align-items: center;
  min-width: 44px;
  padding: 8px;
  font-size: 14px;
  font-weight: 400;
  color: white;
  white-space: nowrap;
  background: rgb(0 0 0 / 50%);
  border-radius: 5px;
}

.itinerary-view-on-map span {
  font-size: 18px;
}

.itinerary-card-actions {
  position: absolute;
  bottom: 10px;
  left: 10px;
  display: flex;
  gap: 6px;
}

.itinerary-preview-btn,
.itinerary-add-btn {
  display: flex;
  gap: 4px;
  align-items: center;
  padding: 6px 10px;
  font-size: 13px;
  font-weight: 400;
  color: white;
  cursor: pointer;
  background: rgb(0 0 0 / 50%);
  border: none;
  border-radius: 5px;
}

.itinerary-preview-btn span,
.itinerary-add-btn span {
  font-size: 16px;
}

.itinerary-item.previewing .itinerary-preview-btn {
  background: rgb(124 124 187 / 80%);
}

.arrow-icon {
  position: absolute;
  top: 18px;
  right: 10px;
  font-size: 1em;
  font-size: 24px;
  font-weight: 400;
  color: white;
  visibility: hidden;
}

.itinerary-panel-inner {
  overflow: hidden; /* To contain the sliding panel */
}

.itinerary-list-view {
  height: 100%;
  transition: transform 0.1s ease-in-out;
  transform: translateX(0);

  &.hide {
    transition: transform 0.3s ease-in-out;
    transform: translateX(-20px);
  }
}

.itinerary-details-view {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  background-color: white;
  transition: transform 0.3s ease-in-out;
  transform: translateX(100%);
}

.itinerary-details-view.show {
  transform: translateX(0);
}

.itinerary-details-view .itinerary-panel-body {
  padding-top: 0;
}

.details-header {
  position: sticky;
  top: 0;
  z-index: 100;

  /* Override .itinerary-panel-header's flex layout in favor of grid so we can
     place A/B/C into named areas (Panel A = title-and-like, Panel B =
     total-distance, Panel C = actions-wrapper).
     F1 follow-up: stats spans both columns so the LocalePill at the end of
     the stats row (via `margin-inline-start: auto`) reaches the panel's
     right edge instead of stopping at the title-column boundary. Actions
     collapses to row 1 only — visually equivalent because the buttons were
     already top-aligned via `align-self: center` in a taller-row span. */
  display: grid;
  grid-template-areas:
    "title    actions"
    "stats    stats";
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 16px;
  align-items: center;
  background-color: white;

  /* Container-query basis for the narrow-layout switch below. CSS cannot
     detect "exactly when A would wrap/clip" without JS — we approximate
     with a width threshold tuned to typical title widths. */
  container-type: inline-size;
}

/* The title-container is a structural wrapper around A+B in the markup. To
   let A and B participate in the .details-header grid as siblings of C
   (instead of being nested under a single grid cell), unwrap it via
   display: contents. The .itinerary-title-container rule at the top of
   this file (line 106) still applies in non-details-header contexts (e.g.
   ItineraryDetailsShimmer.svelte has its own scoped rule). */
.details-header .itinerary-title-container {
  display: contents;
}

.details-header .itinerary-title-and-like {
  grid-area: title;
  align-self: end;
}

/* Editing mode renders a contenteditable div directly inside the
   display:contents wrapper. Give it an explicit grid-area so it
   doesn't rely on auto-placement. */
.details-header .itinerary-title-input {
  grid-area: title;
  align-self: end;
}

.details-header .itinerary-total-distance {
  grid-area: stats;
  align-self: start;
}

.details-header .itinerary-actions-wrapper {
  grid-area: actions;
  align-self: center;
}

/* Narrow panel: switch to Option 2 — A spans the full first row, B and C
   share the second row (B left, C right). Threshold is empirical, not
   tied to A's actual clip; if titles regularly clip above this width,
   raise the threshold. */
@container (max-width: 380px) {
  .details-header {
    grid-template-areas:
      "title    title"
      "stats    actions";
  }

  .details-header .itinerary-actions-wrapper {
    place-self: start end;
  }
}

/* Fallback for browsers without @container support (Safari <16, Firefox <110).
   Use a viewport-width proxy (480px > 380px container to account for panel
   being narrower than the viewport). */
@supports not (container-type: inline-size) {
  @media (width <= 480px) {
    .details-header {
      grid-template-areas:
        "title    title"
        "stats    actions";
    }

    .details-header .itinerary-actions-wrapper {
      place-self: start end;
    }
  }
}

.details-header .itinerary-title {
  overflow: visible;
  text-overflow: unset;
  white-space: normal;
}

.itinerary-title-and-like {
  display: flex;
  gap: 4px;
  align-items: flex-start;
}

.itinerary-title-like {
  flex-shrink: 0;
  padding: 0;
}

.itinerary-title-like .material-symbols-outlined {
  font-size: 18px;
}

.itinerary-steps {
  padding: 0;
}

.step {
  position: relative;
  display: flex;
  align-items: flex-start;
  padding: 8px 8px 8px 0;
  margin: 0;
  cursor: pointer;
  user-select: none;
  border-radius: 12px;
}

.step.selected {
  background-color: transparent;

  .step-title-container {
    button {
      visibility: visible;
    }
  }
}

/* Always visible (it used to fade in on row hover) and a single eye icon —
   the chevron is gone. */
.step-detail-indicator {
  display: flex;
  align-items: center;
  color: #666;
  cursor: pointer;

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

  &:hover {
    color: #333;
  }
}

.step-icon-container {
  position: relative;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  align-items: center;
  align-self: stretch;
  min-width: 36px;
  margin-right: 6px;
}

.step-poi-name {
  padding-top: 4px;
  padding-bottom: 6px;
  font-size: 14px;
  font-weight: 500;
  color: #333;
}

.step-line {
  position: relative;
  flex-grow: 1;
  width: 3px;
  border-radius: 2px;

  .step-distance {
    position: absolute;
    top: 50%;
    left: 50%;
    padding: 2px 6px;
    font-size: 10px;
    color: #9e9e9e;
    background: white;
    transform: translate(-50%, -50%);
  }
}

.step-icon {
  position: relative;
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: transparent;
  border-radius: 50%;

  .material-symbols-outlined {
    font-size: 22px;
    color: inherit;
  }

  img.poi-icon {
    width: 28px;
    height: 28px;
  }
}

.step-content {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  gap: 6px;
  justify-content: center;
  min-height: 32px;
}

.step-title-container {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;

  .step-title {
    font-weight: bold;
  }

  button {
    visibility: hidden;
    background: transparent;
  }
}

.itinerary-details-view.is-editing
  .step-title-container
  span
  button.delete-button,
.itinerary-details-view.is-editing
  .step-title-container
  span
  button.edit-button {
  visibility: visible;
}

.step-poi-row {
  display: flex;
  gap: 10px;
  align-items: center;
  width: 100%;
}

.step-poi-name {
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: #333;
}

.step-actions {
  display: flex;
  gap: 4px;
  margin-left: auto;
}

.step-text {
  min-height: 18px;
  padding: 6px 10px;
  font-size: 13px;
  color: #333;
  user-select: text;
  border: 1px dashed #ccc;
  border-radius: 6px;
}

.step-text-placeholder:empty::before {
  font-style: italic;
  color: #aaa;
  content: attr(data-placeholder);
}

/* Mobile landscape - reduce bottom padding to allow scrolling to last item */
@media (height <= 500px) and (orientation: landscape) {
  .itinerary-panel-body {
    padding-bottom: 20px;
  }
}

/* In-place editor styles */
.step-text[contenteditable="true"] {
  min-height: 1.2em;
  padding: 4px;
  cursor: text;
  border: 1px dashed #ccc;
  border-radius: 4px;
  outline: none;
  transition:
    border-color 0.2s,
    background-color 0.2s;
}

.step-text[contenteditable="true"]:hover {
  background-color: #fafafa;
  border-color: #bbb;
}

.step-text[contenteditable="true"]:focus {
  background-color: white;
  border-color: #2196f3;
  box-shadow: 0 0 0 2px rgb(33 150 243 / 10%);
}

.itinerary-title-input {
  width: 100%;
  min-height: 1.2em;
  padding: 4px;
  margin: -4px;
  font-family: inherit;
  color: inherit;
  word-break: break-word;
  background: transparent;
  border: 1px dashed #ccc;
  border-radius: 4px;
  outline: none;
}

.itinerary-title-input:focus {
   background: white;
   border-color: #2196f3;
}

.drag-handle {
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 4px;
	color: #bdbdbd;
	cursor: grab;
}

.drag-handle .material-symbols-outlined {
	font-size: 20px;
}

.drop-indicator {
  position: relative;
  z-index: 10;
  height: 2px;
  margin: -1px 0;
  pointer-events: none;
  background-color: #2196f3;
}

.drop-indicator::before {
  position: absolute;
  top: 50%;
  left: 0;
  width: 6px;
  height: 6px;
  content: '';
  background-color: #2196f3;
  border-radius: 50%;
  transform: translateY(-50%);
}

.proposal-alert {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 16px;
  margin: 12px 0;
  border-radius: 12px;
  animation: slideDown 0.3s ease-out;
}

.proposal-alert .material-symbols-outlined {
  font-size: 24px;
  color: #2196f3;
}

.proposal-content {
  flex: 1;
}

.proposal-text {
  margin-bottom: 8px;
  font-size: 14px;
  color: #333;
}

.proposal-actions {
  display: flex;
  gap: 8px;
}

.proposal-actions button {
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  border-radius: 6px;
  transition: opacity 0.2s;
}

.proposal-actions button:hover {
  opacity: 0.8;
}

.accept-button {
  color: white;
  background-color: #2196f3;
  border: none;
}

.ignore-button {
  color: #666;
  background-color: transparent;
  border: 1px solid #ccc;
}

.reorder-proposal {
  border: 1px solid #2196f3;
}

.proposal-alert.compact {
  padding: 8px 12px;
  margin: 4px 0 4px 42px;
  font-size: 13px;
  background-color: rgb(33 150 243 / 5%);
  border-style: dashed;
  box-shadow: none;

  .material-symbols-outlined {
    font-size: 20px;
  }

  .proposal-card-content {
      margin-bottom: 4px;
  }

  .proposal-actions button {
      padding: 4px 8px;
      font-size: 12px;
  }
}

.step.suggested-source {
    border: 1px dashed #2196f3;
    animation: pulseSubtle 2s infinite ease-in-out;
}

.step.suggestion-highlight {
    background-color: rgb(33 150 243 / 10%);
    border: 2px dashed #2196f3;
    animation: pulseHighlight 1.5s infinite ease-in-out;
}

@keyframes pulseHighlight {
    0% { background-color: rgb(33 150 243 / 10%); }
    50% { background-color: rgb(33 150 243 / 20%); }
    100% { background-color: rgb(33 150 243 / 10%); }
}

.poi-move-suggestion-wrapper {
    margin: 4px 0 4px 42px;
}

.poi-delete-suggestion-wrapper {
    margin: 4px 0 4px 42px;
}

@keyframes pulseSubtle {
    0% { background-color: transparent; }
    50% { background-color: rgb(33 150 243 / 5%); }
    100% { background-color: transparent; }
}

.search-start-point-message {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
  margin: 16px;
  font-size: 16px;
  color: #666;
  background-color: #f5f5f5;
  border: 2px dashed #ccc;
  border-radius: 12px;
}

.search-start-point-message .material-symbols-outlined {
  font-size: 28px;
  color: #2196f3;
}

.start-at-plan-marina-link {
  padding: 0;
  font-size: inherit;
  color: #0369a1;
  text-decoration: underline;
  cursor: pointer;
  background: none;
  border: none;
}

.start-at-plan-marina-link:hover {
  color: #075985;
}

/* Nav-point start point: coordinates line + day-break affordance under the
   "Starting point selected" message. */
.start-point-coords {
  margin: -8px 16px 0;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: #666;
  text-align: center;
  letter-spacing: 0.02em;
}

.start-point-daybreak {
  display: flex;
  justify-content: center;
  margin: 8px 16px 0;
}

.start-point-daybreak-note {
  margin: 8px 16px 0;
  font-size: 13px;
  color: #666;
  text-align: center;
}

.change-start-button {
  padding: 6px 16px;
  font-size: 14px;
  color: #fff;
  cursor: pointer;
  background-color: #2196f3;
  border: none;
  border-radius: 20px;
  transition: background-color 0.2s;
}

.change-start-button:hover {
  background-color: #1976d2;
}

button.search-mode-active {
  color: white !important;
  background-color: #1565c0 !important;
  box-shadow: inset 0 2px 4px rgb(0 0 0 / 40%) !important;
  transform: scale(0.95) !important;
}

button.search-mode-active:hover {
  background-color: #1565c0 !important;
  transform: scale(0.95) !important;
}

.itinerary-day-group {
    margin: 6px 0;
    overflow: hidden;
    border: 1px solid;
    border-radius: 12px;
    box-shadow: 0 1px 3px rgb(0 0 0 / 4%);
}

.itinerary-day-header {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    padding: 12px;
    cursor: pointer;
    user-select: none;
    background-color: transparent;
}

/* The day disclosure toggle — a real <button> (keyboard + aria-expanded)
   reset to render exactly like the bare chevron span it replaced. */
.day-toggle-button {
    display: flex;
    padding: 0;
    margin: 0;
    cursor: pointer;
    background: none;
    border: none;
}

.itinerary-day-header .material-symbols-outlined {
    margin-top: 2px;
    font-size: 24px;
    color: #9e9e9e;
    transition: transform 0.2s ease;
}

.itinerary-day-group.day-open > .itinerary-day-header .material-symbols-outlined {
    transform: rotate(90deg);
}

/* Collapsed day: hide the content region (was <details>'s native behavior;
   kept in the DOM so aria-controls resolves and weather stays warm). */
.itinerary-day-group:not(.day-open) > .itinerary-day-content {
    display: none;
}

.itinerary-day-title {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 2px;
    overflow: hidden;
}

.day-number {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
}

.day-label {
    font-size: 14px;
    font-weight: 500;
    color: #333;
}

.day-label-input {
    min-width: 100px;
    padding: 2px 4px;
    margin: -2px -4px;
    cursor: text;
    border: 1px dashed transparent;
    border-radius: 4px;
    outline: none;
}

.day-label-input:hover {
    border-color: #ccc;
}

.day-label-input:focus {
    background: white;
    border-color: #666;
    border-style: solid;
}

.day-label-input:empty::before {
    color: #999;
    pointer-events: none;
    content: attr(data-placeholder);
}

.day-sail-length {
    margin-top: 2px;
    font-size: 13px;
    font-weight: 400;
    color: #757575;
    white-space: nowrap;
}

/* Same stroke as the step-tile icons (18px, #666), and the box rides the
   distance label's line so the icon centers on it (the header is
   flex-start-aligned). */
.day-delete-button {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
    margin-top: 2px;
    color: #666;
    cursor: pointer;
    background: none;
    border: none;
    border-radius: 4px;
    transition: background-color 0.2s ease;
}

.day-delete-button:hover {
    color: #f44336;
    background-color: rgb(244 67 54 / 10%);
}

/* color: inherit beats the header's own icon-color rule, so the button's
   #666 (and its red hover) actually reach the glyph. */
.day-delete-button .material-symbols-outlined {
    margin-top: 0;
    font-size: 18px;
    color: inherit;
    transform: none !important;
}

.itinerary-day-content {
    padding: 4px 8px 12px;
}

.day-dragging {
  border: 1px dashed #2196f3;
  opacity: 0.5;
}

.itinerary-days-controls {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    padding: 4px 0;
    margin-bottom: 8px;
    background: white;
}

.days-toggle-button {
    display: flex;
    gap: 4px;
    align-items: center;
    padding: 4px 10px;
    font-size: 12px;
    font-weight: 500;
    color: #666;
    cursor: pointer;
    background: #f5f5f5;
    border: 1px solid #e0e0e0;
    border-radius: 16px;
    transition: background-color 0.2s, border-color 0.2s;
}

.days-toggle-button:hover {
    color: #333;
    background: #ebebeb;
    border-color: #ccc;
}

.days-toggle-button .material-symbols-outlined {
    font-size: 16px;
}

.step-description {
    margin-top: 2px;
    font-size: 12px;
    line-height: 1.4;
    color: #757575;
}

.step-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.step-action-button {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px;
    color: #999;
    cursor: pointer;
    background: transparent;
    border: none;
    border-radius: 4px;
    transition: background-color 0.2s, color 0.2s;
}

.step-action-button:hover {
    color: #333;
    background-color: #f5f5f5;
}

.step-action-button.delete:hover {
    color: #f44336;
    background-color: #feebeb;
}

/* The delete and split icons match the eye (.step-detail-indicator): same
   #666 stroke and the same 18px size — the 24px default reads as a wider
   stroke next to it. */
.step-action-button.delete {
    color: #666;
}

.step-action-button.split-day {
    gap: 2px;
    padding: 2px 6px 2px 4px;
    color: #666;
}

.step-action-button.delete .material-symbols-outlined,
.step-action-button.split-day .material-symbols-outlined {
    font-size: 18px;
}

.split-day-label {
    font-size: 11px;
    white-space: nowrap;
}

/* Batch 7 — per-haven "Add" suggestions menu */
.haven-add-wrapper {
  position: relative;
  display: flex;
}

.step-action-button.haven-add-trigger {
  gap: 0;
  padding: 2px 2px 2px 8px;
  color: #0369a1;
}

.step-action-button.haven-add-trigger:hover {
  color: #075985;
  background-color: #e8f4fb;
}

/* Step-tile action arrangement (see stepTileLayout). One row beside a
   non-wrapping name in the order split, add, delete, eye; when the name
   needs the width the row becomes a 2×2 grid — split+eye on top,
   add+delete below — expressed purely via `order`. */
.step-actions .split-day {
  order: 1;
}

.step-actions .haven-add-wrapper {
  order: 2;
}

.step-actions .delete {
  order: 3;
}

.step-actions .step-detail-indicator {
  order: 4;
}

.step-poi-row.actions-2x2 {
  align-items: flex-start;
}

/* The name's first line centers on the first button row: stepTileLayout
   computes (row1 height − line height) / 2 as top padding, so the first
   line box's center meets the row's center and wrapped lines continue
   below. */
.step-poi-row.actions-2x2 .step-poi-name {
  padding-top: var(--step-name-align-pad, 4px);
}

.step-poi-row.actions-2x2 .step-actions {
  display: grid;
  grid-template-columns: auto auto;
  justify-items: start;
  margin-top: var(--step-actions-align-pad, 0);
}

/* Explicit cells rather than auto-flow: whichever buttons a tile has, the
   eye and delete keep the second column (centered in it, so the delete
   sits horizontally centered under the eye), split and add the first. */
.step-poi-row.actions-2x2 .step-actions .split-day {
  grid-area: 1 / 1;
}

.step-poi-row.actions-2x2 .step-actions .step-detail-indicator {
  grid-area: 1 / 2;
  justify-self: center;
}

.step-poi-row.actions-2x2 .step-actions .haven-add-wrapper {
  grid-area: 2 / 1;
}

.step-poi-row.actions-2x2 .step-actions .delete {
  grid-area: 2 / 2;
  justify-self: center;
}

.haven-add-label {
  font-size: 11px;
  white-space: nowrap;
}

.haven-add-caret {
  font-size: 18px;
}

/* Portaled to <body> (the panel's transform hijacks position:fixed), so
   these stack at root level: above the slide panel (z-index 1000), below
   full-screen modals (9999). */
.haven-add-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1100;
}

.haven-add-menu {
  position: fixed;
  z-index: 1101;
  display: flex;
  flex-direction: column;

  /* The min() keeps min-width from beating the on-screen width clamp on
     viewports narrower than 256px — CSS resolves min>max in min's favor. */
  min-width: min(240px, calc(100vw - 16px));
  max-width: 300px;
  padding: 4px 0;
  overflow-y: auto;
  background: white;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgb(0 0 0 / 15%);
}

.haven-add-section-title {
  padding: 6px 12px 2px;
  font-size: 11px;
  font-weight: 600;
  color: #888;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.haven-add-separator {
  height: 1px;
  margin: 4px 0;
  background-color: #e0e0e0;
}

.haven-add-item {
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%;
  padding: 7px 12px;
  font-size: 13px;
  color: #333;
  text-align: left;
  cursor: pointer;
  background: transparent;
  border: none;
}

.haven-add-item:hover {
  background-color: #f5f5f5;
}

/* Suggestion entry: the add button plus a trailing eye that opens the POI
   details. Two sibling buttons (a button can't nest a button) laid out as
   one visual row. */
.haven-add-row {
  display: flex;
  align-items: stretch;
}

.haven-add-row:hover {
  background-color: #f5f5f5;
}

.haven-add-row .haven-add-item {
  min-width: 0;
}

.haven-add-eye {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  padding: 0 12px 0 2px;
  color: #94a3b8;
  cursor: pointer;
  background: transparent;
  border: none;
}

.haven-add-eye:hover {
  color: #0369a1;
}

.haven-add-eye .material-symbols-outlined {
  font-size: 18px;
}

/* Suggestion rows carry the POI-type <img> icon; the set-prefs row still
   uses a font symbol, which the font-size/color serve. */
.haven-add-item-icon {
  flex-shrink: 0;
  font-size: 18px;
  color: #666;
}

img.haven-add-item-icon {
  width: 18px;
  height: 18px;
}

.haven-add-item-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.haven-add-item-dist {
  flex-shrink: 0;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: #999;
}

.haven-add-set-prefs .haven-add-item-name {
  color: #0369a1;
  white-space: normal;
}

/* This section intentionally left empty - styles consolidated above */

/* Drag and drop for day groups */
.itinerary-day-group.day-dragging {
  opacity: 0.5;
}

/* Insertion line between days during drag */
.day-drop-indicator {
  position: relative;
  z-index: 10;
  height: 2px;
  margin: -1px 0;
  pointer-events: none;
  background-color: #2196f3;
}

.day-drop-indicator::before {
  position: absolute;
  top: 50%;
  left: 0;
  width: 6px;
  height: 6px;
  content: '';
  background-color: #2196f3;
  border-radius: 50%;
  transform: translateY(-50%);
}

/* Visual feedback when day is about to expand on drag hover */
.itinerary-day-group.day-expand-pending > .itinerary-day-header {
  background-color: rgb(33 150 243 / 8%);
  transition: background-color 0.2s ease;
}

/* Diagonal cross over icon (for remove day break button) */
.icon-crossed {
  position: relative;
}

.icon-crossed::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120%;
  height: 2px;
  content: '';
  background-color: currentcolor;
  border-radius: 1px;
  transform: translate(-50%, -50%) rotate(-45deg);
}

/* Start point styling (previous day's end point shown at day start) */
.step.start-point {
  opacity: 0.6;
}

.step.start-point .step-icon-container {
  flex-direction: column-reverse;
}

.step.start-point .step-line {
  flex-grow: 0;
  height: 16px;
}

.start-point-label {
  padding: 2px 6px;
  font-size: 11px;
  color: #9e9e9e;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: #f5f5f5;
  border-radius: 4px;
}

/* Toggle between Suggested and My Itineraries */
.itinerary-mode-toggle {
  display: flex;
  gap: 2px;
  padding: 3px;
  background-color: #f0f0f0;
  border-radius: 20px;
}

.toggle-btn {
  /* Positioning context for the divider below. */
  position: relative;
  padding: 4px 8px;
  font-size: 11px;
  font-weight: 500;
  color: #666;
  cursor: pointer;
  background-color: transparent;
  border: none;
  border-radius: 16px;
  transition: all 0.2s ease;
}

/* A hairline between adjacent tabs.
   The filled pill marks the ACTIVE tab, which means it separates nothing when
   the two tabs beside each other are both inactive: "My  Shared with crew" ran
   together as one line of grey text with only a 2px gap between two labels that
   are themselves multi-word. The rule is `+ .toggle-btn`, so the first tab
   never draws one — a line at the strip's inner edge would read as a border. */
.toggle-btn + .toggle-btn::before {
  /* `left` is centred in `.itinerary-mode-toggle`'s 2px gap. */
  position: absolute;
  top: 50%;
  left: -1px;
  width: 1px;
  height: 12px;
  content: '';
  background-color: #d0d0d0;
  transform: translateY(-50%);
}

/* Suppressed on both sides of the active pill: its shape already does the
   separating there, and a line touching its rounded edge reads as a rendering
   artefact rather than a divider. */
.toggle-btn.active::before,
.toggle-btn.active + .toggle-btn::before {
  content: none;
}

.toggle-btn:hover {
  color: #333;
}

.toggle-btn.active {
  color: white;
  background-color: #2196f3;
}

/* Share Modal */
.share-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgb(0 0 0 / 50%);
}

.share-modal {
  width: 90%;
  max-width: 480px;
  background: white;
  border-radius: 16px;
  box-shadow: 0 4px 24px rgb(0 0 0 / 20%);
}

.share-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #e0e0e0;
}

.share-modal-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.share-modal-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  cursor: pointer;
  background: none;
  border: none;
  border-radius: 50%;
  transition: background-color 0.2s;
}

.share-modal-close:hover {
  background-color: #f0f0f0;
}

.share-modal-body {
  padding: 20px;
}

.share-modal-body p {
  margin: 0 0 16px;
  font-size: 14px;
  color: #666;
}

.share-url-container {
  display: flex;
  gap: 8px;
}

.share-url-input {
  flex: 1;
  padding: 10px 12px;
  font-size: 14px;
  color: #333;
  background-color: #f5f5f5;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  outline: none;
}

.share-url-input:focus {
  border-color: #2196f3;
}

.share-copy-button {
  display: flex;
  gap: 4px;
  align-items: center;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 500;
  color: white;
  cursor: pointer;
  background-color: #2196f3;
  border: none;
  border-radius: 8px;
  transition: background-color 0.2s;
}

.share-copy-button:hover {
  background-color: #1976d2;
}

.share-copy-button .material-symbols-outlined {
  font-size: 18px;
}

/* Share Menu Dropdown */
.share-menu-container {
  position: relative;
}

.share-menu-dropdown {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 100;
  min-width: 220px;
  margin-top: 8px;
  overflow: hidden;
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgb(0 0 0 / 15%);
}

.share-menu-item {
  display: flex;
  gap: 12px;
  align-items: center;
  width: 100%;
  padding: 14px 16px;
  font-size: 14px;
  font-weight: 500;
  color: #333;
  text-align: left;
  cursor: pointer;
  background: none;
  border: none;
  transition: background-color 0.2s;
}

.share-menu-item:hover {
  background-color: #f5f5f5;
}

.share-menu-item:not(:last-child) {
  border-bottom: 1px solid #e8e8e8;
}

.share-menu-item .material-symbols-outlined {
  font-size: 20px;
  color: #666;
}

.share-menu-backdrop {
  position: fixed;
  inset: 0;
  z-index: 99;
  cursor: default;
  background: transparent;
  border: none;
}

.share-menu-item:disabled {
  cursor: default;
  opacity: 0.7;
}

.share-menu-item:disabled:hover {
  background-color: transparent;
}

/* U2 (pre-launch fixes) — visible help text under the "Add to plan" label
   when the user is signed in but not authorized (not the Skipper and not
   TEAM/ADMIN). The hint sits in a column with the label. */
.share-menu-item-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
}

.share-menu-item-label {
  line-height: 1.3;
}

.share-menu-item-hint {
  font-size: 12px;
  font-weight: 400;
  line-height: 1.3;
  color: #777;
}

/* U2 — "blocked" disabled state (vs. the neutral in-flight disabled).
   Used when the user lacks permission to add the itinerary to the plan. */
.share-menu-item-blocked,
.share-menu-item-blocked:hover {
  color: #777;
  cursor: not-allowed;
  background-color: transparent;
}

.share-menu-item-blocked .material-symbols-outlined {
  color: #999;
}

.share-menu-section {
  padding: 12px 16px;
}

.share-menu-section-title {
  margin-bottom: 4px;
  font-size: 12px;
  font-weight: 600;
  color: #666;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.share-menu-section-subtitle {
  margin-bottom: 12px;
  font-size: 12px;
  line-height: 1.4;
  color: #888;
}

.share-menu-loading,
.share-menu-empty {
  padding: 8px 0;
  font-size: 13px;
  color: #888;
}

.share-menu-bookings {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 200px;
  overflow-y: auto;
}

.share-menu-booking-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 8px;
  cursor: pointer;
  border-radius: 8px;
  transition: background-color 0.15s;
}

.share-menu-booking-item:hover {
  background-color: #f5f5f5;
}

.share-menu-booking-item input[type="checkbox"] {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: #4caf50;
  cursor: pointer;
}

.share-menu-booking-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.share-menu-booking-yacht {
  overflow: hidden;
  font-size: 14px;
  font-weight: 500;
  color: #333;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.share-menu-booking-dates {
  font-size: 12px;
  color: #666;
}

.share-menu-divider {
  height: 1px;
  margin: 0;
  background-color: #e8e8e8;
}

/* Share menu toggle item (for isDemo toggle) */
.share-menu-toggle-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 8px;
  cursor: pointer;
  border-radius: 8px;
  transition: background-color 0.15s;
}

.share-menu-toggle-item:hover {
  background-color: #f5f5f5;
}

.share-menu-toggle-item input[type="checkbox"] {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: #2196f3;
  cursor: pointer;
}

.share-menu-toggle-item input[type="checkbox"]:disabled {
  cursor: wait;
  opacity: 0.5;
}

.share-menu-toggle-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.share-menu-toggle-label {
  font-size: 14px;
  font-weight: 500;
  color: #333;
}

.share-menu-toggle-description {
  font-size: 12px;
  line-height: 1.4;
  color: #666;
}

/* Itinerary item info line with source tags */
.itinerary-item-info {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

.source-tag {
  display: inline-flex;
  gap: 3px;
  align-items: center;
  padding: 2px 6px;
  font-size: 10px;
  font-weight: 600;
  text-shadow: none;
  border-radius: 10px;
}

.source-tag .material-symbols-outlined {
  font-size: 12px;
}

.source-tag.shared {
  color: white;
  background-color: rgb(33 150 243 / 90%);
}

.source-tag.booking {
  color: white;
  background-color: rgb(76 175 80 / 90%);
}

.source-tag.local {
  color: white;
  background-color: rgb(158 158 158 / 90%);
}

/* Delete button for local itineraries */
.itinerary-delete-local {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: white;
  cursor: pointer;
  background: rgb(244 67 54 / 80%);
  border: none;
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.2s, background-color 0.2s;
}

.itinerary-item:hover .itinerary-delete-local {
  opacity: 1;
}

.itinerary-delete-local:hover {
  background: rgb(244 67 54);
}

.itinerary-delete-local .material-symbols-outlined {
  font-size: 18px;
}

/* Mobile screens: panel is full-width, use larger header fonts */
@media (width <= 768px) {
  .itinerary-panel-header {
    padding: 12px 16px;
  }

  .itinerary-panel-header > .itinerary-title {
    font-size: 16px;
  }

  .toggle-btn {
    padding: 6px 12px;
    font-size: 10px;
  }

  .details-header .itinerary-title {
    font-size: 24px;
  }
}

.sailing-leg-indicator {
  display: flex;
  gap: 4px;
  align-items: center;
  padding: 0;
  margin-bottom: -6px;
  font-size: 11px;
  color: #888;
}

.sailing-leg-indicator .material-symbols-outlined {
  font-size: 14px;
}

/* Narrow portrait screens: shrink header elements further so close button stays visible */
@media (width <= 400px) and (orientation: portrait) {
  .itinerary-panel-header {
    padding: 3px 16px;
  }

  .itinerary-panel-header > .itinerary-title {
    font-size: 20px;
  }

  .toggle-btn {
    padding: 6px;
    font-size: 15px;
  }

  .details-header {
    gap: 6px;
  }

  .details-header .itinerary-title {
    font-size: 15px;
  }
}

.new-day-divider {
  display: flex;
  align-items: center;
  padding: 4px 16px;
}

.new-day-divider::before,
.new-day-divider::after {
  flex: 1;
  height: 1px;
  content: '';
  background-color: #ccc;
}

.new-day-button {
  display: flex;
  gap: 3px;
  align-items: center;
  padding: 2px 12px;
  margin: 0 8px;
  font-size: 12px;
  font-weight: 500;
  color: #666;
  white-space: nowrap;
  cursor: pointer;
  background: white;
  border: 1px solid #ccc;
  border-radius: 999px;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.new-day-button:hover {
  color: #333;
  background-color: #f5f5f5;
  border-color: #999;
}

.new-day-button .material-symbols-outlined {
  font-size: 14px;
}

  /* U15 of the 2026-08-06 batch-2 plan (R16) — the crew summary row.
     `space-between` with the counts absent leaves the button flush left, which
     is where it belongs when it is the row's only occupant; there is no
     placeholder holding its position. */
  .crew-summary-row.svelte-8ugp5f {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 12px;
    padding: 8px 12px;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    background-color: #f8fafc;
  }
  .crew-summary-counts.svelte-8ugp5f {
    font-size: 13px;
    color: #334155;
    min-width: 0;
  }
  .crew-invite-button.svelte-8ugp5f {
    display: inline-flex;
    flex-shrink: 0;
    gap: 6px;
    align-items: center;
    /* Pinned to the row's right edge even when it is the row's ONLY child.
       `space-between` on the parent puts a lone item at the START, so an
       anonymous visitor — who gets the CTA without the counts — saw the button
       jump to the left. `auto` keeps it right in both arrangements. */
    margin-left: auto;
    /* 44 px is the tap target the rest of the panel's controls hold to; the
       padding rather than a fixed height so the label can wrap on narrow
       panels without the text overflowing the box. */
    min-height: 44px;
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 500;
    color: #0369a1;
    cursor: pointer;
    background: transparent;
    border: 1px solid #bae6fd;
    border-radius: 6px;
    transition: background-color 0.15s;
  }
  .crew-invite-button.svelte-8ugp5f:hover {
    background-color: #e0f2fe;
  }
  .crew-invite-button.svelte-8ugp5f .material-symbols-outlined:where(.svelte-8ugp5f) {
    font-size: 18px;
  }
  .crew-summary-error.svelte-8ugp5f {
    margin-bottom: 12px;
    font-size: 12px;
    color: #b91c1c;
  }

  /* U16 of the 2026-08-06 batch-2 plan (R17) — the two tab names inside the
     empty state's sentence.

     A <button> rather than a styled <span>, because it does something; the
     styling is what makes a button sit inside running text without breaking
     it. `display: inline` (not inline-block) so the sentence can wrap BETWEEN
     the words of "My itineraries" the way the surrounding prose does, and the
     font is inherited so the name reads as part of the sentence rather than as
     a control dropped into it. The underline is the only affordance, which is
     the convention for an inline action in a paragraph.

     No min-height: a 44 px tap target would tear the line apart. The
     underlined text is the target, and the whole sentence sits inside a panel
     whose other controls carry the larger target. */
  .crew-empty-tab-link.svelte-8ugp5f {
    display: inline;
    padding: 0;
    font: inherit;
    color: #0369a1;
    text-decoration: underline;
    cursor: pointer;
    background: none;
    border: none;
  }
  .crew-empty-tab-link.svelte-8ugp5f:hover {
    color: #075985;
  }
  .crew-empty-tab-link.svelte-8ugp5f:focus-visible {
    outline: 2px solid #0369a1;
    outline-offset: 2px;
  }

  /* U11 — Suggestion preview overlay. Positioned absolutely over the
     details-view body so the in-edit DOM stays alive in the background.
     Distinct background tint and an "Add to itinerary" CTA (styled to
     mirror InfoPanel.svelte's `add-to-itinerary-button`). */
  .itinerary-preview-overlay.svelte-8ugp5f {
    position: absolute;
    inset: 0;
    /* Must sit ABOVE `.itinerary-details-view` (z-index: 10) — that's the
       in-edit details body the overlay is meant to cover while previewing
       a curated suggestion. The previous value (5) left the editor on top
       so the overlay rendered into the DOM but was visually obscured. */
    z-index: 20;
    display: flex;
    flex-direction: column;
    /* `min-height: 0` lets the flex container shrink to its parent's height
       instead of growing to fit its (tall) child day list. Without this the
       overlay swells past the viewport and the document scrolls — producing
       a second page-level scrollbar on multi-day previews. */
    min-height: 0;
    background: linear-gradient(180deg, #eef6fb 0%, #ffffff 80%);
    overflow: hidden;
  }
  .itinerary-preview-header.svelte-8ugp5f {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 16px 12px;
    background: #dbeafe;
    border-bottom: 1px solid #bfdbfe;
  }
  .itinerary-preview-header-text.svelte-8ugp5f {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }
  .itinerary-preview-eyebrow.svelte-8ugp5f {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #1d4ed8;
  }
  .itinerary-preview-title.svelte-8ugp5f {
    font-size: 18px;
    font-weight: 700;
    color: #111827;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .itinerary-preview-meta.svelte-8ugp5f {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 13px;
    color: #374151;
  }
  .itinerary-preview-close.svelte-8ugp5f {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    cursor: pointer;
    color: #1f2937;
    border-radius: 50%;
  }
  .itinerary-preview-close.svelte-8ugp5f:hover {
    background: rgba(0, 0, 0, 0.06);
  }
  .itinerary-preview-body.svelte-8ugp5f {
    flex: 1 1 auto;
    /* `min-height: 0` is the load-bearing fix for the double-scrollbar:
       without it a flex item grows to fit its intrinsic content (the
       day list is ~2580px on a 6-day suggestion), pushing the document
       height past the viewport. `overflow-y: auto` only takes effect
       when the box can shrink, which requires the min-height clamp. */
    min-height: 0;
    min-width: 0;
    overflow-y: auto;
    padding: 12px 16px;
  }
  /* The shared `renderItineraryDetailsBody` snippet wraps content in
     `.itinerary-panel-body` + `.itinerary-steps`, which carry editor-context
     styles (`height: 100%; overflow-y: auto; padding-bottom: 80px`) that
     fight the preview overlay's own scroll container. Inside the preview
     overlay the outer `.itinerary-preview-body` owns the scroll; the inner
     wrapper just lays out naturally. */
  .itinerary-preview-body.svelte-8ugp5f .itinerary-panel-body:where(.svelte-8ugp5f) {
    height: auto;
    flex-grow: 0;
    overflow: visible;
    padding: 0;
  }
  .itinerary-preview-cover.svelte-8ugp5f {
    width: 100%;
    border-radius: 8px;
    margin-bottom: 12px;
    object-fit: cover;
    max-height: 180px;
  }
  /* CTA row positioned directly below the blue header. flex-shrink: 0 keeps
     it pinned above the scrollable body; horizontal padding + bottom margin
     visually pair it with the header band. */
  .itinerary-preview-add-row.svelte-8ugp5f {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    padding: 12px 16px 0;
    margin-bottom: 8px;
  }
  .itinerary-preview-add-row.svelte-8ugp5f .add-to-itinerary-button:where(.svelte-8ugp5f) {
    display: flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 10px 16px;
    font-family: "Open Sans", sans-serif;
    font-size: 14px;
    font-weight: 500;
    color: white;
    cursor: pointer;
    background: #4caf50;
    border: none;
    border-radius: 8px;
    transition:
      background-color 0.2s ease,
      opacity 0.2s ease;
  }
  .itinerary-preview-add-row.svelte-8ugp5f .add-to-itinerary-button:where(.svelte-8ugp5f):hover {
    background: #388e3c;
  }
  .itinerary-preview-add-row.svelte-8ugp5f .add-to-itinerary-button[disabled]:where(.svelte-8ugp5f) {
    opacity: 0.6;
    cursor: not-allowed;
  }
  .itinerary-preview-add-row.svelte-8ugp5f .add-to-itinerary-button:where(.svelte-8ugp5f) .material-symbols-outlined:where(.svelte-8ugp5f) {
    font-size: 20px;
  }
  /* When the preview is active, prevent pointer interaction with the
     underlying details-view (overlay is opaque already, but this keeps
     focus/keyboard semantics clean). */
  .itinerary-details-view.preview-active.svelte-8ugp5f {
    pointer-events: none;
  }
  .itinerary-preview-overlay.svelte-8ugp5f,
  .itinerary-preview-overlay.svelte-8ugp5f :where(.svelte-8ugp5f) {
    pointer-events: auto;
  }
  html.dark .itinerary-preview-overlay {
    background: linear-gradient(180deg, #1e3a5f 0%, #1f2937 80%);
  }
  html.dark .itinerary-preview-header {
    background: #1e3a8a;
    border-bottom-color: #1d4ed8;
  }
  html.dark .itinerary-preview-eyebrow {
    color: #93c5fd;
  }
  html.dark .itinerary-preview-title,
  html.dark .itinerary-preview-meta {
    color: #f3f4f6;
  }
  /* My-tab tile like button — scaled to 70% so it sits unobtrusively on the
     small tile thumbnail. The wrapper still occupies its layout slot; only
     the button visual shrinks. transform-origin centers the scale on the
     wrapper's centroid. */
  .itinerary-item-like.svelte-8ugp5f .like-itinerary-button {
    transform: scale(0.7);
    transform-origin: center;
  }

  /* Dark mode (class-based — html.dark) lives here so :global() compiles. */
  html.dark .itinerary-panel-inner,
  html.dark .itinerary-panel-header,
  html.dark .itinerary-panel-body,
  html.dark .itinerary-list-view,
  html.dark .itinerary-details-view,
  html.dark .itinerary-title,
  html.dark .itinerary-item-title,
  html.dark .step-poi-name,
  html.dark .step-text,
  html.dark .details-header h2,
  html.dark .details-header h3,
  html.dark .step,
  html.dark .step-content {
    color: #f3f4f6;
  }
  /* The inner / list / body / details containers ship with hard-coded white
     backgrounds in the CSS file — override them here so the gaps between
     itinerary cards read as the dark surface, not flashes of white. */
  html.dark .itinerary-panel-inner,
  html.dark .itinerary-panel-body,
  html.dark .itinerary-list-view,
  html.dark .itinerary-details-view {
    background-color: #1f2937;
  }
  html.dark .itinerary-total-distance,
  html.dark .step-detail-indicator {
    color: #d1d5db;
  }
  html.dark .itinerary-close-button,
  html.dark .itinerary-icon-button,
  html.dark .itinerary-button {
    color: #f3f4f6;
    background-color: #374151;
    border-color: #4b5563;
  }
  html.dark .itinerary-close-button:hover,
  html.dark .itinerary-icon-button:hover,
  html.dark .itinerary-button:hover {
    background-color: #4b5563;
  }
  html.dark .itinerary-separator {
    background-color: rgb(255 255 255 / 10%);
  }
  html.dark .itinerary-item {
    color: #f3f4f6;
    background: #1f2937;
    border-color: #4b5563;
  }
  html.dark .itinerary-item:hover {
    background: #273342;
    border-color: #6b7280;
  }
  html.dark .itinerary-item.selected {
    border-color: #3b82f6;
  }
  /* U10 — the like-button pill on My-tab tiles ships with a white/75%
     background in ItineraryPanel.css; keep it a dark translucent surface in
     dark theme so the gray-300 unliked heart (and the red-400 liked heart)
     read clearly against it. */
  html.dark .itinerary-item-like {
    background: rgb(31 41 55 / 75%);
  }
  html.dark .itinerary-pill {
    color: #d1d5db;
    background: #374151;
  }
  html.dark .itinerary-view-on-map,
  html.dark .itinerary-add-btn {
    color: #f3f4f6;
    background: #374151;
    border-color: #4b5563;
  }
  html.dark .itinerary-view-on-map:hover,
  html.dark .itinerary-add-btn:hover {
    background: #4b5563;
  }
  html.dark .step-line {
    background: rgb(255 255 255 / 18%);
  }
  html.dark .itinerary-title-input {
    color: #f3f4f6;
    background: #1f2937;
    border-color: #4b5563;
  }
  html.dark .itinerary-title-input:focus {
    border-color: #3b82f6;
  }
  html.dark .new-day-button {
    color: #d1d5db;
    background: #374151;
    border-color: #4b5563;
  }
  html.dark .new-day-button:hover {
    color: #f3f4f6;
    background-color: #4b5563;
    border-color: #6b7280;
  }
  html.dark .proposal-alert,
  html.dark .reorder-proposal {
    color: #f3f4f6;
    background: #1f2937;
    border-color: #4b5563;
  }
  html.dark .ignore-button {
    color: #d1d5db;
    background: transparent;
    border-color: #4b5563;
  }
  html.dark .ignore-button:hover {
    background: #374151;
  }

  /* Suggested/My segmented toggle */
  html.dark .itinerary-mode-toggle {
    background-color: #374151;
  }
  html.dark .toggle-btn {
    color: #d1d5db;
  }
  /* Same hairline as light mode, lifted off the dark strip background. */
  html.dark .toggle-btn + .toggle-btn::before {
    background-color: #4a5568;
  }

  html.dark .toggle-btn:hover {
    color: #f3f4f6;
  }
  /* .toggle-btn.active keeps its blue accent — already legible. */

  /* "Starting from / Ending at" banners and inline change/select-point
     buttons live behind the depth-layer-fm-sky-* utilities (defined in
     packages/ui/src/app.css) which only generate a single light-mode
     background-color. Override the surfaces under html.dark so the banner
     and the in-banner pill button no longer flash bright sky-blue. */
  html.dark .depth-layer-no-hover-fm-sky-200 {
    background-color: oklch(36.59% 0.091 244.66) !important;
    color: #f3f4f6;
  }
  html.dark .depth-layer-fm-sky-100 {
    background-color: oklch(47.81% 0.124 246.36) !important;
    color: #f3f4f6;
  }

  /* Editing-view chrome */
  html.dark .details-header {
    background-color: #1f2937;
  }
  html.dark .search-start-point-message {
    color: #d1d5db;
    background-color: #374151;
    border-color: #6b7280;
  }
  html.dark .search-start-point-message .material-symbols-outlined {
    color: #60a5fa;
  }
  html.dark .itinerary-days-controls {
    background: #1f2937;
  }
  html.dark .days-toggle-button {
    color: #d1d5db;
    background: #374151;
    border-color: #4b5563;
  }
  html.dark .days-toggle-button:hover {
    color: #f3f4f6;
    background: #4b5563;
    border-color: #6b7280;
  }

  /* In-panel "Share with crew" / "Shared with crew" button.
     Two states, both in the blue palette but visually distinct so the
     user can read the attached state at a glance without parsing the
     label:
       - not attached (primary action): solid blue background + white text.
       - attached (state, "done"): blue-tinted outline button — blue border,
         pale blue background, dark blue text. Reads as a checked-off state
         rather than a CTA, without leaving the brand palette.
     Disabled state (HTML disabled + opacity-60 + cursor-not-allowed)
     applies to both the canEdit=false viewer and the in-flight state. */
  .add-to-plan-button.svelte-8ugp5f {
    color: #ffffff;
    background: #2563eb;
    border-color: #1d4ed8;
  }
  .add-to-plan-button.svelte-8ugp5f:hover:not([disabled]) {
    color: #ffffff;
    background: #1d4ed8;
    border-color: #1e40af;
  }
  .add-to-plan-button.svelte-8ugp5f .material-symbols-outlined:where(.svelte-8ugp5f) {
    color: #ffffff;
  }
  .add-to-plan-button.added.svelte-8ugp5f {
    color: #1e40af;
    background: #eff6ff;
    border-color: #2563eb;
  }
  .add-to-plan-button.added.svelte-8ugp5f:hover:not([disabled]) {
    color: #1e3a8a;
    background: #dbeafe;
    border-color: #1d4ed8;
  }
  .add-to-plan-button.added.svelte-8ugp5f .material-symbols-outlined:where(.svelte-8ugp5f) {
    color: #1d4ed8;
  }
  .add-to-plan-button[disabled].svelte-8ugp5f {
    opacity: 0.6;
    cursor: not-allowed;
  }
  html.dark .add-to-plan-button {
    color: #ffffff;
    background: #1d4ed8;
    border-color: #1e3a8a;
  }
  html.dark .add-to-plan-button:hover:not([disabled]) {
    background: #1e40af;
    border-color: #1e3a8a;
  }
  html.dark .add-to-plan-button .material-symbols-outlined {
    color: #ffffff;
  }
  html.dark .add-to-plan-button.added {
    color: #bfdbfe;
    background: #1e3a8a;
    border-color: #3b82f6;
  }
  html.dark .add-to-plan-button.added:hover:not([disabled]) {
    color: #dbeafe;
    background: #1e40af;
    border-color: #60a5fa;
  }
  html.dark .add-to-plan-button.added .material-symbols-outlined {
    color: #93c5fd;
  }
  html.dark .step-description {
    color: #d1d5db;
  }

  /* Day-row labels in the editing view: ".day-label" carries the auto
     "Relaxing at sea" / custom day title and was #333 — disappears on
     the dark blue day card. The contenteditable variants need the same
     treatment, plus a sane focus surface. */
  html.dark .day-label {
    color: #f3f4f6;
  }
  html.dark .day-label-input:hover {
    border-color: #4b5563;
  }
  html.dark .day-label-input:focus {
    color: #f3f4f6;
    background: #1f2937;
    border-color: #6b7280;
  }
  html.dark .day-label-input:empty::before {
    color: #6b7280;
  }

  /* Inline date editor inside the day-title header. Dashed underline cues
     editability without competing with the surrounding day-number colour. */
  .day-date-btn.svelte-8ugp5f {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
    text-decoration: underline dotted;
    text-underline-offset: 2px;
  }
  .day-date-btn.svelte-8ugp5f:hover {
    text-decoration: underline;
  }
  .day-date-input.svelte-8ugp5f {
    font: inherit;
    border: 1px solid var(--color-slate-300, #cbd5e1);
    border-radius: 0.25rem;
    padding: 0 0.25rem;
    color: inherit;
    background: transparent;
  }
  /* Anchor for the custom calendar dropdown; the native picker popup is
     replaced by <DayDateCalendar>, so hide the browser's own trigger icon. */
  .day-date-edit-wrap.svelte-8ugp5f {
    position: relative;
    display: inline-block;
  }
  .day-date-input.svelte-8ugp5f::-webkit-calendar-picker-indicator {
    display: none;
  }

  /* Share menu dropdown: hardcoded white background is invisible / unreadable
     in dark mode. Override with a dark surface that matches the panel palette. */
  html.dark .share-menu-dropdown {
    background-color: #374151;
    color: #f3f4f6;
  }
  html.dark .share-menu-item {
    color: #f3f4f6;
  }
  html.dark .share-menu-item:hover {
    background-color: #4b5563;
  }

  /* ── U18 (R18, R21) — the per-tile control cluster ──────────────────────── */

  /* Tiles clipped their cover photo with `overflow: hidden`, which also clips
     anything anchored INSIDE them — a share dropdown on a 150 px tile would
     have been invisible rather than merely cramped. The clip moves onto the
     image itself (13 px = the 15 px outer radius minus the 2 px border), and
     the decoration pseudo-element gets the inset the clip used to give it, so
     the tile renders as before while the menu can escape. */
  .itinerary-item.svelte-8ugp5f {
    overflow: visible;
  }

  /* Letting the menu ESCAPE the tile (above) is not the same as letting it sit
     ABOVE the next one. Tiles are siblings painted in DOM order, so a dropdown
     hanging off tile N was overlapped by tile N+1 — and the tile below is
     exactly where a 150px tile's menu opens. Raising the whole tile, not just
     the menu, keeps the cluster and its dropdown in one stacking context.
     `:has()` scopes the lift to the tile that actually has a menu open, so the
     rest of the grid keeps its natural order. */
  /* `:global()` on the dropdown half is required, not stylistic: the element is
     rendered by ShareItineraryMenu and carries ITS scope hash, so the scoped
     selector matched nothing and Svelte pruned the whole rule as unused. */
  .itinerary-item.svelte-8ugp5f:has(.share-menu-dropdown) {
    z-index: 20;
  }

  .itinerary-item.svelte-8ugp5f img:where(.svelte-8ugp5f) {
    border-radius: 13px;
  }

  .itinerary-item.svelte-8ugp5f::before {
    inset: 0;
    border-radius: 13px;
  }

  /* Two controls at the tile's trailing edge, like then share. 44 px targets
     with an 8 px gap: mis-hitting like and getting share opens a full-viewport
     backdrop menu, which is a far more disruptive slip than the reverse.
     z-index clears the title block, which is also absolutely positioned. */
  .itinerary-tile-controls.svelte-8ugp5f {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 3;
    display: flex;
    /* A COLUMN down the tile's right edge, like on top. Side by side, the pair
       ate horizontal room the title needs — "Port of Lavrio → Plaia Epidavrou"
       ran under them — and stacking gives each control the tile's full right
       margin instead of half of it. Like stays first in the DOM, so column
       order and reading order agree without an `order` override. */
    flex-direction: column;
    gap: 8px;
    align-items: center;
  }

  /* The like chip keeps its global look (translucent disc, 22 px heart) and
     loses only the absolute positioning it needed while it was the tile's one
     control. Sized to the same 44 px floor as its neighbour. */
  .itinerary-tile-controls.svelte-8ugp5f .itinerary-item-like:where(.svelte-8ugp5f) {
    position: static;
    width: 44px;
    height: 44px;
  }

  .itinerary-tile-share.svelte-8ugp5f {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    color: #1f2937;
    cursor: pointer;
    background: rgb(255 255 255 / 75%);
    backdrop-filter: blur(2px);
    border: none;
    border-radius: 999px;
    box-shadow: 0 1px 3px rgb(0 0 0 / 15%);
  }

  .itinerary-tile-share.svelte-8ugp5f .material-symbols-outlined:where(.svelte-8ugp5f) {
    font-size: 22px;
  }


  .unit-selector.svelte-1bu9hkj {
    display: flex;
    color: white;
    margin-left: 5px;
    font-family: 'Open Sans', sans-serif;
    font-size: 14px;
    gap: 3px;
  }
  .unit-selector.svelte-1bu9hkj span:where(.svelte-1bu9hkj) {
    padding: 2px 5px;
    cursor: pointer;
    border-radius: 3px;
    opacity: 0.8;
    background: #a9a9a9;
    color: black;
  }
  .unit-selector.svelte-1bu9hkj span.selected:where(.svelte-1bu9hkj) {
    background-color: #007cbf;
    color: white;
  }
  .distance-display-container.svelte-1bu9hkj {
    position: absolute;
    transform: translateX(-50%);
    z-index: 1001;
    pointer-events: auto;
    transition: top 0.2s ease;
  }

  .distance-input-wrapper.svelte-1bu9hkj {
    display: flex;
    align-items: center;
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 5px;
    padding: 5px 10px;
  }

  .distance-display.svelte-1bu9hkj {
    background-color: transparent;
    color: white;
    font-family: 'Open Sans', sans-serif;
    font-size: 14px;
    border: none;
    text-align: right;
  }

  /* Hide arrows from number input */
  .distance-display.svelte-1bu9hkj::-webkit-inner-spin-button,
  .distance-display.svelte-1bu9hkj::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  .distance-display.svelte-1bu9hkj {
    -moz-appearance: textfield;
  }


  @keyframes svelte-7ooc5l-spin {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }

  .spin.svelte-7ooc5l {
    animation: svelte-7ooc5l-spin 1s linear infinite;
  }

  .map-control-button.svelte-7ooc5l {
    position: relative;
    padding: 10px;
    background-color: #fff;
    color: rgba(0, 0, 0, 0.7);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    width: 40px;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    transition: background-color 0.3s ease;
  }

  .map-control-button.is-on.svelte-7ooc5l {
    background-color: #e0e0e0;
  }

    .map-control-button.svelte-7ooc5l:hover {
        background-color: #f5f5f5;
    }

    .map-control-button.is-on.svelte-7ooc5l:hover {
        background-color: #d0d0d0;
    }

  /* U8 — "my menu is open", keyed off `aria-expanded="true"` and NOT off
     `.is-on`: on the layers button `.is-on` still means "satellite showing",
     so the two must be able to hold independently — grey fill without the
     ring (satellite, menu closed), ring on white (roadmap, menu open), both.
     A ring rather than a fill so it composes with `.is-on`'s fill instead of
     replacing it. 2.5px of the brand green, the same ring
     `MfmControlButton.is-on` wears, because MfmMenu's `beside-*` caret is
     drawn in that colour and sized to start where a 2.5px ring ends. Declared
     before the accent block so an accent button's own ring (same specificity,
     later in source) is untouched. */
  .map-control-button.is-open.svelte-7ooc5l {
    box-shadow:
      0 0 0 2.5px #2bbe4a,
      0 2px 6px rgba(0, 0, 0, 0.16);
  }

  .badge.svelte-7ooc5l {
    position: absolute;
    left: 28px;
        bottom: 28px;
    width: 12px;
    height: 12px;
    background-color: #d32f2f;
    border-radius: 50%;
  }

  /* "Ring + glow" accent — itinerary entry-point button.
     Default fills the pill with the same brand green as the ring (the
     glyph is white). When pressed (`:active`) or while the panel is
     open (`.is-on`), the pill flips to a white background with the
     green ring preserved and the glyph in brand green. */
  .map-control-button.accent-ring-glow.svelte-7ooc5l {
    background-color: #2bbe4a;
    color: #fff;
    box-shadow:
      0 0 0 2.5px #2bbe4a,
      0 0 0 6px rgba(43, 190, 74, 0.18),
      0 2px 6px rgba(0, 0, 0, 0.12);
    transition: background-color 0.3s ease, color 0.3s ease, box-shadow 0.2s ease, transform 0.1s ease;
  }
  .map-control-button.accent-ring-glow.svelte-7ooc5l:hover {
    background-color: #2bbe4a;
    color: #fff;
    box-shadow:
      0 0 0 2.5px #2bbe4a,
      0 0 0 6px rgba(43, 190, 74, 0.30),
      0 2px 6px rgba(0, 0, 0, 0.12);
  }
  .map-control-button.accent-ring-glow.svelte-7ooc5l:active,
  .map-control-button.accent-ring-glow.is-on.svelte-7ooc5l,
  .map-control-button.accent-ring-glow.is-on.svelte-7ooc5l:hover {
    background-color: #fff;
    color: #18a33a;
    box-shadow:
      0 0 0 2.5px #2bbe4a,
      0 0 0 6px rgba(43, 190, 74, 0.18),
      0 2px 6px rgba(0, 0, 0, 0.12);
  }
  .map-control-button.accent-ring-glow.svelte-7ooc5l:active {
    transform: scale(0.96);
  }

  html.dark {
    .map-control-button.svelte-7ooc5l {
      background-color: #1f2937;
      color: #f3f4f6;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
    }
    .map-control-button.is-on.svelte-7ooc5l {
      background-color: #4b5563;
    }
    .map-control-button.svelte-7ooc5l:hover {
      background-color: #374151;
    }
    .map-control-button.is-on.svelte-7ooc5l:hover {
      background-color: #6b7280;
    }
    /* Same lighter green MfmControlButton's dark `.is-on` ring and MfmMenu's
       dark caret use, so the ring and its caret still read as one shape. */
    .map-control-button.is-open.svelte-7ooc5l {
      box-shadow:
        0 0 0 2.5px #35d357,
        0 2px 6px rgba(0, 0, 0, 0.5);
    }
    /* Dark basemaps need a slightly stronger glow alpha for legibility,
       per the spec's "Edge Cases" note. Default keeps the green fill so
       the button reads as a primary action; pressed/open flips to white
       with the green ring still doing the work. */
    .map-control-button.accent-ring-glow.svelte-7ooc5l {
      background-color: #2bbe4a;
      color: #fff;
      box-shadow:
        0 0 0 2.5px #2bbe4a,
        0 0 0 6px rgba(43, 190, 74, 0.28),
        0 2px 6px rgba(0, 0, 0, 0.4);
    }
    .map-control-button.accent-ring-glow.svelte-7ooc5l:hover {
      background-color: #2bbe4a;
      color: #fff;
      box-shadow:
        0 0 0 2.5px #2bbe4a,
        0 0 0 6px rgba(43, 190, 74, 0.38),
        0 2px 6px rgba(0, 0, 0, 0.4);
    }
    .map-control-button.accent-ring-glow.svelte-7ooc5l:active,
    .map-control-button.accent-ring-glow.is-on.svelte-7ooc5l,
    .map-control-button.accent-ring-glow.is-on.svelte-7ooc5l:hover {
      background-color: #fff;
      color: #18a33a;
      box-shadow:
        0 0 0 2.5px #2bbe4a,
        0 0 0 6px rgba(43, 190, 74, 0.28),
        0 2px 6px rgba(0, 0, 0, 0.4);
    }
  }


  .map-controls-container.svelte-1p5tydi {
    position: absolute;
    right: 10px;
    /* The collide-anyway default for the compact rule below, which is the only
       one low enough to meet the weather datetime bar — the 180px resting
       position already clears it. `weatherClearanceStyle` overrides this inline
       with 0px once the bar provably cannot reach this cluster. Declared here
       rather than on `.compact` so both live in one place. */
    --weather-clearance: var(--weather-overlay-h, 0px);
    /* 180px clears Google's own Street View and Camera controls, which are
       pinned to this same corner (MapComponent's `mapOptions`, RIGHT_BOTTOM).
       Measured: camera tops out 148px above the map's bottom edge, so this
       leaves 32px. Both this cluster and those two controls changed corners
       together precisely so this relationship — and this number — did not have
       to change. */
    bottom: 180px;
    /* Item 6 — was `1`, which trapped this whole stacking context BELOW
       `.weatherSliderOverlay` (z-index 5). FilterMenu's inner `z-[1000]` could
       never escape it, so the filter menu painted under the weather datetime
       bar. Lifting the container lifts the menu with it.

       6, not something larger: the AI bottom sheet lives at z-aibar (1300) and
       must stay above the map chrome. Anything >= 1300 here would put the map
       tools over the sheet. */
    z-index: 6;
    display: flex;
    flex-direction: column;
    gap: 33px;
    transition: transform 0.3s ease-in-out, bottom 0.3s ease-in-out, right 0.3s ease-in-out;
  }

  .edit-locations-wrapper.svelte-1p5tydi {
    position: relative;
  }

  /* U3 — `display: flex`, not the default block: MfmMenu's root is
     `inline-flex`, and an inline-level box inside a block wrapper sits on a
     line box whose strut can add a few px of slack under the 40px button.
     The column's height arithmetic (`mapToolsButtonCount` /
     `TOOLS_BUTTON_HEIGHT` in mfmClusterLayout.ts) assumes exactly 40px per
     button, so the slack would move the shared reflow threshold. A flex
     wrapper blockifies the root and the row stays 40px. */
  .maptype-toggle-wrapper.svelte-1p5tydi {
    position: relative;
    display: flex;
  }

  /* A3/U8 — MapControlButton's own circle is 40px (below the WCAG 2.5.5 /
     Apple HIG 44px touch-target floor MfmControlButton already holds itself
     to elsewhere in this chrome). Rather than resizing the shared component
     — which would also grow "Measure distance" and "Edit Locations" and
     change the 33px-gap column arithmetic `mapToolsButtonCount`/
     `TOOLS_BUTTON_HEIGHT` in mfmClusterLayout.ts pin — this expands only the
     new button's HIT area via an absolutely-positioned pseudo-element, the
     same technique MapComponent.svelte's `.weatherOverlayClose::after` uses.
     40px + 2×2px inset = 44px, with no added box in the flex column. */
  .maptype-toggle-wrapper .map-control-button::after {
    content: '';
    position: absolute;
    inset: -2px;
  }

  /* Opens LEFTWARD, toward the viewport interior — this cluster is bottom-right.
     The offset is the button's 40px plus a 10px gap. */
  .edit-locations-menu.svelte-1p5tydi {
    position: absolute;
    right: 50px;
    top: 0;
    background: white;
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    min-width: 180px;
    overflow: hidden;
    z-index: 10;
  }

  .edit-locations-menu-item.svelte-1p5tydi {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 16px;
    border: none;
    background: white;
    cursor: pointer;
    font-size: 14px;
    color: #333;
    text-align: left;
    transition: background-color 0.15s;
  }

  .edit-locations-menu-item.svelte-1p5tydi:hover:not(:disabled) {
    background: #f5f5f5;
  }

  .edit-locations-menu-item.svelte-1p5tydi:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .edit-locations-menu-item.svelte-1p5tydi:not(:last-child) {
    border-bottom: 1px solid #eee;
  }

  .edit-locations-menu-item.svelte-1p5tydi .material-symbols-outlined:where(.svelte-1p5tydi) {
    font-size: 20px;
    color: #666;
  }

  /* Dynamic panel-aware positioning is handled via inline style.
     The transition ensures smooth movement when panel resizes. */

  /* U1 (plan 2026-05-27-001) — numbered search-results panel.
     Anchored to the same left-edge column as the floating map controls,
     but sits above them so the buttons remain reachable. The badge uses the
     same #1a73e8 accent the FilterMenu uses for the active search-results
     state (≥4.5:1 contrast with white text per WCAG 2.1 AA). */
  .search-results-panel.svelte-1p5tydi {
    position: absolute;
    left: 10px;
    /* A2/U1: was a flat 60px, tuned to sit below Google's Map/Satellite
       toggle — which U1 turns off (`mapTypeControl: false`), making that
       number arbitrary. The panel now clears the overlay chrome's band
       instead, reading the ONE declaration of its height from
       MapChrome.svelte so the two cannot drift; the literal fallback keeps
       the panel correct if the chrome is ever absent. */
    top: calc(var(--map-chrome-h, 60px) + 10px);
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-width: 240px;
    max-height: calc(100vh - 200px);
    padding: 6px;
    background: rgba(255, 255, 255, 0.96);
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    overflow: hidden;
  }

  html.dark .search-results-panel.svelte-1p5tydi {
    background: rgba(31, 41, 55, 0.96);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
  }

  .search-results-header.svelte-1p5tydi {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 4px 6px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    flex: 0 0 auto;
  }

  html.dark .search-results-header.svelte-1p5tydi {
    border-bottom-color: rgba(255, 255, 255, 0.08);
  }

  .search-results-title.svelte-1p5tydi {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 11px;
    font-weight: 500;
    color: #6b7280;
    line-height: 1.2;
    letter-spacing: 0.02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  html.dark .search-results-title.svelte-1p5tydi {
    color: #9ca3af;
  }

  .search-results-list.svelte-1p5tydi {
    display: flex;
    flex-direction: column;
    gap: 6px;
    overflow-y: auto;
    overflow-x: hidden;
    padding-top: 4px;
    min-height: 0;
  }

  /* Close × — sits in the header so it stays put while the list scrolls. */
  .search-results-close.svelte-1p5tydi {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.04);
    color: #6b7280;
    cursor: pointer;
    flex: 0 0 auto;
    transition: background-color 0.15s, color 0.15s;
  }

  .search-results-close.svelte-1p5tydi .material-symbols-outlined:where(.svelte-1p5tydi) {
    font-size: 16px;
    line-height: 1;
  }

  .search-results-close.svelte-1p5tydi:hover {
    background: rgba(0, 0, 0, 0.10);
    color: #111827;
  }

  .search-results-close.svelte-1p5tydi:focus-visible {
    outline: 2px solid #1a73e8;
    outline-offset: 1px;
  }

  html.dark .search-results-close.svelte-1p5tydi {
    background: rgba(255, 255, 255, 0.08);
    color: #d1d5db;
  }

  html.dark .search-results-close.svelte-1p5tydi:hover {
    background: rgba(255, 255, 255, 0.16);
    color: #f9fafb;
  }

  .search-result-item.svelte-1p5tydi {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: 32px;
    padding: 4px 8px;
    border: none;
    background: transparent;
    cursor: pointer;
    text-align: left;
    border-radius: 6px;
    transition: background-color 0.15s;
  }

  .search-result-item.svelte-1p5tydi:hover {
    background: #f5f5f5;
  }

  html.dark .search-result-item.svelte-1p5tydi:hover {
    background: #374151;
  }

  .search-result-item.svelte-1p5tydi:focus-visible {
    outline: 2px solid #1a73e8;
    outline-offset: 1px;
  }

  .search-result-badge.svelte-1p5tydi {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 4px;
    border-radius: 11px;
    background: #1a73e8;
    color: #ffffff;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    /* Contrast: #ffffff on #1a73e8 ≈ 4.86:1, passes WCAG AA for small text. */
  }

  /* Featured (recommended) rows get a warmer accent to match the
     marker layer's gold "Crown of Waves" glow. */
  .search-result-item.featured.svelte-1p5tydi .search-result-badge:where(.svelte-1p5tydi) {
    background: #b8860b;
    /* #ffffff on #b8860b ≈ 4.51:1, passes WCAG AA. */
  }

  .search-result-label.svelte-1p5tydi {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13px;
    line-height: 1.2;
    color: #333;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  html.dark .search-result-label.svelte-1p5tydi {
    color: #f3f4f6;
  }

  /* Compact (mobile / short viewports): keep the panel anchored at the
     top-left, below the overlay chrome, but cap height tighter so the
     content below stays visible. Same offset as the base rule — the chrome
     band does not change height with the cluster's compact mode. */
  .search-results-panel.compact.svelte-1p5tydi {
    left: 10px;
    top: calc(var(--map-chrome-h, 60px) + 10px);
    max-width: calc(100vw - 20px);
    max-height: 50vh;
  }

  /* Compact tightens the spacing and drops the cluster toward the corner. It
     keeps the base `flex-direction: column` — a portrait phone is narrow, not
     short, and the row it used to get here spent width it did not have.

     The clearance var rides on top so the column clears the weather datetime
     bar, which at this width really does span under it. 0 when the bar is
     absent or provably out of reach, so the resting position is the 35px base. */
  .map-controls-container.compact.svelte-1p5tydi {
    bottom: max(35px, calc(35px + var(--weather-clearance, 0px) + var(--ai-bar-bottom-h, 0px)));
    right: 10px;
    gap: 20px;
  }

  /* Genuinely SHORT viewports (landscape phone) still reflow to a row, which is
     the case the row was introduced for: four buttons stacked do not fit above
     the fold.

     Plain `row`, not row-reverse: the rule is "whichever child sits at the
     bottom of the column sits nearest the corner in the row", and that child is
     the last one. Right-anchored, last-last means NOT reversing. The mfm cluster
     takes the opposite value for exactly the same reason. */
  .map-controls-container.compact.short.svelte-1p5tydi {
    flex-direction: row;
  }

  /* In the compact ROW the menu cannot open sideways — there is no room beside
     the button — so it goes straight up instead.

     Aligned LEFT here, the mirror of the base rule's `right`. The row is
     right-anchored and this button is its first child, so it sits at the row's
     LEFT end: growing the menu rightward keeps it inside the row's own
     footprint, while `right: 0` would push it further left than the row itself
     reaches and off a narrow viewport. */
  .map-controls-container.compact.short.svelte-1p5tydi .edit-locations-menu:where(.svelte-1p5tydi) {
    left: 0;
    right: auto;
    top: auto;
    bottom: 50px;
  }

  /* Class-based dark mode toggled by $lib/utils/theme.ts on <html class="dark">. */
  html.dark .edit-locations-menu.svelte-1p5tydi {
    background: #1f2937;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
  }
  html.dark .edit-locations-menu-item.svelte-1p5tydi {
    background: #1f2937;
    color: #f3f4f6;
  }
  html.dark .edit-locations-menu-item.svelte-1p5tydi:hover:not(:disabled) {
    background: #374151;
  }
  html.dark .edit-locations-menu-item.svelte-1p5tydi:not(:last-child) {
    border-bottom-color: #374151;
  }
  html.dark .edit-locations-menu-item.svelte-1p5tydi .material-symbols-outlined:where(.svelte-1p5tydi) {
    color: #d1d5db;
  }


  @keyframes svelte-1j4lisl-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }

  .spin.svelte-1j4lisl {
    animation: svelte-1j4lisl-spin 1s linear infinite;
  }

  .mfm-control-button.svelte-1j4lisl {
    position: relative;
    padding: 8px 12px;
    background-color: #2bbe4a;
    color: #fff;
    border: 0;
    /* A pill, not a circle — the silhouette IS the distinguishing signal. */
    border-radius: 12px;
    cursor: pointer;
    min-width: 48px;
    /* 44px is the WCAG 2.5.5 / Apple HIG minimum touch target, and this
       cluster is used one-handed on a moving boat — the case that most
       deserves the full target. Was 40px. */
    height: 44px;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    transition: background-color 0.2s ease, box-shadow 0.2s ease, transform 0.1s ease;
  }

  .mfm-control-button.svelte-1j4lisl:hover {
    background-color: #23a83f;
  }

  /* Open/active: invert to a white pill with the green ring preserved, the same
     "pressed" language the itinerary button's accent already uses, so the two
     read as one family once U7 moves it in here. */
  .mfm-control-button.is-on.svelte-1j4lisl,
  .mfm-control-button.is-on.svelte-1j4lisl:hover {
    background-color: #fff;
    color: #18a33a;
    box-shadow:
      0 0 0 2.5px #2bbe4a,
      0 2px 6px rgba(0, 0, 0, 0.16);
  }

  .mfm-control-button.svelte-1j4lisl:active {
    transform: scale(0.96);
  }

  .mfm-control-button.svelte-1j4lisl:focus-visible {
    outline: 2px solid #18a33a;
    outline-offset: 2px;
  }

  .badge.svelte-1j4lisl {
    position: absolute;
    top: -3px;
    right: -3px;
    width: 12px;
    height: 12px;
    background-color: #d32f2f;
    border: 2px solid #fff;
    border-radius: 50%;
  }

  html.dark {
    .mfm-control-button.svelte-1j4lisl {
      background-color: #2bbe4a;
      color: #fff;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
    }
    .mfm-control-button.svelte-1j4lisl:hover {
      background-color: #35d357;
    }
    /* Dark basemaps: keep the inverted state light enough to stay legible
       against a dark tile, and thicken the ring slightly for contrast. */
    .mfm-control-button.is-on.svelte-1j4lisl,
    .mfm-control-button.is-on.svelte-1j4lisl:hover {
      background-color: #f3f4f6;
      color: #157f2e;
      box-shadow:
        0 0 0 2.5px #35d357,
        0 2px 6px rgba(0, 0, 0, 0.5);
    }
    .badge.svelte-1j4lisl {
      border-color: #1f2937;
    }
  }


  /* Ties the popover to the button that opened it, matching MfmMenu's caret so
     the whole cluster reads the same way — including its direction: the base
     sits on the BUTTON and the apex meets this panel, so the taper names the
     source. `bottom` is set inline because it tracks the trigger while the
     panel itself may have been shifted down.

     9.5px = the 12px gap between the trigger and this menu, less the 2.5px
     `.is-on` ring MfmControlButton spreads outside the pill. Same derivation as
     `--mfm-caret-width` in MfmMenu.svelte, written out because this caret is
     positioned against a flex row rather than the panel. */
  .filter-menu-caret.svelte-o361wv {
    position: absolute;
    left: -9.5px;
    width: 0;
    height: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    /* MfmControlButton's `.is-on` ring, so the caret reads as that ring growing
       a tail. Same colour pair as `.mfm-menu-caret` in MfmMenu.svelte. */
    border-left: 9.5px solid #2bbe4a;
  }

  html.dark .filter-menu-caret.svelte-o361wv {
    border-left-color: #35d357;
  }

  /* R3a's 44px tap-target minimum, carried over from the bottom-sheet B3/U10
     removed. The rows are py-2.5/text-[13px] (~38px), which is right for a
     mouse and short of the touch minimum; the sheet used to raise them via a
     `.sheet-body` wrapper that no longer exists.

     Re-scoped to the card at phone widths rather than dropped, because the
     requirement was never about the sheet — it was about fingers. Same 600px
     breakpoint the removed `isMobile` used, so the same viewports keep the same
     targets; the desktop popover's rows are untouched. Taller rows make the
     card taller, which U9's cap and this element's own `overflow-y-auto`
     already handle. */
  @media (max-width: 600px) {
    .filter-menu-card.svelte-o361wv button,
    .filter-menu-card.svelte-o361wv [role='button'],
    .filter-menu-card.svelte-o361wv input {
      min-height: 44px;
    }
    /* Icon-only controls (checkbox/chevron toggles) need the area too. */
    .filter-menu-card.svelte-o361wv button.h-6,
    .filter-menu-card.svelte-o361wv button.w-6 {
      min-width: 44px;
      min-height: 44px;
    }
  }

  /* U8 — AI-tagged pill: subtle dotted underline on the label so the
     user can distinguish "AI surfaced this for me" from "I toggled this". */
  .filter-ai-tagged.svelte-o361wv > span:where(.svelte-o361wv):last-child {
    text-decoration: underline dotted;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    text-decoration-color: rgba(26, 115, 232, 0.45);
  }

  /* U8 — Pulse on newly-activated pill (~600ms). Svelte 5 auto-scopes
     both the @keyframes name and the matching `animation:` reference
     inside this style block, keeping them in sync without a manual
     :global() wrap. */
  @keyframes svelte-o361wv-filterActivatedPulse {
    0%   { box-shadow: 0 0 0 0 rgba(26, 115, 232, 0); }
    50%  { box-shadow: 0 0 0 4px rgba(26, 115, 232, 0.35); }
    100% { box-shadow: 0 0 0 0 rgba(26, 115, 232, 0); }
  }

  @media (prefers-reduced-motion: no-preference) {
    .filter-just-activated.svelte-o361wv {
      animation: svelte-o361wv-filterActivatedPulse 600ms ease-out;
    }
  }


  .mfm-controls-container.svelte-rpbn0u {
    position: absolute;
    left: 10px;
    /* This cluster owns the bottom-LEFT corner. Do NOT copy the map tools'
       180px resting height: that number exists to clear Google's native Street
       View and Camera controls, which are stacked under the map tools in
       whichever corner those two share (the bottom-RIGHT one, since the swap).
       This corner has nothing beneath it, so 40px clears the attribution strip
       and nothing else.

       The two vars are then added on top so the cluster never sits under the
       weather datetime bar or the expanded mobile AI sheet. Both publish 0 when
       absent, so the resting position is the 40px base.

       The AI term applies at every width — that sheet is full-bleed, so it is
       always underneath. The WEATHER term is not: `.weatherSliderOverlay` is a
       centred card, so on a wide map its near edge never reaches this cluster
       and the lift is pure dead space. Hence the indirection through
       --weather-clearance: this declaration is the collide-anyway default, and
       `weatherClearanceStyle` overrides it inline with 0px once the two
       provably cannot touch. (That predicate is side-agnostic — the bar is
       centred — so it needed no change when this cluster changed corners.) */
    --weather-clearance: var(--weather-overlay-h, 0px);
    bottom: max(40px, calc(40px + var(--weather-clearance, 0px) + var(--ai-bar-bottom-h, 0px)));
    /* U4 / item 6 — above `.weatherSliderOverlay` (z-index 5) so this cluster's
       menus and the map tools' FilterMenu both paint over the weather datetime
       bar. Deliberately NOT >= 1300: that would put it above the AI bottom
       sheet, which must stay on top of the map chrome. */
    z-index: 6;
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
    transition:
      transform 0.3s ease-in-out, bottom 0.3s ease-in-out,
      left 0.3s ease-in-out, gap 0.3s ease-in-out;
  }

  /* Compact (narrow OR short viewports): the cluster becomes a horizontal row
     anchored bottom-left while the map tools sit bottom-right.

     The two rows sit on SEPARATE vertical bands rather than sharing one. The
     plan's "meet in the middle" only works if each row fits its own half, and
     the map tools' compact row does not: five 40px buttons plus gaps is 280px,
     which already overflows half of a 390px viewport before this cluster asks
     for any width. Sharing a band would overlap them by ~90px on the most
     common phone size.

     So: 83px = the map tools' 35px base + their 40px button + an 8px gap. The
     weather/AI vars are added on top exactly as in the default layout. */
  /* The filter menu is positioned against this, not the container, so it tracks
     the button through both layouts. */
  .mfm-filter-wrapper.svelte-rpbn0u {
    position: relative;
  }

  /* ── B3/U5 + B3/U6 — the hide-gate notices (R1, R2) ───────────────────────
     Out of the flex flow in every layout (see the markup comment for the three
     reasons), stacked upward from the cluster's top edge so the pills keep
     their full touch targets and the container's measured width is unchanged.

     `max-width` rather than a fixed width: one notice is ~200px and two stack
     rather than share a line, so the cap only bites on a phone, where it makes
     the label ellipsise instead of pushing the pill past the map's edge. The
     `100vw - 20px` term is `MFM_INSET` at each side, matching `.compact`. */
  .mfm-hide-notices.svelte-rpbn0u {
    position: absolute;
    /* BESIDE the cluster, not above it. Stacked above, a notice about havens
       floated over the map with the Havens button below and to its left, and
       read as a banner about the map rather than as the label on the control
       that releases it. To the right of the column it sits alongside the pills
       it belongs to, in space that is empty map in this layout.
       `top: 0` rather than `bottom: 0`: the gated buttons (Filter, then Havens)
       are the top of the column, so the notices meet them there. */
    left: calc(100% + 8px);
    top: 0;
    /* The cluster's own vertical rhythm, restated so each notice can be placed
       on its button's centreline below. `--mfm-row-h` is MfmControlButton's box
       and `--mfm-row-gap` is this container's own `gap` — keep all three in
       step, or the notices drift off their buttons by a row. */
    --mfm-row-h: 44px;
    --mfm-row-gap: 12px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* 12px, not the cluster's 6-8px: each notice's action button expands its
       hit area 6px beyond the pill (see `::after` below), so a smaller gap
       would overlap the two buttons' targets and hand a tap to the wrong
       gate. 6 + 6 = 12 makes them abut exactly. */
    gap: 12px;
    max-width: min(320px, calc(100vw - 20px));
    /* The wrapper is only a positioning box; letting it take pointer events
       would swallow map drags in the strip above the cluster. The pills take
       theirs back. */
    pointer-events: none;
  }

  /* The retired `.mfm-haven-hint`'s treatment, revived deliberately: a
     translucent white pill over the map is what a passive notice looks like in
     this cluster, and the reason A3/U9 retired it from
     `.mfm-control-button-caption` was that a caption is not tappable while a
     white pill reads as if it were. These ARE tappable. */
  /* Each notice on its own button's CENTRELINE (column layout only).
     `--mfm-row` is the button's index down the cluster: Filter leads it, then
     Havens. Selected on the testid rather than a modifier class so this stays a
     stylesheet-only concern — the markup that renders these is shared and
     deliberately untouched.

     `top` resolves to the row's centre and `translateY(-50%)` hangs the pill on
     it, so the notice tracks the button whatever the notice's own height. The
     two rows are 56px apart and the pill is ~38px, so both can show at once
     without meeting.

     Scoped away from `.compact`: it lays the cluster out as a horizontal row,
     where a row INDEX is not a vertical offset at all and the notices keep
     their stacked-above position. */
  .mfm-controls-container.svelte-rpbn0u:not(.compact) .mfm-hide-notice:where(.svelte-rpbn0u) {
    position: absolute;
    top: calc(
      var(--mfm-row, 0) * (var(--mfm-row-h) + var(--mfm-row-gap)) + var(--mfm-row-h) / 2
    );
    transform: translateY(-50%);
    /* Taking the notices out of flow leaves the wrapper with no in-flow content,
       so it shrinks to zero width — and the pill's own `max-width: 100%` then
       resolves against zero, collapsing the label to nothing and leaving a bare
       icon and "Show again". Size to the content instead, and restate the cap
       against the VIEWPORT, which is what it was really protecting. */
    width: max-content;
    max-width: calc(100vw - var(--mfm-row-h) - 30px);
  }

  .mfm-hide-notice[data-testid='mfm-hide-notice-points'].svelte-rpbn0u { --mfm-row: 0; }
  .mfm-hide-notice[data-testid='mfm-hide-notice-havens'].svelte-rpbn0u { --mfm-row: 1; }

  .mfm-hide-notice.svelte-rpbn0u {
    display: flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    min-width: 0;
    padding: 3px 4px 3px 10px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.94);
    color: #1f2937;
    font-size: 12px;
    white-space: nowrap;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    backdrop-filter: blur(4px);
    pointer-events: auto;
  }

  /* The label is the only part that may shrink — the icon and the escape
     button are fixed-size targets, exactly as in the retired hint. */
  .mfm-hide-notice-label.svelte-rpbn0u {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .mfm-hide-notice-action.svelte-rpbn0u {
    position: relative;
    flex: none;
    display: flex;
    align-items: center;
    min-height: 32px;
    padding: 0 10px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: #1a73e8;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
  }

  /* 32px painted, 44px hit — the WCAG 2.5.5 floor every other control on this
     map holds, reached with an inset pseudo-element rather than by growing
     the pill to 44px tall (which would read as a button, not a notice).
     32 + 2*6 = 44. */
  .mfm-hide-notice-action.svelte-rpbn0u::after {
    content: '';
    position: absolute;
    inset: -6px -4px;
  }

  .mfm-hide-notice-action.svelte-rpbn0u:hover {
    background: rgba(26, 115, 232, 0.1);
  }

  .mfm-hide-notice-action.svelte-rpbn0u:focus-visible {
    outline: 2px solid #1a73e8;
    outline-offset: 1px;
  }

  html.dark .mfm-hide-notice.svelte-rpbn0u {
    background: rgba(31, 41, 55, 0.94);
    color: #f3f4f6;
  }

  html.dark .mfm-hide-notice-action.svelte-rpbn0u {
    color: #93c5fd;
  }

  html.dark .mfm-hide-notice-action.svelte-rpbn0u:hover {
    background: rgba(147, 197, 253, 0.15);
  }

  /* A3/U6 removed `.mfm-haven-hint` and its dark-theme block from here. Its
     translucent-pill-over-the-map treatment briefly lived on in
     `.mfm-control-button-caption` (MfmControlButton.svelte); A3/U9 retired
     that too — a white pill is a tappable affordance (R3) — and replaced it
     with a haloed white label. Nothing in this app carries the hint's
     treatment now. */

  /* Compact only tightens the spacing. It used to reflow to a horizontal row as
     well, which was wrong for the case that triggers it most: a portrait phone
     is NARROW, not short, and turning a 4-button column on its side there spends
     the one axis that is scarce to save the one that is not — and dropped the
     row on top of the full-width weather bar. */
  .mfm-controls-container.compact.svelte-rpbn0u {
    left: 10px;
    gap: 8px;
    max-width: calc(100vw - 20px);
  }

  /* The row layout survives for genuinely SHORT viewports (landscape phone),
     where a column of four buttons does not fit above the fold at all. `short`
     is the height half of `isCompact` split back out — the two were conflated,
     so the short-viewport remedy was being applied to narrow ones too.

     83px = the map tools' 35px base + their 40px button + an 8px gap: in this
     layout BOTH clusters are rows on the same band, so this one rides above. */
  .mfm-controls-container.compact.short.svelte-rpbn0u {
    bottom: max(
      var(--mfm-short-base, 83px),
      calc(var(--mfm-short-base, 83px) + var(--weather-clearance, 0px) + var(--ai-bar-bottom-h, 0px))
    );
    /* row-REVERSE, because this cluster is left-anchored. The rule is "whichever
       child sits at the bottom of the column sits nearest the corner in the
       row", and that child is the last one (AI). Left-anchored, last-first means
       reversing. Swapping the anchor without swapping this leaves the row
       mirrored end-for-end — which reads as nothing worse than odd button order,
       so it survives review easily. The map tools take the opposite value for
       exactly the same reason. */
    flex-direction: row-reverse;
    align-items: center;
    flex-wrap: nowrap;
  }

  /* Compact lays the cluster out as a horizontal ROW along the bottom, where
     the space to its right is the map-tools cluster, not empty map. So the
     notices keep the original position above it in that layout. */
  .mfm-controls-container.compact.svelte-rpbn0u .mfm-hide-notices:where(.svelte-rpbn0u) {
    left: 0;
    top: auto;
    bottom: calc(100% + 8px);
  }

  @media (prefers-reduced-motion: reduce) {
    .mfm-controls-container.svelte-rpbn0u {
      transition: none;
    }
  }



  .seamark-attribution.svelte-w23wtp {
    position: absolute;
    /* 76px clears the Google logo: Google draws it ~66px wide with a ~5px
       inset in the bottom-left of each layer div, and the strip wants a few
       pixels of air after it. */
    left: 76px;
    /* Inside Google's 40px strip band (the mfm cluster's clearance), lifted
       by the mobile AI sheet only — the same `--ai-bar-bottom-h` contract
       `.weatherSliderOverlay` uses. 0 when collapsed/hidden, unset on desktop
       → falls back to 0. Smooth so it follows the sheet's expand/collapse. */
    bottom: calc(8px + var(--ai-bar-bottom-h, 0px));
    transition: bottom 0.3s ease-in-out;
    /* 8px bottom + 24px max height = a 32px top edge, under the 40px band. */
    max-height: 24px;
    box-sizing: border-box;
    padding: 3px 8px;
    /* Above the layer divs (Google's `.gm-style` root opens its own stacking
       context, so nothing inside the map can climb past a later sibling);
       below the weather bar (5) and the mfm cluster (6), which never reach
       this corner anyway. */
    z-index: 1;
    font-size: 11px;
    line-height: 16px;
    white-space: nowrap;
    overflow: hidden;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.8);
    color: rgba(0, 0, 0, 0.7);
    /* The strip itself must never swallow a map drag; only the link is live. */
    pointer-events: none;
    user-select: none;
  }

  /* The card covers even the short form (phones): hang just above it. 16px is
     the card's own bottom inset (`.weatherSliderOverlay`), --weather-overlay-h
     its measured height as MapComponent publishes it on <html>, 6px the gap;
     the AI-sheet term stays so the lifted strip still rises with the sheet. */
  .seamark-attribution.is-lifted.svelte-w23wtp {
    bottom: calc(16px + var(--weather-overlay-h, 0px) + 6px + var(--ai-bar-bottom-h, 0px));
  }

  .seamark-attribution-link.svelte-w23wtp {
    pointer-events: auto;
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  .seamark-attribution-link.svelte-w23wtp:hover {
    color: #111827;
  }

  /* Follows the app's resolved theme (html.dark), the way the rest of the map
     chrome does — the same slate the map-control buttons and the weather bar
     use on dark. */
  html.dark .seamark-attribution.svelte-w23wtp {
    background: rgba(31, 41, 55, 0.85);
    color: #e5e7eb;
  }
  html.dark .seamark-attribution-link.svelte-w23wtp:hover {
    color: #ffffff;
  }

/*!
 * Quill Editor v2.0.3
 * https://quilljs.com
 * Copyright (c) 2017-2024, Slab
 * Copyright (c) 2014, Jason Chen
 * Copyright (c) 2013, salesforce.com
 */
.ql-container{box-sizing:border-box;font-family:Helvetica,Arial,sans-serif;font-size:13px;height:100%;margin:0;position:relative}.ql-container.ql-disabled .ql-tooltip{visibility:hidden}.ql-container:not(.ql-disabled) li[data-list=checked] > .ql-ui,.ql-container:not(.ql-disabled) li[data-list=unchecked] > .ql-ui{cursor:pointer}.ql-clipboard{left:-100000px;height:1px;overflow-y:hidden;position:absolute;top:50%}.ql-clipboard p{margin:0;padding:0}.ql-editor{box-sizing:border-box;counter-reset:list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;line-height:1.42;height:100%;outline:none;overflow-y:auto;padding:12px 15px;tab-size:4;-moz-tab-size:4;text-align:left;white-space:pre-wrap;word-wrap:break-word}.ql-editor > *{cursor:text}.ql-editor p,.ql-editor ol,.ql-editor pre,.ql-editor blockquote,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6{margin:0;padding:0}@supports (counter-set:none){.ql-editor p,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6{counter-set:list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor p,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6{counter-reset:list-0 list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor table{border-collapse:collapse}.ql-editor td{border:1px solid #000;padding:2px 5px}.ql-editor ol{padding-left:1.5em}.ql-editor li{list-style-type:none;padding-left:1.5em;position:relative}.ql-editor li > .ql-ui:before{display:inline-block;margin-left:-1.5em;margin-right:.3em;text-align:right;white-space:nowrap;width:1.2em}.ql-editor li[data-list=checked] > .ql-ui,.ql-editor li[data-list=unchecked] > .ql-ui{color:#777}.ql-editor li[data-list=bullet] > .ql-ui:before{content:'\2022'}.ql-editor li[data-list=checked] > .ql-ui:before{content:'\2611'}.ql-editor li[data-list=unchecked] > .ql-ui:before{content:'\2610'}@supports (counter-set:none){.ql-editor li[data-list]{counter-set:list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list]{counter-reset:list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered]{counter-increment:list-0}.ql-editor li[data-list=ordered] > .ql-ui:before{content:counter(list-0, decimal) '. '}.ql-editor li[data-list=ordered].ql-indent-1{counter-increment:list-1}.ql-editor li[data-list=ordered].ql-indent-1 > .ql-ui:before{content:counter(list-1, lower-alpha) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-1{counter-set:list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-1{counter-reset:list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-2{counter-increment:list-2}.ql-editor li[data-list=ordered].ql-indent-2 > .ql-ui:before{content:counter(list-2, lower-roman) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-2{counter-set:list-3 list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-2{counter-reset:list-3 list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-3{counter-increment:list-3}.ql-editor li[data-list=ordered].ql-indent-3 > .ql-ui:before{content:counter(list-3, decimal) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-3{counter-set:list-4 list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-3{counter-reset:list-4 list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-4{counter-increment:list-4}.ql-editor li[data-list=ordered].ql-indent-4 > .ql-ui:before{content:counter(list-4, lower-alpha) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-4{counter-set:list-5 list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-4{counter-reset:list-5 list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-5{counter-increment:list-5}.ql-editor li[data-list=ordered].ql-indent-5 > .ql-ui:before{content:counter(list-5, lower-roman) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-5{counter-set:list-6 list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-5{counter-reset:list-6 list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-6{counter-increment:list-6}.ql-editor li[data-list=ordered].ql-indent-6 > .ql-ui:before{content:counter(list-6, decimal) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-6{counter-set:list-7 list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-6{counter-reset:list-7 list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-7{counter-increment:list-7}.ql-editor li[data-list=ordered].ql-indent-7 > .ql-ui:before{content:counter(list-7, lower-alpha) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-7{counter-set:list-8 list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-7{counter-reset:list-8 list-9}}.ql-editor li[data-list=ordered].ql-indent-8{counter-increment:list-8}.ql-editor li[data-list=ordered].ql-indent-8 > .ql-ui:before{content:counter(list-8, lower-roman) '. '}@supports (counter-set:none){.ql-editor li[data-list].ql-indent-8{counter-set:list-9}}@supports not (counter-set:none){.ql-editor li[data-list].ql-indent-8{counter-reset:list-9}}.ql-editor li[data-list=ordered].ql-indent-9{counter-increment:list-9}.ql-editor li[data-list=ordered].ql-indent-9 > .ql-ui:before{content:counter(list-9, decimal) '. '}.ql-editor .ql-indent-1:not(.ql-direction-rtl){padding-left:3em}.ql-editor li.ql-indent-1:not(.ql-direction-rtl){padding-left:4.5em}.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right{padding-right:3em}.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right{padding-right:4.5em}.ql-editor .ql-indent-2:not(.ql-direction-rtl){padding-left:6em}.ql-editor li.ql-indent-2:not(.ql-direction-rtl){padding-left:7.5em}.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right{padding-right:6em}.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right{padding-right:7.5em}.ql-editor .ql-indent-3:not(.ql-direction-rtl){padding-left:9em}.ql-editor li.ql-indent-3:not(.ql-direction-rtl){padding-left:10.5em}.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right{padding-right:9em}.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right{padding-right:10.5em}.ql-editor .ql-indent-4:not(.ql-direction-rtl){padding-left:12em}.ql-editor li.ql-indent-4:not(.ql-direction-rtl){padding-left:13.5em}.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right{padding-right:12em}.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right{padding-right:13.5em}.ql-editor .ql-indent-5:not(.ql-direction-rtl){padding-left:15em}.ql-editor li.ql-indent-5:not(.ql-direction-rtl){padding-left:16.5em}.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right{padding-right:15em}.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right{padding-right:16.5em}.ql-editor .ql-indent-6:not(.ql-direction-rtl){padding-left:18em}.ql-editor li.ql-indent-6:not(.ql-direction-rtl){padding-left:19.5em}.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right{padding-right:18em}.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right{padding-right:19.5em}.ql-editor .ql-indent-7:not(.ql-direction-rtl){padding-left:21em}.ql-editor li.ql-indent-7:not(.ql-direction-rtl){padding-left:22.5em}.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right{padding-right:21em}.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right{padding-right:22.5em}.ql-editor .ql-indent-8:not(.ql-direction-rtl){padding-left:24em}.ql-editor li.ql-indent-8:not(.ql-direction-rtl){padding-left:25.5em}.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right{padding-right:24em}.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right{padding-right:25.5em}.ql-editor .ql-indent-9:not(.ql-direction-rtl){padding-left:27em}.ql-editor li.ql-indent-9:not(.ql-direction-rtl){padding-left:28.5em}.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right{padding-right:27em}.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right{padding-right:28.5em}.ql-editor li.ql-direction-rtl{padding-right:1.5em}.ql-editor li.ql-direction-rtl > .ql-ui:before{margin-left:.3em;margin-right:-1.5em;text-align:left}.ql-editor table{table-layout:fixed;width:100%}.ql-editor table td{outline:none}.ql-editor .ql-code-block-container{font-family:monospace}.ql-editor .ql-video{display:block;max-width:100%}.ql-editor .ql-video.ql-align-center{margin:0 auto}.ql-editor .ql-video.ql-align-right{margin:0 0 0 auto}.ql-editor .ql-bg-black{background-color:#000}.ql-editor .ql-bg-red{background-color:#e60000}.ql-editor .ql-bg-orange{background-color:#f90}.ql-editor .ql-bg-yellow{background-color:#ff0}.ql-editor .ql-bg-green{background-color:#008a00}.ql-editor .ql-bg-blue{background-color:#06c}.ql-editor .ql-bg-purple{background-color:#93f}.ql-editor .ql-color-white{color:#fff}.ql-editor .ql-color-red{color:#e60000}.ql-editor .ql-color-orange{color:#f90}.ql-editor .ql-color-yellow{color:#ff0}.ql-editor .ql-color-green{color:#008a00}.ql-editor .ql-color-blue{color:#06c}.ql-editor .ql-color-purple{color:#93f}.ql-editor .ql-font-serif{font-family:Georgia,Times New Roman,serif}.ql-editor .ql-font-monospace{font-family:Monaco,Courier New,monospace}.ql-editor .ql-size-small{font-size:.75em}.ql-editor .ql-size-large{font-size:1.5em}.ql-editor .ql-size-huge{font-size:2.5em}.ql-editor .ql-direction-rtl{direction:rtl;text-align:inherit}.ql-editor .ql-align-center{text-align:center}.ql-editor .ql-align-justify{text-align:justify}.ql-editor .ql-align-right{text-align:right}.ql-editor .ql-ui{position:absolute}.ql-editor.ql-blank::before{color:rgba(0,0,0,0.6);content:attr(data-placeholder);font-style:italic;left:15px;pointer-events:none;position:absolute;right:15px}.ql-snow.ql-toolbar:after,.ql-snow .ql-toolbar:after{clear:both;content:'';display:table}.ql-snow.ql-toolbar button,.ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:inline-block;float:left;height:24px;padding:3px 5px;width:28px}.ql-snow.ql-toolbar button svg,.ql-snow .ql-toolbar button svg{float:left;height:100%}.ql-snow.ql-toolbar button:active:hover,.ql-snow .ql-toolbar button:active:hover{outline:none}.ql-snow.ql-toolbar input.ql-image[type=file],.ql-snow .ql-toolbar input.ql-image[type=file]{display:none}.ql-snow.ql-toolbar button:hover,.ql-snow .ql-toolbar button:hover,.ql-snow.ql-toolbar button:focus,.ql-snow .ql-toolbar button:focus,.ql-snow.ql-toolbar button.ql-active,.ql-snow .ql-toolbar button.ql-active,.ql-snow.ql-toolbar .ql-picker-label:hover,.ql-snow .ql-toolbar .ql-picker-label:hover,.ql-snow.ql-toolbar .ql-picker-label.ql-active,.ql-snow .ql-toolbar .ql-picker-label.ql-active,.ql-snow.ql-toolbar .ql-picker-item:hover,.ql-snow .ql-toolbar .ql-picker-item:hover,.ql-snow.ql-toolbar .ql-picker-item.ql-selected,.ql-snow .ql-toolbar .ql-picker-item.ql-selected{color:#06c}.ql-snow.ql-toolbar button:hover .ql-fill,.ql-snow .ql-toolbar button:hover .ql-fill,.ql-snow.ql-toolbar button:focus .ql-fill,.ql-snow .ql-toolbar button:focus .ql-fill,.ql-snow.ql-toolbar button.ql-active .ql-fill,.ql-snow .ql-toolbar button.ql-active .ql-fill,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-fill,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-fill,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-fill,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-fill,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-fill,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-fill,.ql-snow.ql-toolbar button:hover .ql-stroke.ql-fill,.ql-snow .ql-toolbar button:hover .ql-stroke.ql-fill,.ql-snow.ql-toolbar button:focus .ql-stroke.ql-fill,.ql-snow .ql-toolbar button:focus .ql-stroke.ql-fill,.ql-snow.ql-toolbar button.ql-active .ql-stroke.ql-fill,.ql-snow .ql-toolbar button.ql-active .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill{fill:#06c}.ql-snow.ql-toolbar button:hover .ql-stroke,.ql-snow .ql-toolbar button:hover .ql-stroke,.ql-snow.ql-toolbar button:focus .ql-stroke,.ql-snow .ql-toolbar button:focus .ql-stroke,.ql-snow.ql-toolbar button.ql-active .ql-stroke,.ql-snow .ql-toolbar button.ql-active .ql-stroke,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke,.ql-snow.ql-toolbar button:hover .ql-stroke-miter,.ql-snow .ql-toolbar button:hover .ql-stroke-miter,.ql-snow.ql-toolbar button:focus .ql-stroke-miter,.ql-snow .ql-toolbar button:focus .ql-stroke-miter,.ql-snow.ql-toolbar button.ql-active .ql-stroke-miter,.ql-snow .ql-toolbar button.ql-active .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke-miter,.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter,.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter{stroke:#06c}@media (pointer:coarse){.ql-snow.ql-toolbar button:hover:not(.ql-active),.ql-snow .ql-toolbar button:hover:not(.ql-active){color:#444}.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-fill,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-fill,.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke.ql-fill{fill:#444}.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke,.ql-snow.ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter,.ql-snow .ql-toolbar button:hover:not(.ql-active) .ql-stroke-miter{stroke:#444}}.ql-snow{box-sizing:border-box}.ql-snow *{box-sizing:border-box}.ql-snow .ql-hidden{display:none}.ql-snow .ql-out-bottom,.ql-snow .ql-out-top{visibility:hidden}.ql-snow .ql-tooltip{position:absolute;transform:translateY(10px)}.ql-snow .ql-tooltip a{cursor:pointer;text-decoration:none}.ql-snow .ql-tooltip.ql-flip{transform:translateY(-10px)}.ql-snow .ql-formats{display:inline-block;vertical-align:middle}.ql-snow .ql-formats:after{clear:both;content:'';display:table}.ql-snow .ql-stroke{fill:none;stroke:#444;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.ql-snow .ql-stroke-miter{fill:none;stroke:#444;stroke-miterlimit:10;stroke-width:2}.ql-snow .ql-fill,.ql-snow .ql-stroke.ql-fill{fill:#444}.ql-snow .ql-empty{fill:none}.ql-snow .ql-even{fill-rule:evenodd}.ql-snow .ql-thin,.ql-snow .ql-stroke.ql-thin{stroke-width:1}.ql-snow .ql-transparent{opacity:.4}.ql-snow .ql-direction svg:last-child{display:none}.ql-snow .ql-direction.ql-active svg:last-child{display:inline}.ql-snow .ql-direction.ql-active svg:first-child{display:none}.ql-snow .ql-editor h1{font-size:2em}.ql-snow .ql-editor h2{font-size:1.5em}.ql-snow .ql-editor h3{font-size:1.17em}.ql-snow .ql-editor h4{font-size:1em}.ql-snow .ql-editor h5{font-size:.83em}.ql-snow .ql-editor h6{font-size:.67em}.ql-snow .ql-editor a{text-decoration:underline}.ql-snow .ql-editor blockquote{border-left:4px solid #ccc;margin-bottom:5px;margin-top:5px;padding-left:16px}.ql-snow .ql-editor code,.ql-snow .ql-editor .ql-code-block-container{background-color:#f0f0f0;border-radius:3px}.ql-snow .ql-editor .ql-code-block-container{margin-bottom:5px;margin-top:5px;padding:5px 10px}.ql-snow .ql-editor code{font-size:85%;padding:2px 4px}.ql-snow .ql-editor .ql-code-block-container{background-color:#23241f;color:#f8f8f2;overflow:visible}.ql-snow .ql-editor img{max-width:100%}.ql-snow .ql-picker{color:#444;display:inline-block;float:left;font-size:14px;font-weight:500;height:24px;position:relative;vertical-align:middle}.ql-snow .ql-picker-label{cursor:pointer;display:inline-block;height:100%;padding-left:8px;padding-right:2px;position:relative;width:100%}.ql-snow .ql-picker-label::before{display:inline-block;line-height:22px}.ql-snow .ql-picker-options{background-color:#fff;display:none;min-width:100%;padding:4px 8px;position:absolute;white-space:nowrap}.ql-snow .ql-picker-options .ql-picker-item{cursor:pointer;display:block;padding-bottom:5px;padding-top:5px}.ql-snow .ql-picker.ql-expanded .ql-picker-label{color:#ccc;z-index:2}.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-fill{fill:#ccc}.ql-snow .ql-picker.ql-expanded .ql-picker-label .ql-stroke{stroke:#ccc}.ql-snow .ql-picker.ql-expanded .ql-picker-options{display:block;margin-top:-1px;top:100%;z-index:1}.ql-snow .ql-color-picker,.ql-snow .ql-icon-picker{width:28px}.ql-snow .ql-color-picker .ql-picker-label,.ql-snow .ql-icon-picker .ql-picker-label{padding:2px 4px}.ql-snow .ql-color-picker .ql-picker-label svg,.ql-snow .ql-icon-picker .ql-picker-label svg{right:4px}.ql-snow .ql-icon-picker .ql-picker-options{padding:4px 0}.ql-snow .ql-icon-picker .ql-picker-item{height:24px;width:24px;padding:2px 4px}.ql-snow .ql-color-picker .ql-picker-options{padding:3px 5px;width:152px}.ql-snow .ql-color-picker .ql-picker-item{border:1px solid transparent;float:left;height:16px;margin:2px;padding:0;width:16px}.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg{position:absolute;margin-top:-9px;right:0;top:50%;width:18px}.ql-snow .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before{content:attr(data-label)}.ql-snow .ql-picker.ql-header{width:98px}.ql-snow .ql-picker.ql-header .ql-picker-label::before,.ql-snow .ql-picker.ql-header .ql-picker-item::before{content:'Normal'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before{content:'Heading 1'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before{content:'Heading 2'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before{content:'Heading 3'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before{content:'Heading 4'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before{content:'Heading 5'}.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before{content:'Heading 6'}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before{font-size:2em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before{font-size:1.5em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before{font-size:1.17em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before{font-size:1em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before{font-size:.83em}.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before{font-size:.67em}.ql-snow .ql-picker.ql-font{width:108px}.ql-snow .ql-picker.ql-font .ql-picker-label::before,.ql-snow .ql-picker.ql-font .ql-picker-item::before{content:'Sans Serif'}.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before{content:'Serif'}.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before{content:'Monospace'}.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before{font-family:Georgia,Times New Roman,serif}.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before{font-family:Monaco,Courier New,monospace}.ql-snow .ql-picker.ql-size{width:98px}.ql-snow .ql-picker.ql-size .ql-picker-label::before,.ql-snow .ql-picker.ql-size .ql-picker-item::before{content:'Normal'}.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before{content:'Small'}.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before{content:'Large'}.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before{content:'Huge'}.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before{font-size:10px}.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before{font-size:18px}.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before{font-size:32px}.ql-snow .ql-color-picker.ql-background .ql-picker-item{background-color:#fff}.ql-snow .ql-color-picker.ql-color .ql-picker-item{background-color:#000}.ql-code-block-container{position:relative}.ql-code-block-container .ql-ui{right:5px;top:5px}.ql-toolbar.ql-snow{border:1px solid #ccc;box-sizing:border-box;font-family:'Helvetica Neue','Helvetica','Arial',sans-serif;padding:8px}.ql-toolbar.ql-snow .ql-formats{margin-right:15px}.ql-toolbar.ql-snow .ql-picker-label{border:1px solid transparent}.ql-toolbar.ql-snow .ql-picker-options{border:1px solid transparent;box-shadow:rgba(0,0,0,0.2) 0 2px 8px}.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border-color:#ccc}.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options{border-color:#ccc}.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item.ql-selected,.ql-toolbar.ql-snow .ql-color-picker .ql-picker-item:hover{border-color:#000}.ql-toolbar.ql-snow + .ql-container.ql-snow{border-top:0}.ql-snow .ql-tooltip{background-color:#fff;border:1px solid #ccc;box-shadow:0 0 5px #ddd;color:#444;padding:5px 12px;white-space:nowrap}.ql-snow .ql-tooltip::before{content:"Visit URL:";line-height:26px;margin-right:8px}.ql-snow .ql-tooltip input[type=text]{display:none;border:1px solid #ccc;font-size:13px;height:26px;margin:0;padding:3px 5px;width:170px}.ql-snow .ql-tooltip a.ql-preview{display:inline-block;max-width:200px;overflow-x:hidden;text-overflow:ellipsis;vertical-align:top}.ql-snow .ql-tooltip a.ql-action::after{border-right:1px solid #ccc;content:'Edit';margin-left:16px;padding-right:8px}.ql-snow .ql-tooltip a.ql-remove::before{content:'Remove';margin-left:8px}.ql-snow .ql-tooltip a{line-height:26px}.ql-snow .ql-tooltip.ql-editing a.ql-preview,.ql-snow .ql-tooltip.ql-editing a.ql-remove{display:none}.ql-snow .ql-tooltip.ql-editing input[type=text]{display:inline-block}.ql-snow .ql-tooltip.ql-editing a.ql-action::after{border-right:0;content:'Save';padding-right:0}.ql-snow .ql-tooltip[data-mode=link]::before{content:"Enter link:"}.ql-snow .ql-tooltip[data-mode=formula]::before{content:"Enter formula:"}.ql-snow .ql-tooltip[data-mode=video]::before{content:"Enter video:"}.ql-snow a{color:#06c}.ql-container.ql-snow{border:1px solid #ccc}

/*# sourceMappingURL=quill.snow.css.map*/
  .quill-wrapper.svelte-10unq2k {
    background: white;
    position: relative;
  }

  .editor-header.svelte-10unq2k {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 10;
  }

  .expand-btn.svelte-10unq2k {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 1px solid #e5e7eb;
    border-radius: 4px;
    background: white;
    cursor: pointer;
    color: #6b7280;
    transition: all 0.15s;
  }

  .expand-btn.svelte-10unq2k:hover {
    background: #f3f4f6;
    color: #374151;
  }

  .expand-btn.svelte-10unq2k .material-symbols-outlined:where(.svelte-10unq2k) {
    font-size: 18px;
  }

  .quill-wrapper.svelte-10unq2k .ql-container {
    min-height: 150px;
    font-size: 14px;
  }

  .quill-wrapper.svelte-10unq2k .ql-editor {
    min-height: 150px;
  }

  .quill-wrapper.svelte-10unq2k .ql-toolbar {
    border-top-left-radius: 0.5rem;
    border-top-right-radius: 0.5rem;
    background: #f9fafb;
  }

  .quill-wrapper.svelte-10unq2k .ql-container {
    border-bottom-left-radius: 0.5rem;
    border-bottom-right-radius: 0.5rem;
  }

  /* Modal styles */
  .modal-backdrop.svelte-10unq2k {
    position: fixed;
    inset: 0;
    background: rgba(55, 65, 81, 0.6);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10000;
    padding: 16px;
  }

  @media (min-width: 640px) {
    .modal-backdrop.svelte-10unq2k {
      padding: 24px;
    }
  }

  @media (min-width: 1024px) {
    .modal-backdrop.svelte-10unq2k {
      padding-left: 288px;
      padding-top: 80px;
    }
  }

  .modal-content.svelte-10unq2k {
    background: white;
    border-radius: 12px;
    width: 100%;
    max-width: 42rem; /* max-w-2xl */
    height: 85vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  }

  @media (min-width: 1024px) {
    .modal-content.svelte-10unq2k {
      max-width: 64rem; /* max-w-5xl */
    }
  }

  .modal-header.svelte-10unq2k {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid #e5e7eb;
  }

  .modal-header.svelte-10unq2k h3:where(.svelte-10unq2k) {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #111827;
  }

  .close-btn.svelte-10unq2k {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 6px;
    background: transparent;
    cursor: pointer;
    color: #6b7280;
    font-size: 24px;
    line-height: 1;
    transition: all 0.15s;
  }

  .close-btn.svelte-10unq2k:hover {
    background: #f3f4f6;
    color: #374151;
  }

  .modal-editor.svelte-10unq2k {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .modal-editor.svelte-10unq2k .ql-toolbar {
    border-left: none;
    border-right: none;
    border-top: none;
    background: #f9fafb;
  }

  .modal-editor.svelte-10unq2k .ql-container {
    flex: 1;
    border: none;
    font-size: 16px;
    overflow-y: auto;
  }

  .modal-editor.svelte-10unq2k .ql-editor {
    padding: 20px 24px;
    min-height: 100%;
  }


  .fullscreen-overlay.svelte-y0h6bt {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .fullscreen-content.svelte-y0h6bt {
    position: relative;
    padding: 0;
    border-radius: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width:100%;
    height: 100%;
  }

  .close-button.svelte-y0h6bt {
    position: fixed;
    top: 0;
    right: 12px;
    background: none;
    border: none;
    font-size: 48px;
    color: white;
    cursor: pointer;
    border-radius: 50%;
  }

  .fullscreen-content.svelte-y0h6bt img:where(.svelte-y0h6bt) {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .nav-button.svelte-y0h6bt {
    position: fixed;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.5);
    color: white;
    border: none;
    padding: 10px 15px;
    cursor: pointer;
    font-size: 2em;
    border-radius: 5px;
    z-index: 1201;
  }

  .nav-button.left.svelte-y0h6bt {
    left: 10px;
  }

  .nav-button.right.svelte-y0h6bt {
    right: 10px;
  }

  .source-details.svelte-y0h6bt {
    position:fixed;
    bottom:12px;
    left:6px;
    background:rgba(255, 255, 255, 0.8);
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    color: #555;
    font-family: "Open Sans", sans-serif;
  }

  .source-details.svelte-y0h6bt a:where(.svelte-y0h6bt) {
    color: #007bff;
    text-decoration: none;
  }

  .source-details.svelte-y0h6bt a:where(.svelte-y0h6bt):hover {
    text-decoration: underline;
  }


  .scrollbar-thin.svelte-1fq5gm6::-webkit-scrollbar {
    height: 6px;
  }
  .scrollbar-thin.svelte-1fq5gm6::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }
  .scrollbar-thin.svelte-1fq5gm6::-webkit-scrollbar-thumb {
    background: #ccc;
    border-radius: 3px;
  }
  .scrollbar-thin.svelte-1fq5gm6::-webkit-scrollbar-thumb:hover {
    background: #aaa;
  }

  @media (hover: none) {
    .hover-fallback.svelte-1fq5gm6 {
      opacity: 1 !important;
    }
  }


  .place-details-container.svelte-alp3zm {
    min-height: 60px;
  }

  .place-details-container.svelte-alp3zm gmp-place-details-compact {
    width: 100%;
    --gmp-place-details-compact-background: white;
  }


  

  gmp-advanced-marker:has(> .selected-marker) {
    z-index: 1000;
  }

  .custom-advanced-marker {
    position: relative;
    transition: transform 0.1s ease-in-out;
    transform:translateY(20px);
    transform-origin: center;
    user-select: none;
  }

  .draft-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 10px;
    height: 10px;
    background-color: #ef4444;
    border-radius: 50%;
    border: 1.5px solid white;
    pointer-events: none;
  }

  .recommended-crown {
    position: absolute;
    top: -5px;
    left: 50%;
    transform: translateX(-50%);
    width: 22px;
    height: 10px;
    pointer-events: none;
    filter: drop-shadow(0 1px 1px rgba(0,0,0,0.2));
  }

  /* Unverified pin: render the dedicated _unverified.svg sprite at the same
     28 × 24 (40 × 34 when full-size) box used by verified markers so the
     dashed disc matches their outer radius — see icon CSS above for the
     defaults that this rule deliberately leaves untouched. The dashed
     stroke and shaded fill live in the SVG itself; no extra masks here. */

  .custom-advanced-marker.selected-marker {
    transform:translateY(20px) scale(1.5);
  }

  /* One-shot confirmation for "Show on map", which opens no panel. Animates a
     halo via box-shadow rather than transform: the selected-marker rule above
     owns `transform`, and animating it here would fight that scale. */
  @keyframes svelte-7sr3kz-mfm-reveal-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(43, 190, 74, 0.75); }
    70%  { box-shadow: 0 0 0 18px rgba(43, 190, 74, 0); }
    100% { box-shadow: 0 0 0 0 rgba(43, 190, 74, 0); }
  }

  .custom-advanced-marker.revealed-marker {
    border-radius: 50%;
    animation: svelte-7sr3kz-mfm-reveal-pulse 1.1s ease-out 2;
  }

  /* Respect a reduced-motion preference: the pulse is pure confirmation, so
     dropping it costs nothing that the selected scale does not already say. */
  @media (prefers-reduced-motion: reduce) {
    .custom-advanced-marker.revealed-marker {
      animation: none;
    }
  }

  .plus-icon-overlay {
    position: absolute;
    background-color: white;
    border-radius: 50%;
    cursor: pointer;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);
    user-select: none;
  }

  .plus-icon-overlay .material-symbols-outlined {
    font-size: 24px;
    color: #1a73e8;
  }

  .navigational-point-overlay {
    position: absolute;
    width: 18px;
    height: 18px;
    background-color: #6666cc;
    border: 2px solid white;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    cursor: grab;
    transition: transform 0.1s ease-in-out;
    user-select: none;
  }

  .navigational-point-overlay:hover {
    transform: translate(-50%, -50%) scale(1.2);
  }

  .navigational-point-overlay.selected-nav-point {
    transform: translate(-50%, -50%) scale(1.5);
    z-index: 1000;
  }

  .nav-point-delete-button {
    position: absolute;
    width: 20px;
    height: 20px;
    background-color: #d32f2f;
    border: 2px solid white;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1001;
    transition: background-color 0.15s ease;
    user-select: none;
  }

  .nav-point-delete-button:hover {
    background-color: #b71c1c;
  }

  .nav-point-delete-button .material-symbols-outlined {
    font-size: 14px;
    color: white;
  }

  .clicked-location-marker {
    width: 14px;
    height: 14px;
    background-color: #4285F4;
    border: 2px solid white;
    border-radius: 50%;
    box-shadow: 0 0 4px rgba(0,0,0,0.4);
    cursor: grab;
    user-select: none;
  }

  .distance-label {
    position: absolute;
    background: rgba(255, 255, 255, 0.8);
    padding: 2px 5px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: 500;
    transform: translate(-50%, -50%);
    white-space: nowrap;
  }

  .custom-advanced-marker img.advanced-marker-icon {
    display: block;
    width: 28px;
    height: 24px;
  }

  /* Full-size markers for POI types (zoom 12-16) when zoomed to 17+ */
  .custom-advanced-marker.marker-full-size img.advanced-marker-icon {
    width: 40px;
    height: 34px;
  }

  /* ── Occluded-marker dots ──────────────────────────────────────────────
     A marker that loses the 24px occlusion contest keeps its position and
     renders as a 4px disc in its own category colour instead of vanishing.
     Design: docs/superpowers/specs/2026-08-03-occluded-marker-dots-design.md

     Every rule is scoped under .mapWrapper.occlusion-dots (same pattern as
     .ai-build-hiding-pois below) so that with the feature off the ::after
     below is never created — otherwise every marker on the map would carry a
     pseudo-element for a feature that is not running.

     --occlusion-dot-color and --occlusion-dot-y are published per marker by
     createMarker, read from the marker's own sprite. The fallbacks here cover
     markers whose art is outside the sprite set (external iconUrl) and the
     window before the sprite parse resolves. 46% is the midpoint of the three
     real disc centres (44.07% / 48% / 50%), i.e. the least-wrong constant —
     which is exactly why the real value is derived rather than hardcoded. */
  /* One source of truth for the dot<->pin timing: it drives four transitions
     across three rules, and at 180ms the grow/collapse was over before the eye
     could pick it up — the markers just appeared to snap. Custom properties
     inherit, and every marker is a descendant of .mapWrapper, so the value
     reaches all of them. */
  .mapWrapper.occlusion-dots.svelte-7sr3kz {
    --occlusion-dot-anim: 500ms;
  }

  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker img.advanced-marker-icon {
    /* The pin shrinks toward the dot's centre rather than the box's, which is
       what makes the two read as one object growing and collapsing. */
    transform-origin: 50% var(--occlusion-dot-y, 46%);
    transition:
      transform var(--occlusion-dot-anim, 500ms) ease-out,
      opacity var(--occlusion-dot-anim, 500ms) ease-out;
  }

  /* 0.33 ≈ 6px ÷ ~18px, the rendered diameter of the sprite's coloured disc, so
     the shrinking pin lands on the dot's size rather than near it. A single
     constant despite the two sprite families implying 0.357 and 0.321: the
     image is fully transparent by the time it reaches this scale, so only the
     ORIGIN above is visually load-bearing. Keep in step with the dot's
     width/height below. */
  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker.occluded-dot img.advanced-marker-icon {
    transform: scale(0.33);
    opacity: 0;
  }

  /* Every child that is NOT the pin image fades out in the dot state.
     Stated as the complement of the one element that must animate, rather than
     as a list of the decorations that must not: the crown, the draft badge and
     the weather score pill are all absolutely positioned siblings that would
     otherwise hang at full size around a 4px dot, and the pill in particular is
     appended imperatively by the weather effect (see PILL_ATTR above) — a rule
     naming each class by hand would silently miss it, and miss the next one. */
  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker > *:not(img.advanced-marker-icon) {
    transition: opacity var(--occlusion-dot-anim, 500ms) ease-out;
  }

  /* `!important` is load-bearing here, not laziness. The weather status pill
     (WeatherScorePill.ts) sets `opacity:0.9` as an INLINE style, and its
     'loading' variant additionally animates opacity through the Web Animations
     API. A normal stylesheet declaration loses to both; an important author
     declaration outranks inline-normal styles AND animations, so it is the only
     form that actually hides them. Without it the no-score and still-loading
     havens keep a full-size grey pill hovering over a 6px dot — which is what
     made demoted markers look like locations that should not be on the map. */
  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker.occluded-dot > *:not(img.advanced-marker-icon) {
    opacity: 0 !important;
  }

  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker::after {
    content: '';
    position: absolute;
    left: 50%;
    top: var(--occlusion-dot-y, 46%);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--occlusion-dot-color, #6b7280);
    /* No ring and no shadow: at this size either one eats most of the disc and
       swamps the category colour it exists to show. */
    transform: translate(-50%, -50%) scale(0);
    opacity: 0;
    transition:
      transform var(--occlusion-dot-anim, 500ms) ease-out,
      opacity var(--occlusion-dot-anim, 500ms) ease-out;
    pointer-events: none;
  }

  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker.occluded-dot::after {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }

  /* Decorative only — a dot must never take a click from the pin that
     occluded it. */
  .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker.occluded-dot {
    pointer-events: none;
  }

  @media (prefers-reduced-motion: reduce) {
    .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker img.advanced-marker-icon,
    .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker > *:not(img.advanced-marker-icon),
    .mapWrapper.occlusion-dots.svelte-7sr3kz .custom-advanced-marker::after {
      transition: none;
    }
  }

  /* U6: weather time-slider + cadence overlay, pinned to the bottom-centre of the
     map. Sits above the map tiles; the rest of the map stays interactive. */
  .weatherSliderOverlay.svelte-7sr3kz {
    position: absolute;
    /* Sit above the mobile AI bottom bar when it's visible: the bar publishes
       its occupied height as --ai-bar-bottom-h (0 when collapsed/hidden, unset
       on desktop → falls back to 0). Smooth so it follows the bar's expand/
       collapse. */
    bottom: calc(16px + var(--ai-bar-bottom-h, 0px));
    transition: bottom 0.3s ease-in-out;
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
    /* 780 rather than 660: the Show/Hide PILLS (Batch 3 follow-up) are wider
       than the checkboxes they replaced (~280px for the pair against ~180),
       and at 660 they wrapped onto a second header row even on a wide desktop.
       780 fits title + cadence + the "updated …" note + both pills on the
       first row; `calc(100% - 32px)` still caps it on anything narrower, where
       the header wraps exactly as before (the 470px container query below is
       untouched). */
    width: min(780px, calc(100% - 32px));
    /* Container queries below size the header off the PANEL's own width (not the
       viewport), so the "updated …" note and the word "weather" drop only when this
       panel actually lacks the room. */
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* No inner gap/padding: the header is its own tinted bar and the night
       bands below it fill edge-to-edge down to the panel bottom. overflow:hidden
       clips both to the rounded corners. */
    gap: 0;
    padding: 0;
    border-radius: 12px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28), 0 2px 6px rgba(0, 0, 0, 0.16);
    backdrop-filter: blur(4px);
    pointer-events: auto;
  }
  html.dark .weatherSliderOverlay.svelte-7sr3kz {
    background: rgba(31, 41, 55, 0.92);
  }
  .weatherOverlayHeader.svelte-7sr3kz {
    align-self: stretch;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 8px;
    /* row-gap 0: the mobile two-row split's only vertical gap is the break line's
       own height (below), so the phantom break line can't double the row spacing. */
    row-gap: 0;
    /* Positioning context for the ✕, which is pinned to this corner rather than
       flowing with the rest of the row — see .weatherOverlayClose. */
    position: relative;
    /* The right padding reserves the ✕'s column (10px edge + 22px button + 6px
       breathing room) so no wrapped row can ever run underneath it. */
    padding: 6px 38px 6px 10px;
    background: #f1f5f9; /* slate-100 — distinct title-bar tint vs the panel */
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    -webkit-user-select: none;
    user-select: none;
  }
  html.dark .weatherOverlayHeader.svelte-7sr3kz {
    background: #374151; /* gray-700 */
    border-bottom-color: rgba(255, 255, 255, 0.08);
  }
  /* The cadence segmented control sits inline in the header sequence
     (title · "worst in:" · cadence · "updated hourly • last …" · ✕), keeping its
     natural width; the header wraps on narrow screens. */
  .weatherOverlayCadence.svelte-7sr3kz {
    display: flex;
    align-items: center;
  }
  /* Info link — Batch 3 moved both instances INSIDE their overlay pills (see
     .weatherOverlayPill below), which now inherit the pill's color; this base
     rule keeps the box, hit area and glyph sizing. */
  .weatherOverlayInfo.svelte-7sr3kz {
    flex: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    /* Fully rounded, like the pill it sits in — the hover fill is a circle. */
    border-radius: 9999px;
    color: #6b7280;
    text-decoration: none;
    cursor: pointer;
  }
  .weatherOverlayInfo.svelte-7sr3kz .material-symbols-outlined:where(.svelte-7sr3kz) {
    font-size: 18px;
    line-height: 1;
  }
  /* ~44px touch target without affecting layout (outdoor mobile use). */
  .weatherOverlayInfo.svelte-7sr3kz::after {
    content: '';
    position: absolute;
    inset: -11px;
  }
  .weatherOverlayInfo.svelte-7sr3kz:hover {
    background: rgba(0, 0, 0, 0.06);
    color: #111827;
  }
  html.dark .weatherOverlayInfo.svelte-7sr3kz {
    color: #9ca3af;
  }
  html.dark .weatherOverlayInfo.svelte-7sr3kz:hover {
    background: rgba(255, 255, 255, 0.1);
    color: #f3f4f6;
  }
  .weatherOverlayTitle.svelte-7sr3kz {
    font-size: 13px;
    font-weight: 600;
    color: #111827; /* gray-900 */
  }
  .weatherOverlayNote.svelte-7sr3kz {
    font-size: 11px;
    font-weight: 400;
    color: #6b7280; /* gray-500 */
  }
  /* Desktop: the "updated …" note + toggles sit between the cadence and the ✕ — two
     auto left-margins (here + on .weatherOverlayClose) split the free space equally.
     Stacked on two tight lines ("updated hourly" / "last 07:18") so the note costs
     about half the row width it did inline, which is what buys room for the toggles. */
  .weatherOverlayUpdated.svelte-7sr3kz {
    margin-left: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1.15;
    text-align: center;
    white-space: nowrap;
    /* The note is the TALLEST item in this flex row (measured: 25.3px, against
       24px for the cadence control), so it — not the cadence buttons — sets the
       header height. Swapping its two lines for the 14px spinner therefore
       shrank the header by 1.3px and grew it back on every fetch. Reserving the
       two-line height keeps the row still: font-size × line-height × 2 lines,
       written as the arithmetic so it tracks the two values above. */
    min-height: calc(11px * 1.15 * 2);
  }
  /* The note's loading state: a small spinner in place of the two-line text,
     sized to sit inside the same row without growing the header. */
  .weatherOverlaySpinner.svelte-7sr3kz {
    font-size: 14px;
    line-height: 1;
    color: #6b7280; /* gray-500, matches .weatherOverlayNote's text colour */
  }
  html.dark .weatherOverlaySpinner.svelte-7sr3kz {
    color: #9ca3af; /* gray-400, matches the dark-mode note colour */
  }
  /* U4 — the note's failure state. Two lines like the settled state ("couldn't
     load forecast" / "Retry"), so it lands inside the height
     .weatherOverlayUpdated already reserves and the header does not jump. */
  .weatherOverlayFailed.svelte-7sr3kz {
    color: #b91c1c; /* red-700, matching the weather error banner in MfmControls */
  }
  html.dark .weatherOverlayFailed.svelte-7sr3kz {
    color: #fca5a5; /* red-300 */
  }
  .weatherOverlayRetry.svelte-7sr3kz {
    padding: 0;
    border: none;
    background: transparent;
    font: inherit;
    line-height: inherit;
    color: #b91c1c;
    text-decoration: underline;
    cursor: pointer;
  }
  .weatherOverlayRetry.svelte-7sr3kz:hover {
    color: #7f1d1d; /* red-900 */
  }
  html.dark .weatherOverlayRetry.svelte-7sr3kz {
    color: #fca5a5;
  }
  html.dark .weatherOverlayRetry.svelte-7sr3kz:hover {
    color: #fecaca; /* red-200 */
  }
  .spinning.svelte-7sr3kz {
    animation: svelte-7sr3kz-spin 1s linear infinite;
  }
  @keyframes svelte-7sr3kz-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
  /* The Scores / Beaufort-zones checkboxes, ending the first row.
     Its auto left-margin is the SECOND of exactly two in the row (the other is on the
     note): free space splits evenly between them, so the note sits the same distance
     from the cadence control as from the Scores checkbox. The ✕ is not part of this
     arithmetic — it is absolutely positioned in the header corner, and the header's
     reserved right padding is what keeps this group clear of it. When the note is
     hidden on narrow panels this auto is the only one left and the toggles still
     travel to the right edge. */
  .weatherOverlayToggles.svelte-7sr3kz {
    flex: none;
    margin-left: auto;
    display: flex;
    align-items: center;
    column-gap: 8px;
  }
  /* Batch 3 — the SHOW/HIDE pills that replaced the two checkboxes. The pill
     itself is the colored rounded rectangle; its two interactive children (the
     toggle button and the info link) sit flat inside it, so the info button is
     visually INSIDE the pill without nesting interactive elements. Filled
     while the overlay is on, tinted while off — the label carries the action
     ("Show …" / "Hide …"), the fill carries the state. */
  .weatherOverlayPill.svelte-7sr3kz {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px 4px 2px 0;
    border-radius: 9999px;
    white-space: nowrap;
  }
  .weatherOverlayPillMain.svelte-7sr3kz {
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 6px 2px 8px;
    cursor: pointer;
    border-radius: 9999px 0 0 9999px;
    /* Review finding — a hairline seam before the info icon, so the pill
       visibly contains TWO targets and a click near its right edge is not a
       surprise info-panel open. On the button's flat right edge (the radius
       above rounds only the left), so it renders straight; currentColor at
       low opacity keeps it legible on both the filled and tinted states. */
    border-right: 1px solid color-mix(in srgb, currentColor 30%, transparent);
  }
  /* The VIBRANT fill belongs to the "Show …" state (overlay off): that is the
     invitation, so it carries the saturated call-to-action color; once the
     overlay is on, the pill reads "Hide …" and drops to the quiet tint —
     the map itself is now showing the color. (This is the reverse of the
     first cut, flipped on direct product direction.)

     Scores — the blue the old checkbox's accent-color already used. */
  .weatherOverlayPillScores.svelte-7sr3kz {
    background: #2563eb; /* blue-600 */
    color: #fff;
  }
  .weatherOverlayPillScores.is-on.svelte-7sr3kz {
    background: #dbeafe; /* blue-100 */
    color: #1d4ed8; /* blue-700 */
  }
  /* Beaufort zones — violet, so the two pills read as two different overlays
     at a glance rather than two states of one control. Violet rather than a
     wind-scale hue (green/amber/red) on purpose: the zones themselves paint
     the map in the wind scale, and a pill wearing one of those colors would
     read as a wind strength rather than as a control. */
  .weatherOverlayPillZones.svelte-7sr3kz {
    background: #7c3aed; /* violet-600 */
    color: #fff;
  }
  .weatherOverlayPillZones.is-on.svelte-7sr3kz {
    background: #ede9fe; /* violet-100 */
    color: #6d28d9; /* violet-700 */
  }
  html.dark .weatherOverlayPillScores.svelte-7sr3kz {
    background: #2563eb;
    color: #fff;
  }
  html.dark .weatherOverlayPillScores.is-on.svelte-7sr3kz {
    background: rgba(37, 99, 235, 0.25);
    color: #93c5fd; /* blue-300 */
  }
  html.dark .weatherOverlayPillZones.svelte-7sr3kz {
    background: #7c3aed;
    color: #fff;
  }
  html.dark .weatherOverlayPillZones.is-on.svelte-7sr3kz {
    background: rgba(124, 58, 237, 0.3);
    color: #c4b5fd; /* violet-300 */
  }
  /* The info link inside a pill inherits the pill's color in both states —
     the base rule's grey would vanish against the filled state. */
  .weatherOverlayPill.svelte-7sr3kz .weatherOverlayInfo:where(.svelte-7sr3kz) {
    color: inherit;
  }
  .weatherOverlayPill.svelte-7sr3kz .weatherOverlayInfo:where(.svelte-7sr3kz):hover {
    background: rgba(0, 0, 0, 0.12);
    color: inherit;
  }
  html.dark .weatherOverlayPill.svelte-7sr3kz .weatherOverlayInfo:where(.svelte-7sr3kz),
  html.dark .weatherOverlayPill.svelte-7sr3kz .weatherOverlayInfo:where(.svelte-7sr3kz):hover {
    color: inherit;
  }

  /* The no-zones note's toggle — sized like the info button beside it, and
     inheriting the pill's state color the same way. */
  .weatherOverlayZonesNoteBtn.svelte-7sr3kz {
    flex: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border: 0;
    padding: 0;
    background: transparent;
    border-radius: 9999px;
    color: inherit;
    cursor: pointer;
  }
  .weatherOverlayZonesNoteBtn.svelte-7sr3kz .material-symbols-outlined:where(.svelte-7sr3kz) {
    font-size: 18px;
    line-height: 1;
  }
  /* Dismissed-but-relevant: while the note is hidden its button wears the
     pill's "Show …" call-to-action fill (the zones-off violet), so the way
     back to the explanation stands out against the quiet is-on tint around
     it — same invitation language as the pills themselves. Same values in
     dark mode, which also fills its "Show" state with violet-600/white. */
  .weatherOverlayZonesNoteBtn.note-hidden.svelte-7sr3kz {
    background: #7c3aed; /* violet-600 */
    color: #fff;
  }
  /* ~44px touch target without affecting layout, like the info button's. */
  .weatherOverlayZonesNoteBtn.svelte-7sr3kz::after {
    content: '';
    position: absolute;
    inset: -11px;
  }
  .weatherOverlayZonesNoteBtn.svelte-7sr3kz:hover {
    background: rgba(0, 0, 0, 0.12);
  }
  html.dark .weatherOverlayZonesNoteBtn.svelte-7sr3kz:hover {
    background: rgba(255, 255, 255, 0.1);
  }

  /* ── The "no Beaufort zone warnings here" row ──────────────────────────────
     The panel's first in-flow row, above the header and the datetime strip.
     In-flow, never absolutely positioned outside the panel: the panel is
     `overflow: hidden`, which clips a hung-outside toast to nothing (found
     the hard way in the browser), and in-flow it joins the measured panel
     height for free. Violet-tinted to read as the zones overlay's voice,
     matching .weatherOverlayPillZones. */
  .weatherZonesEmptyNote.svelte-7sr3kz {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 6px 8px 6px 12px;
    background: rgba(124, 58, 237, 0.08);
    border-bottom: 1px solid rgba(124, 58, 237, 0.2);
    font-size: 12px;
    line-height: 1.45;
    color: #374151;
  }
  .weatherZonesEmptyNoteText.svelte-7sr3kz {
    min-width: 0;
  }
  .weatherZonesEmptyNoteLink.svelte-7sr3kz {
    border: 0;
    padding: 0;
    background: transparent;
    color: #6d28d9;
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
  }
  .weatherZonesEmptyNoteLink.svelte-7sr3kz:hover {
    color: #5b21b6;
  }
  .weatherZonesEmptyNoteClose.svelte-7sr3kz {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border: 0;
    padding: 0;
    background: transparent;
    border-radius: 9999px;
    color: #6b7280;
    font-size: 12px;
    cursor: pointer;
  }
  .weatherZonesEmptyNoteClose.svelte-7sr3kz:hover {
    background: rgba(0, 0, 0, 0.06);
    color: #111827;
  }
  html.dark .weatherZonesEmptyNote.svelte-7sr3kz {
    background: rgba(124, 58, 237, 0.18);
    border-bottom-color: rgba(196, 181, 253, 0.25);
    color: #e5e7eb;
  }
  html.dark .weatherZonesEmptyNoteLink.svelte-7sr3kz {
    color: #c4b5fd;
  }
  html.dark .weatherZonesEmptyNoteLink.svelte-7sr3kz:hover {
    color: #ddd6fe;
  }
  html.dark .weatherZonesEmptyNoteClose.svelte-7sr3kz {
    color: #9ca3af;
  }
  html.dark .weatherZonesEmptyNoteClose.svelte-7sr3kz:hover {
    background: rgba(255, 255, 255, 0.1);
    color: #f3f4f6;
  }
  html.dark .weatherOverlayPill.svelte-7sr3kz .weatherOverlayInfo:where(.svelte-7sr3kz):hover {
    background: rgba(255, 255, 255, 0.18);
  }
  /* The pills' info links sit 22px tall inside a ~24px pill; their ::after
     hit-area extension (below) still provides the ~44px touch target. */
  /* ── U28 (R38, R39) — the note row ───────────────────────────────────────
     `flex-basis: 100%` makes it its own row at EVERY width by construction, so
     no breakpoint has to put it there and none can accidentally pull it back up
     beside the toggles. It stays inside the header's box (including the 38px
     right padding that reserves the ✕'s column), so the pinned ✕ never lands on
     top of the prose. */
  .weatherOverlayNoteRow.svelte-7sr3kz {
    flex-basis: 100%;
    margin: 0;
    padding-top: 4px;
    /* U8 / R6 — "a larger font that fills the row".
       Fluid against the PANEL, not the viewport: `.weatherSliderOverlay` already
       declares `container-type: inline-size` for the degrade ladder below, so
       `cqi` (1% of the panel's inline size) is the unit that already describes
       this row's real constraint. A fixed size cannot both fill a 660px panel and
       fit a 343px one; a viewport unit would ignore that the panel stops growing
       at 660 and would keep inflating on a wide desktop.

       The numbers: the full sentence measures ~40× the font size, against
       `container − 48px` of usable width (the header's padding plus the ✕'s
       reserved column). At the 660px cap that is 2.2cqi ≈ 14.5px and ~581px of
       text in 612px of room — the row fills, which is what R6 asks for. The 15px
       ceiling is therefore never reached at the current cap; it is there so a
       wider panel does not keep scaling.

       The 12px floor is the load-bearing end. It sets where the prose stops
       fitting on one line (40 × 12 + 48 = 528px of panel), which is why the note
       row's degrade breakpoint below is 530 and no longer shares the toggles' 470
       — raising the font without moving that threshold would have left a band of
       panel widths showing two-line prose. */
    font-size: clamp(12px, 2.2cqi, 15px);
    line-height: 1.35;
    color: #6b7280; /* gray-500 — the weight .weatherOverlayNote already uses */
  }
  html.dark .weatherOverlayNoteRow.svelte-7sr3kz {
    color: #9ca3af;
  }
  /* The three controls. Buttons rather than anchors: each opens a dialog in
     place, there is no URL behind them, and a bare <a href="#"> would offer a
     right-click menu full of dead options. Reset to look like the running text
     they sit inside, so the full-width row reads as one sentence. */
  .weatherOverlayNoteLink.svelte-7sr3kz {
    display: inline;
    margin: 0;
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    color: #1d4ed8; /* blue-700 — passes AA on the slate-100 header tint */
    text-decoration: underline;
    text-underline-offset: 2px;
    white-space: nowrap; /* a control may wrap the row, never split in half */
    cursor: pointer;
  }
  .weatherOverlayNoteLink.svelte-7sr3kz:hover {
    color: #1e3a8a; /* blue-900 */
  }
  html.dark .weatherOverlayNoteLink.svelte-7sr3kz {
    color: #93c5fd; /* blue-300 */
  }
  html.dark .weatherOverlayNoteLink.svelte-7sr3kz:hover {
    color: #bfdbfe; /* blue-200 */
  }
  .weatherOverlayNoteDay.svelte-7sr3kz,
  .weatherOverlayNoteDaySep.svelte-7sr3kz {
    white-space: nowrap;
  }
  /* Wide presentation: the connective prose is rendered and the chip label and
     chip separators are not. The narrow block below swaps exactly these two
     sets — one set of CONTROLS serves both, which is the whole point: a second
     copy would double every button for a screen reader and for any query that
     counts them. */
  .weatherOverlayNoteChipLabel.svelte-7sr3kz,
  .weatherOverlayNoteSep.svelte-7sr3kz {
    display: none;
  }
  /* Panel too narrow for title + cadence + note + toggles + ✕ → drop the "updated …"
     note first; it is the only decorative item in the row, and the toggles are
     controls. Threshold measured against the rendered header, not guessed. */
  @container (max-width: 610px) {
    .weatherOverlayUpdated.svelte-7sr3kz {
      display: none;
    }
  }
  /* U28 / R39 — the note row's degrade. Re-COMPOSED, never truncated: the
     prose drops out and the same three controls become a labelled chip row,
     `Affected by: Sailing · Activity · Dates · day 3`. All three targets
     survive at full size and nothing is hidden behind an ellipsis — which is
     what `text-overflow: ellipsis; white-space: nowrap` would have done to
     whichever control fell off the end, and the controls ARE the row.

     Threshold MEASURED, not inherited from any row above. The full sentence
     renders at ~40× the font size of text, against `container − 48px` of usable
     width, and below that it wraps three and four lines deep as the panel
     narrows — exactly the "tripling the panel's height" R39 forbids. It is not
     the 330px breakpoint the header's droppable "within" uses: degrading at 330
     would leave every phone on the multi-line version (an iPhone SE renders this
     panel 343px wide) — correct against the letter of the plan and wrong on the
     device the requirement is about.

     U8 / R6 MOVED this from 470 to 530 and out of the toggles' block. At the
     old 11px the sentence was ~440px wide and held one line down to a ~490px
     panel, so 470 — where the toggles break anyway — was close enough to be
     worth sharing. The row's floor is now 12px (~480px of text, one line down to
     528), so keeping 470 would have opened a 470–528 band showing two-line prose
     where there used to be one line. The toggles keep their own 470 break, which
     was never about this row's text; between 530 and 470 the panel simply gains
     the chip form a little earlier. */
  @container (max-width: 530px) {
    .weatherOverlayNoteProse.svelte-7sr3kz {
      display: none;
    }
    .weatherOverlayNoteChipLabel.svelte-7sr3kz,
    .weatherOverlayNoteSep.svelte-7sr3kz {
      display: inline;
    }
    /* "sailing" → "Sailing": chips are labels, not sentence fragments. Done in
       CSS so the markup carries the prose casing once, and the two
       presentations cannot drift into two copies of the same three words. */
    .weatherOverlayNoteLink.svelte-7sr3kz {
      text-transform: capitalize;
    }
  }
  /* Narrow: the row can no longer hold cadence + toggles. Break it in two, with the
     toggles starting the second row, left-aligned. The ✕ needs no rule here — it is
     pinned to the header corner and out of the flow, so it stays at the first row's
     right end (where it always is, and so never moves under the thumb) on its own.
     The phone layout still gains exactly two rows, both single-line (measured: the
     note row at the 12px floor; panel 111px wide-open, 119px on a phone). */
  @container (max-width: 470px) {
    .weatherOverlayToggles.svelte-7sr3kz {
      margin-left: 0; /* left-align: no auto margin pushing it right */
      flex-basis: 100%;
      padding-top: 4px;
    }
  }
  /* Even narrower (no room for title + cadence + ✕) → drop the word "within"
     ("Peak wind:") so the ✕ still fits on the row. Threshold tuned so iPhone-SE-width
     panels (~343px) keep the full "Peak wind within:".

     "within" is the droppable word rather than "wind": "Peak wind:" still names
     the quantity, where "Peak within:" names nothing at all. */
  @container (max-width: 330px) {
    .weatherOverlayTitleWord.svelte-7sr3kz {
      display: none;
    }
  }
  /* The ✕ is pinned to the header's top-right corner instead of flowing as the
     last flex item.
     As a flex child it wrapped: the row's natural width (title + cadence + note
     + both toggle groups) exceeds the panel at every size between the 470px
     two-row breakpoint and roughly 1060px, so the ✕ — the last and most
     droppable item — spilled onto a second row and, having no auto margin in
     that range, sat at its LEFT edge. Widening the breakpoint ladder would have
     traded one hard-coded guess for another; taking the button out of the flow
     makes "end of the first row" true at every width by construction, and the
     header's reserved right padding keeps wrapped content clear of it. */
  .weatherOverlayClose.svelte-7sr3kz {
    position: absolute;
    top: 6px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: #6b7280;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
  }
  /* Expand the touch target to ~44px without changing the 22px visual or layout
     (the pseudo-element is absolute, so it adds no box) — outdoor mobile use. */
  .weatherOverlayClose.svelte-7sr3kz::after {
    content: '';
    position: absolute;
    inset: -11px;
  }
  .weatherOverlayClose.svelte-7sr3kz:hover {
    background: rgba(0, 0, 0, 0.06);
    color: #111827;
  }
  html.dark .weatherOverlayTitle.svelte-7sr3kz {
    color: #f3f4f6;
  }
  html.dark .weatherOverlayNote.svelte-7sr3kz {
    color: #9ca3af;
  }
  html.dark .weatherOverlayClose.svelte-7sr3kz {
    color: #9ca3af;
  }
  html.dark .weatherOverlayClose.svelte-7sr3kz:hover {
    background: rgba(255, 255, 255, 0.1);
    color: #f3f4f6;
  }

  .mapWrapper.svelte-7sr3kz {
    width: 100%;
    height: 100%;
    position: relative;
    /* Use `clip` (not `hidden`) so the hidden ItineraryPanel — which lives
       off-screen at translateX(panelWidth) and extends the wrapper's
       scrollWidth — cannot be scrolled into view by the browser's
       focus-into-view heuristic. Without this, opening the InfoPanel can
       shift the whole map left by panelWidth, leaving a panel-sized
       whitespace strip on the right of the viewport. */
    overflow: clip;
  }

  .mapContainerStack.svelte-7sr3kz {
    position: absolute;
    inset: 0;
    transition: width 0.3s ease, height 0.3s ease;
  }

  .mapContainer.svelte-7sr3kz {
    width: 100%;
    height: 100%;
    transition: width 0.3s ease, height 0.3s ease; /* Smooth transition */
  }

  .mapContainerLayer.svelte-7sr3kz {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0s linear;
  }

  .mapContainerLayer.is-active.svelte-7sr3kz {
    opacity: 1;
    pointer-events: auto;
  }

  /* Map sizing is now handled dynamically via inline styles on .mapContainerStack */

  .toggle-map-id {
    position: absolute;
    bottom: 165px;
    right: 10px;
    z-index: 1000;
    padding: 10px;
    background-color: #fff;
    color:rgba(0, 0, 0, 0.7);
    border:0;
    border-radius: 50%;
    cursor: pointer;
    width:40px;
    height:40px;
    display:flex;
    justify-content: center;
    align-items: center;
  }

    .divider {
      border-top: 1px solid #cacaca;
      width: 100%;
    }

  .lat-lng-display-container.svelte-7sr3kz {
    position: absolute;
    bottom: 10px;
    transform: translateX(-50%);
    z-index: 1;
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 5px;
    padding: 5px 10px;
    display: flex;
    align-items: center;
    font-family: 'Roboto', sans-serif; /* Use a standard font */
    font-size: 0.8em;
    color: #333; /* Darker text for readability */
    transition: bottom 0.3s ease;
  }

  .lat-lng-display.svelte-7sr3kz {
    display: flex;
      align-items: center;
    white-space: nowrap; /* Prevent wrapping */
    border:0px;
    color: white;
    font-family: 'Open Sans', sans-serif;
    font-size: 14px;
    background:transparent;
    display: flex;
    gap: 5px;
  }

  .chatbot-result-marker {
    position: relative;
  }

  .chatbot-result-marker img.advanced-marker-icon {
    width: 40px;
    height: 34px;
  }

  .chatbot-result-number {
    position: absolute;
    top: -5px;
    right: -3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #3B82F6;
    color: white;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    border: 1.5px solid white;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
  }

  .featured-marker img.advanced-marker-icon {
    filter: drop-shadow(0 0 4px rgba(245, 158, 11, 0.8)) drop-shadow(0 0 8px rgba(245, 158, 11, 0.5));
  }

  .mapWrapper.ai-build-hiding-pois.svelte-7sr3kz .custom-advanced-marker:not([data-ai-build-marker='true']) {
    opacity: 0;
    transform: translateY(20px) scale(0.75);
    transition: opacity 0.24s ease, transform 0.24s ease;
    pointer-events: none;
  }

  .ai-build-icon-marker {
    position: relative;
    transform: translateY(20px) scale(0);
    transform-origin: center bottom;
    animation: svelte-7sr3kz-ai-build-pop-in 0.46s cubic-bezier(0.2, 0.9, 0.24, 1.18) forwards;
    filter: drop-shadow(0 10px 18px rgba(15, 23, 42, 0.24));
    user-select: none;
  }

  .ai-build-icon-marker__icon {
    display: block;
    width: 46px;
    height: 40px;
  }

  .ai-build-icon-marker__fallback {
    width: 46px;
    height: 46px;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
    color: #0f172a;
    font-family: 'Open Sans', sans-serif;
    font-size: 18px;
    font-weight: 700;
    border: 3px solid rgba(255, 255, 255, 0.96);
    box-shadow: 0 10px 20px rgba(15, 23, 42, 0.22);
  }

  .ai-build-icon-marker::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 38%;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    transform: translate(-50%, -50%);
    background: rgba(59, 130, 246, 0.12);
    box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.18);
    animation: svelte-7sr3kz-ai-build-ring 1.7s ease-out infinite;
    z-index: -1;
  }

  .ai-build-icon-marker--start .ai-build-icon-marker__icon {
    width: 58px;
    height: 50px;
  }

  .ai-build-icon-marker--winner .ai-build-icon-marker__icon {
    width: 54px;
    height: 46px;
  }

  .ai-build-icon-marker--day .ai-build-icon-marker__icon {
    width: 62px;
    height: 54px;
  }

  .ai-build-icon-marker--stop .ai-build-icon-marker__icon {
    width: 38px;
    height: 32px;
  }

  .ai-build-icon-marker--start::after {
    background: rgba(13, 148, 136, 0.14);
    box-shadow: 0 0 0 0 rgba(13, 148, 136, 0.18);
  }

  .ai-build-icon-marker--winner::after,
  .ai-build-icon-marker--day::after {
    background: rgba(37, 99, 235, 0.14);
    box-shadow: 0 0 0 0 rgba(37, 99, 235, 0.18);
  }

  .ai-build-icon-marker__label {
    position: absolute;
    top: -9px;
    right: -8px;
    min-width: 24px;
    height: 24px;
    border-radius: 999px;
    padding: 0 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #0f172a;
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.96);
    box-shadow: 0 8px 16px rgba(15, 23, 42, 0.2);
    font-family: 'Open Sans', sans-serif;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.03em;
  }

  .ai-build-icon-marker__score {
    position: absolute;
    bottom: -8px;
    left: 50%;
    transform: translateX(-50%);
    min-width: 20px;
    height: 16px;
    border-radius: 8px;
    padding: 0 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #3b82f6;
    color: white;
    border: 1.5px solid rgba(255, 255, 255, 0.96);
    box-shadow: 0 2px 6px rgba(59, 130, 246, 0.3);
    font-family: 'Open Sans', sans-serif;
    font-size: 7.5px;
    font-weight: 700;
    line-height: 1;
  }

  @keyframes svelte-7sr3kz-ai-build-pop-in {
    0% {
      transform: translateY(20px) scale(0);
      opacity: 0;
    }
    65% {
      transform: translateY(20px) scale(1.22);
      opacity: 1;
    }
    100% {
      transform: translateY(20px) scale(1);
      opacity: 1;
    }
  }

  @keyframes svelte-7sr3kz-ai-build-ring {
    0% {
      transform: translate(-50%, -50%) scale(0.78);
      opacity: 0.7;
    }
    75% {
      transform: translate(-50%, -50%) scale(1.9);
      opacity: 0;
    }
    100% {
      transform: translate(-50%, -50%) scale(1.9);
      opacity: 0;
    }
  }


  .map-loading-indicator.svelte-1h9cs4g {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* Fits inside the chrome band's 8px of top padding (AppChrome.svelte's
       `--map-chrome-h: 60px` with `padding: 8px 10px`), so it sits above the
       logo pill rather than over any control or any map pixel the chrome was
       not already covering. */
    height: 3px;
    background-color: var(--color-fm-red, #e11d48);
    /* Above the map chrome band (z-mapchrome, 100) and below z-confirm
       (1200), so no dialog, picker or modal is ever crossed by a 3px line. */
    z-index: 1150;
    pointer-events: none;
    opacity: 0;
    /* The ONLY motion in this element, and it is a fade of the indicator
       itself — not of anything laid over the canvas. Mounted permanently at
       opacity 0 so the transition has a baseline from first paint. */
    transition: opacity 0.2s ease-in-out;
  }

  .map-loading-indicator.is-busy.svelte-1h9cs4g {
    opacity: 1;
  }

  @media (prefers-reduced-motion: reduce) {
    .map-loading-indicator.svelte-1h9cs4g {
      transition: none;
    }
  }

