/*!
 * A2Z Dispatch — Widget Embed Stylesheet
 * Loaded by widget.js before the embed HTML is injected.
 * This extracts the inline styles from layouts/booking-tool.blade.php so they
 * are available in cross-origin embed context (no full page layout is rendered).
 */

/* ── Palette tokens ──────────────────────────────────────────────────────── */
#widget-vue-body {
    --bt-bg:     #FAF7F3;
    --bt-card:   #FFFFFF;
    --bt-border: #EEE5DD;
    --bt-soft:   #FFF3E8;
    --bt-text:   #2F2A26;
    --bt-muted:  #6F625B;

    /* Layout/theme tokens (brand-primary/hover/light injected by server) */
    --brand-dark: #121214;
    --text-main: #2a2a2e;
    --text-muted: #6c6c74;
    --bg-light: #f5f6f8;
    --input-bg: #ffffff;
    --input-border: #D0C4BB;
    /* Outline of anything you type in or pick from — kept separate from
       --bt-border (cards, dividers, rules) so the two can diverge by theme.
       On white, --bt-border already reads as a border; on the near-black dark
       card the same #2c2c35 disappeared, and the fields lost their edges. This
       is that value in light, so nothing moves there. */
    --field-border: #EEE5DD;
    /* The hairline under a field in Appearance › Form Fields › Underline. Its
       own token rather than reusing --field-border because a lone rule has to
       carry the whole field on its own — there is no box, no fill and no
       shadow left to help it — so it wants more contrast than a box edge did,
       in both themes. --input-border is exactly that value and had no consumer
       left but the dead .input-box block. */
    --bt-field-line: var(--input-border);
    --bt-field-line-focus: var(--brand-primary);
    --scrollbar-thumb: #d1d5db;

    /* Responsive layout tokens */
    --shadow-soft: 0 4px 20px rgba(0,0,0,0.04);
    --shadow-medium: 0 12px 30px rgba(0,0,0,0.08);
    --shadow-premium: 0 24px 60px rgba(18, 18, 20, 0.12);
    --radius-pill: 100px;
    --radius-lg: 28px;
    --radius-md: 16px;
    --transition-smooth: all 0.35s cubic-bezier(0.25, 0.8, 0.25, 1);

    /* ── Advanced appearance tokens ───────────────────────────────────────
       Set from Booking Widget › Appearance and injected by the server (see
       partials/_theme-tokens.blade.php). The values below are the widget's
       historical look, so an install that has configured nothing renders
       exactly as it always has — that is the contract, and every consumer
       below spells its own fallback out again as `var(--token, <old value>)`
       so it survives even if this block is somehow missing.

       Note --bt-btn-bg is a `background`, not a `background-color`: it holds
       either a flat colour or a linear-gradient(), and only the shorthand
       accepts both. Any button reading it must use `background:`.
       ─────────────────────────────────────────────────────────────────────── */
    --bt-font-body:      "DM Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --bt-font-heading:   var(--bt-font-body);
    --bt-heading-weight: 700;
    --bt-btn-font:       var(--bt-font-body);
    --bt-btn-weight:     700;
    --bt-btn-transform:  uppercase;
    --bt-btn-pad-y:      14px;
    --bt-btn-pad-x:      28px;
    --bt-btn-size:       15px;
    --bt-field-radius:   0px;
    --bt-btn-radius:     0px;
    --bt-btn-bg:         var(--brand-primary);
    --bt-btn-bg-hover:   var(--brand-primary-hover);

    position: relative;
    width: 100%;
    height: 100%;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    /* The widget paints its own ground rather than borrowing the page's. On the
       standalone page <body> already carried the theme, but the embed is a
       fragment inside somebody else's container — a host card with its own
       `background: #f9f9f9` showed straight through the step padding, so a dark
       or system-dark widget rendered with white gutters down both sides. */
    background: var(--bt-bg);
    color: var(--bt-text);
    font-family: var(--bt-font-body, "DM Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
}

/* ── Card/surface overrides ──────────────────────────────────────────────── */
#widget-vue-body .bt-card {
    background: var(--bt-card);
    border: 1px solid var(--bt-border);
}

#widget-vue-body .bt-soft { background: var(--bt-soft); }

#widget-vue-body .border-gray-100,
#widget-vue-body .border-gray-200 { border-color: var(--bt-border); }

#widget-vue-body .text-gray-800,
#widget-vue-body .text-gray-700   { color: var(--bt-text); }

#widget-vue-body .text-gray-500,
#widget-vue-body .text-gray-400   { color: var(--bt-muted); }

/* ── Form-container shadow ───────────────────────────────────────────────── */
.form-container { box-shadow: 0 12px 28px rgba(100,102,107,.3); }

/* ── Auth modal ──────────────────────────────────────────────────────────── */
.modal {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .5);
    z-index: 1000;
    align-items: center;
    justify-content: center;
}

.modal.active { display: flex; }

.modal-content {
    background: #fff;
    border-radius: 1.25rem;
    max-width: 380px;
    width: 90%;
    max-height: 90vh;
    overflow-y: auto;
}

/* ── Fix Google Maps tile sizing (Tailwind preflight resets max-width) ───── */
.gm-style img { max-width: none !important; }

/* Hide the InfoWindow close "×" — pickup/dropoff address labels are toggled
   by clicking their marker instead (see attachMarkerLabel in the widget JS). */
.gm-ui-hover-effect { display: none !important; }

/* Google's InfoWindow wraps content in its own fixed-size scroll container;
   let our label div's own sizing (mkMapLabel) control the box instead so the
   full address shows without an inner scrollbar. */
.gm-style-iw-d { overflow: visible !important; max-height: none !important; max-width: none !important; }
.gm-style-iw-c { max-width: none !important; max-height: none !important; }

/* ── Focus states ────────────────────────────────────────────────────────── */
#widget-vue-body input:focus,
#widget-vue-body select:focus,
#widget-vue-body textarea:focus {
    outline: none !important;
    box-shadow: none !important;
    border-color: transparent !important;
}

button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--brand-primary) 40%, transparent);
    outline-offset: 2px;
}

/* ── Visible-hidden helper (prevents FOUC before Vue mounts) ─────────────── */
.visible-hidden { visibility: hidden; }

/* ── Pre-mount skeleton ───────────────────────────────────────────────────
   #widget-skeleton is plain HTML — no Vue directives — placed as a sibling
   BEFORE #widget-vue-body in both index.blade.php and embed.blade.php. It
   paints immediately (before Vue, jQuery, flatpickr, Maps, etc. even finish
   loading) and covers the same header + quote-card + map shape as the real
   step-1 view so the visitor sees a shaped placeholder instead of a blank
   page. Removed outright in the `mounted()` hook, right where `isMounted`
   flips true — same moment `.visible-hidden` lifts off the real widget.
   Deliberately NOT scoped under #widget-vue-body (mirrors the admin
   fm-sk/fleet-manager skeleton) and uses literal colors for the same reason. */
#widget-skeleton {
    position: fixed;
    inset: 0;
    z-index: 99999;
    background: #f9f9f9;
    display: flex;
    flex-direction: column;
    /* Mirrors #widget-vue-body.step-1's own side padding (widget.css ~line 138)
       so the loader's card/map split sits at the same inset as the real one
       instead of running flush to the viewport edge on wide screens. */
    padding: 0 clamp(16px, calc((100vw - 1000px) / 2), 280px);
    box-sizing: border-box;
}

/* Script-embed variant. `position: fixed` is right for the standalone page,
   where the widget IS the page — in an embed it made the loader cover the
   host's header, hero and everything else until Vue mounted. Anchored to the
   container widget.js was pointed at instead (that element is given
   `position: relative` by widget.js before the fragment is injected), so it
   covers the widget's own box and nothing of the page around it. */
#widget-skeleton.wsk-embed {
    position: absolute;
    /* z-index stays at the base rule's 99999 on purpose. #widget-vue-body is
       `position: relative` with `z-index: auto`, so it opens no stacking context
       and its modals (.modal at 1000, .bk-modal above that) sit in the root one —
       anything lower here lets the un-mounted, un-hidden widget markup paint over
       the loader. Being absolute rather than fixed already confines it to the
       widget's own box, which was the point. */
}

/* The skeleton sits OUTSIDE #widget-vue-body, so it cannot read the --bt-*
   tokens and has to carry the palette itself — otherwise a dark-themed widget
   flashes a full white loader before it mounts. Both `data-theme` and
   `data-scheme` are stamped on this element too by both blades for exactly
   this — see the note on the dark palette block further down for why the
   surface rules key on the computed scheme rather than the operator's radio. */
#widget-skeleton[data-scheme="dark"]                { background: #121214; }
#widget-skeleton[data-scheme="dark"] .wsk-header,
#widget-skeleton[data-scheme="dark"] .wsk-card      { background: #1a1a1e; }
#widget-skeleton[data-scheme="dark"] .wsk-header    { border-bottom-color: #2c2c35; }
#widget-skeleton[data-scheme="dark"] .wsk-map       { background: #17171b; }
#widget-skeleton[data-scheme="dark"] .wsk-sk        { background: #24242b; }
#widget-skeleton[data-scheme="dark"] .wsk-sk:after  { background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.06), rgba(255,255,255,0)); }
#widget-skeleton[data-scheme="dark"] .wsk-field     { border-color: #2c2c35; }

@media (prefers-color-scheme: dark) {
    #widget-skeleton[data-theme="system"]                { background: #121214; }
    #widget-skeleton[data-theme="system"] .wsk-header,
    #widget-skeleton[data-theme="system"] .wsk-card      { background: #1a1a1e; }
    #widget-skeleton[data-theme="system"] .wsk-header    { border-bottom-color: #2c2c35; }
    #widget-skeleton[data-theme="system"] .wsk-map       { background: #17171b; }
    #widget-skeleton[data-theme="system"] .wsk-sk        { background: #24242b; }
    #widget-skeleton[data-theme="system"] .wsk-sk:after  { background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.06), rgba(255,255,255,0)); }
    #widget-skeleton[data-theme="system"] .wsk-field     { border-color: #2c2c35; }
}
.wsk-header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 36px;
    padding: 12px clamp(16px, 3vw, 40px);
    background: #fff;
    border-bottom: 1px solid #EEE5DD;
}
.wsk-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: row;
}
.wsk-card {
    flex: 0 0 440px;
    width: 440px;
    max-width: 440px;
    display: flex;
    flex-direction: column;
    background: #fff;
    box-shadow: 0 12px 30px rgba(0, 0, 0, .08);
    padding: 28px 24px;
    box-sizing: border-box;
    gap: 20px;
}
.wsk-tabs { display: flex; gap: 28px; margin-top: 4px; }
.wsk-fields { display: flex; flex-direction: column; gap: 10px; flex: 1; }
.wsk-fields > .wsk-label { margin-top: 10px; }
.wsk-fields > .wsk-label:first-child { margin-top: 0; }
.wsk-when { display: flex; gap: 6px; }
.wsk-datetime { display: flex; gap: 6px; }
.wsk-footer { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.wsk-map {
    flex: 1 1 auto;
    min-width: 0;
    background: #eae7e1;
}

/* Shimmer bar — same recipe as the admin fm-sk skeleton. */
.wsk-sk {
    position: relative;
    overflow: hidden;
    display: block;
    background: #EEF0EE;
}
.wsk-sk:after {
    content: '';
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.7), rgba(255,255,255,0));
    animation: wsk-shimmer 1.3s infinite;
}
@keyframes wsk-shimmer { 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .wsk-sk:after { animation: none; } }

.wsk-field { height: 46px; border: 1.5px solid #EEE5DD; box-sizing: border-box; }
.wsk-field.wsk-dashed { border-style: dashed; background: none; }
.wsk-pill { height: 40px; border-radius: 100px; }
.wsk-cta { height: 48px; }

@media (max-width: 640px) {
    .wsk-body { flex-direction: column; }
    .wsk-card { width: 100%; max-width: 100%; flex: 1 1 auto; box-shadow: none; }
    .wsk-map { display: none; }
}

/* ── Spinner animation used by the booking overlay ──────────────────────── */
@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ── Responsive Mobile App-Like UX Styles ────────────────────────────────── */

/* 1. Global Setup & Step-1 (Quote form + route map split) Styles.
   The `bq-*` component styling for the quote step lives in its own section
   further down ("Quote Step (bq-)"). */
#widget-vue-body.step-1 {
    justify-content: initial;
    align-items: initial;
    /* Edge padding is whatever is LEFT OVER once both columns fit, not a flat
       share of the viewport. The split needs ~1000px (400px .bk-side + ~600px
       .bk-main) to keep vehicle rows on one line, so a `20vw` term kept stealing
       width that wasn't spare and crushed .bk-main on laptops/tablets. Bottoms
       out at 16px around 1032px, where the ≤1024 full-bleed block takes over. */
    padding: 0 clamp(16px, calc((100vw - 1000px) / 2), 280px);
}

#widget-vue-body.step-1 .a2z-step-1-wrapper {
    /* Flex, not block: .bq-split below sizes itself with flex: 1, because a
       percentage height would resolve against this box's `height: auto` (its
       used height comes from flex) and collapse the split to content height. */
    display: flex;
    flex-direction: column;
    width: 100%;
    flex: 1;
    min-height: 0;
}

#widget-vue-body.step-1 .a2z-stepper-wrapper {
    display: none !important;
}

/* Hide the step-2+ route map wrapper in Step 1 */
#widget-vue-body.step-1 .a2z-map-wrapper {
    display: none !important;
}

/* 2. Step Container (Step 2 Onwards) Layouts */
.a2z-step-container {
    position: relative;
    width: 100%;
    transition: var(--transition-smooth);
}

/* 3. Responsive Adaptations */

/* DESKTOP VIEWPORT LAYOUT */
@media (min-width: 1025px) {
    /* The root keeps the hard viewport height and clips; .bkh-body is a flex
       child that takes whatever the top bar leaves (its height grows as the
       inline sign-in form expands), giving the columns a definite box to
       scroll inside. Root stays column (base) so the bar sits above the body. */
    #widget-vue-body:not(.step-1) {
        height: 100dvh;
        overflow: hidden;
    }

    #widget-vue-body:not(.step-1) .a2z-stepper-wrapper {
        position: absolute;
        top: 20px;
        left: 480px;
        right: 40px;
        z-index: 20;
        max-width: none;
    }

    #widget-vue-body:not(.step-1) .a2z-step-container {
        display: flex;
        flex-direction: row;
        width: 100%;
        height: 100%;
        gap: 0 !important;
        max-width: none !important;
        margin: 0 !important;
    }

    #widget-vue-body:not(.step-1) .a2z-panel-container {
        width: 30%;
        height: 100%;
        border-left: 1px solid var(--bt-border);
        box-shadow: var(--shadow-medium);
        display: flex;
        flex-direction: column;
        z-index: 10;
    }

    #widget-vue-body:not(.step-1) .a2z-map-wrapper {
        flex: 1 !important;
        height: 100% !important;
        position: relative !important;
    }
}

/* TABLET VIEWPORT LAYOUT */
@media (min-width: 641px) and (max-width: 1024px) {
    #widget-vue-body:not(.step-1) {
        position: relative;
        height: 100dvh;
        overflow: hidden;
    }

    #widget-vue-body:not(.step-1) .a2z-stepper-wrapper {
        position: absolute;
        top: 24px;
        left: 456px;
        right: 32px;
        z-index: 20;
        max-width: none;
    }

    #widget-vue-body:not(.step-1) .a2z-step-container {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        gap: 0 !important;
        max-width: none !important;
        margin: 0 !important;
    }

    #widget-vue-body:not(.step-1) .a2z-map-wrapper {
        position: absolute !important;
        inset: 0 !important;
        width: 100% !important;
        height: 100% !important;
        z-index: 1;
    }

    #widget-vue-body:not(.step-1) .a2z-panel-container {
        position: absolute;
        left: 32px;
        top: 32px;
        bottom: 32px;
        width: 400px;
        height: calc(100% - 64px);
        border-radius: 0 !important;
        border: 1px solid var(--bt-border);
        box-shadow: var(--shadow-premium);
        z-index: 10;
        display: flex;
        flex-direction: column;
        background: var(--bt-card);
        overflow: hidden;
    }
}

/* MOBILE VIEWPORT LAYOUT (NATIVE MOBILE APP STYLE) */
@media (max-width: 640px) {
    #widget-vue-body {
        position: relative;
        height: 100dvh;
        overflow: hidden;
        background: var(--bt-card);
    }

    /* Root owns the viewport box; the step content takes what the top bar leaves. */
    #widget-vue-body .bkh-body {
        flex: 1 1 auto;
        min-height: 0;
        overflow: hidden;
    }

    /* Step 1 on mobile: form fills the viewport (the bq- section handles the
       column layout + in-card map). */
    #widget-vue-body.step-1 {
        padding: 0 !important;
    }

    #widget-vue-body:not(.step-1) .a2z-stepper-wrapper {
        position: absolute;
        top: 12px;
        left: 16px;
        right: 16px;
        z-index: 20;
        margin-bottom: 0 !important;
    }

    #widget-vue-body:not(.step-1) .a2z-step-container {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        gap: 0 !important;
        max-width: none !important;
        margin: 0 !important;
    }

    #widget-vue-body:not(.step-1) .a2z-map-wrapper {
        position: absolute !important;
        top: 0;
        left: 0;
        width: 100% !important;
        height: 50% !important; /* Map sits on top half */
        z-index: 1;
    }

    #widget-vue-body:not(.step-1) .a2z-panel-container {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        height: 55%; /* Minimized height when map is visible */
        border-top-left-radius: 0 !important;
        border-top-right-radius: 0 !important;
        border-bottom-left-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
        box-shadow: 0 -8px 30px rgba(0,0,0,0.12);
        z-index: 10;
        background: var(--bt-card);
        display: flex;
        flex-direction: column;
        transition: height 0.4s cubic-bezier(0.25, 1, 0.5, 1), border-radius 0.4s cubic-bezier(0.25, 1, 0.5, 1);
        overflow: hidden;
    }

    /* Expanded bottom sheet class (covers full height, hides map) */
    #widget-vue-body:not(.step-1) .a2z-panel-container.expanded {
        height: 100%;
        border-top-left-radius: 0 !important;
        border-top-right-radius: 0 !important;
    }

    /* Display drag handle as a clickable arrow button */
    .sheet-drag-handle {
        display: flex !important;
        justify-content: center;
        align-items: center;
        padding: 12px 0 6px;
        cursor: pointer;
        background: var(--bt-card);
    }
    .sheet-drag-handle i {
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: #f3f4f6;
        color: #9ca3af;
        font-size: 14px;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: background-color 0.2s ease, color 0.2s ease, transform 0.3s ease;
    }
    .sheet-drag-handle:hover i {
        background-color: var(--brand-primary-light);
        color: var(--brand-primary);
    }

}

/* 4. Common Panel & Scrolling Classes */
.a2z-scrollable-content {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.sheet-drag-handle {
    display: none;
}

/* Hide sidebar summary on mobile and tablet to prevent clutter */
@media (max-width: 1024px) {
    #widget-vue-body .a2z-sidebar-summary {
        display: none !important;
    }
}

/* ── Step 1 Form Styling (Mockup Port) ── */
#widget-vue-body .segment-tabs {
    display: flex;
    background-color: var(--bg-light);
    border-radius: var(--radius-pill);
    padding: 4px;
    border: 1px solid var(--border-color);
    margin-bottom: 8px;
}
#widget-vue-body .tab-btn {
    flex: 1;
    background: none;
    border: none;
    padding: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: var(--radius-pill);
    transition: var(--transition-smooth);
    text-align: center;
}
#widget-vue-body .tab-btn.active {
    background-color: #ffffff;
    color: var(--brand-primary);
    box-shadow: var(--shadow-soft);
}
#widget-vue-body .input-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
#widget-vue-body .input-label {
    font-size: 12px;
    font-weight: 700;
    color: var(--brand-dark);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: left;
}
#widget-vue-body .input-label.normal-case {
    text-transform: none;
    letter-spacing: normal;
}
#widget-vue-body .input-box {
    display: flex;
    align-items: center;
    background-color: var(--input-bg);
    border: 1.5px solid var(--input-border);
    border-radius: var(--bt-field-radius, 0);
    padding: 10px 14px;
    transition: var(--transition-smooth);
    width: 100%;
}
#widget-vue-body .input-box:focus-within {
    background-color: var(--input-bg);
    border-color: var(--brand-primary);
    box-shadow: 0 0 0 3px var(--brand-primary-light);
}
#widget-vue-body .input-icon-circle {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: var(--bg-light);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 12px;
    box-shadow: var(--shadow-soft);
    color: var(--brand-primary);
    font-size: 13px;
    flex-shrink: 0;
}
#widget-vue-body .input-field-wrapper {
    flex: 1;
    display: flex;
    flex-direction: column;
    text-align: left;
    min-width: 0;
}
#widget-vue-body .input-field-wrapper span {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-muted);
}
#widget-vue-body .input-box input,
#widget-vue-body .input-box select {
    width: 100%;
    border: none !important;
    background: none !important;
    outline: none !important;
    color: var(--text-main);
    font-size: 14px;
    font-weight: 600;
    padding: 0 !important;
    margin: 0 !important;
    box-shadow: none !important;
}
#widget-vue-body .add-stop-trigger {
    background: none;
    border: none;
    color: var(--brand-primary);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    align-self: flex-start;
    padding: 4px 8px;
    border-radius: 6px;
    transition: var(--transition-smooth);
    margin-top: 4px;
    margin-bottom: 4px;
}
#widget-vue-body .add-stop-trigger:hover {
    background-color: var(--brand-primary-light);
}
#widget-vue-body .vias-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
#widget-vue-body .via-input-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}
#widget-vue-body .via-input-row .input-box {
    flex: 1;
}
#widget-vue-body .remove-via-btn {
    background-color: #fee2e2;
    color: #ef4444;
    border: none;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: var(--transition-smooth);
    flex-shrink: 0;
}
#widget-vue-body .remove-via-btn:hover {
    background-color: #fecaca;
}
#widget-vue-body .toggle-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 0;
    width: 100%;
}
#widget-vue-body .toggle-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: left;
}
#widget-vue-body .toggle-info span.title {
    font-size: 13px;
    font-weight: 700;
    color: var(--brand-dark);
}
#widget-vue-body .toggle-info span.desc {
    font-size: 11px;
    color: var(--text-muted);
}
#widget-vue-body .switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
}
#widget-vue-body .switch input { opacity: 0; width: 0; height: 0; }
#widget-vue-body .slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background-color: #e4e4e7;
    transition: .3s;
    border-radius: 34px;
}
#widget-vue-body .slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: .3s;
    border-radius: 50%;
}
#widget-vue-body input:checked + .slider { background-color: var(--brand-primary); }
#widget-vue-body input:checked + .slider:before { transform: translateX(20px); }

/* ── Step 2: Fleet Selection ── */
#widget-vue-body .fleet-filter-chip {
    background-color: var(--bg-light);
    border: 1px solid var(--border-color);
    padding: 6px 14px;
    border-radius: 0;
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: var(--transition-smooth);
    flex-shrink: 0;
}
#widget-vue-body .fleet-filter-chip.active {
    background-color: var(--brand-dark);
    color: #ffffff;
    border-color: var(--brand-dark);
}
#widget-vue-body .fleet-card-new {
    border: 1.5px solid var(--border-color);
    border-radius: 0;
    padding: 16px;
    display: flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    transition: var(--transition-smooth);
    background-color: var(--bg-light);
    width: 100%;
}
#widget-vue-body .fleet-card-new:hover {
    border-color: var(--brand-primary);
}
#widget-vue-body .fleet-card-new.selected {
    border: 2px solid var(--brand-primary) !important;
    background-color: var(--brand-primary-light);
}
#widget-vue-body .fleet-name-new {
    display: block;
    font-size: 15px;
    font-weight: 700;
    color: var(--brand-dark);
    line-height: 1.2;
}
#widget-vue-body .fleet-specs-new {
    display: flex;
    gap: 12px;
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 600;
    margin-top: 5px;
}
#widget-vue-body .fleet-price-val {
    font-size: 18px;
    font-weight: 800;
    color: var(--brand-dark);
    line-height: 1;
}
#widget-vue-body .fleet-price-lbl {
    display: block;
    font-size: 9px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.3px;
    margin-top: 3px;
}

/* ══════════════════════════════════════════════════════════════════════════
   Quote Step (bq-)
   Full rebuild of the step-1 quote view. Split layout + all form components,
   in the widget's own language (brand tokens, DM Sans, sharp corners, round
   pills). The map canvas #quote-map is the JS contract (desktop split only —
   narrow viewports render no map at all).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Split layout ─────────────────────────────────────────────────────────── */
#widget-vue-body.step-1 .bq-split {
    display: flex;
    flex-direction: row;
    width: 100%;
    /* Takes the space .bkh-body has left after the top bar, rather than a flat
       100dvh — the bar's height changes as the inline sign-in form expands. */
    flex: 1 1 auto;
    min-height: 0;
}
#widget-vue-body.step-1 .bq-card {
    flex: 0 0 440px;
    width: 440px;
    max-width: 440px;
    /* stretch, not height:100% — .bq-split is flex-sized, so a percentage
       height here resolves to auto and collapses the card to its content. */
    align-self: stretch;
    background: var(--bt-card);
    box-shadow: var(--shadow-medium);
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
}
#widget-vue-body.step-1 .bq-map {
    position: relative;
    overflow: hidden;
    background: #eae7e1;
}
#widget-vue-body.step-1 .bq-map--desktop {
    flex: 1 1 auto;
    min-width: 0;
    align-self: stretch;
}
#widget-vue-body.step-1 .bq-map--desktop .bq-map-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

/* ── Card internals ───────────────────────────────────────────────────────── */
#widget-vue-body .bq-head { flex-shrink: 0; padding: 28px 24px 0; }
#widget-vue-body .bq-form { display: flex; flex-direction: column; flex: 1; min-height: 0; }
#widget-vue-body .bq-scroll {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 20px 24px 8px;
    scrollbar-width: none;
}
#widget-vue-body .bq-scroll::-webkit-scrollbar { display: none; }
#widget-vue-body .bq-footer {
    position: sticky;
    bottom: 0;
    z-index: 20;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 16px 24px;
    background: var(--bt-card);
}

/* ── Headline + tabs (active = dot, not underline) ────────────────────────── */
#widget-vue-body .bq-headline {
    font-size: 26px;
    line-height: 1.18;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--bt-text);
    margin-bottom: 20px;
}
#widget-vue-body .bq-tabs { display: flex; gap: 28px; }
#widget-vue-body .bq-tab {
    position: relative;
    background: none;
    border: none;
    padding: 2px 0 14px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--bt-muted);
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .bq-tab.is-active { color: var(--bt-text); }
#widget-vue-body .bq-tab.is-active::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 3px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--brand-primary);
    transform: translateX(-50%);
}

/* ── Sections + labels ────────────────────────────────────────────────────── */
#widget-vue-body .bq-section { display: flex; flex-direction: column; gap: 10px; }
#widget-vue-body .bq-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--bt-muted);
}
#widget-vue-body .bq-label--normal { text-transform: none; letter-spacing: normal; }
#widget-vue-body .bq-error { font-size: 11px; line-height: 1.3; color: #ef4444; margin-top: -8px; }
/* A stop's message sits inside the .bq-vias column, which supplies its own gap
   — the pull-up above would drag it onto the row it belongs to. */
#widget-vue-body .bq-error--row { margin-top: 0; }
/* The Book step's own field messages. .bk-fields / .bk-contact-fields are gapped
   grids, so this one pushes down from its field rather than up towards it. */
#widget-vue-body .bk-error { font-size: 11px; line-height: 1.3; color: #ef4444; margin: 5px 0 0; }
#widget-vue-body .bq-helper { font-size: 11.5px; line-height: 1.5; color: var(--bt-muted); }
#widget-vue-body .bq-helper--center { text-align: center; }

/* ── Invalid fields ───────────────────────────────────────────────────────
   A message under a field is easy to miss on a form this long, so the shell is
   marked too. Both field styles carry the mark in the edge they already draw —
   the box in Boxed, the rule in Underline (further down, after the underline
   overrides) — so neither grows a border it does not otherwise have. */
#widget-vue-body .bq-field.is-invalid,
#widget-vue-body .bk-field.is-invalid { border-color: #ef4444; }
#widget-vue-body .bq-field.is-invalid:focus-within,
#widget-vue-body .bk-field.is-invalid:focus-within {
    border-color: #ef4444;
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.16);
}

/* ── Fields ───────────────────────────────────────────────────────────────── */
#widget-vue-body .bq-field {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-width: 0;
    background: var(--input-bg);
    border: 1.5px solid var(--field-border);
    border-radius: var(--bt-field-radius, 0);
    padding: 13px 16px;
    box-sizing: border-box;
    transition: var(--transition-smooth);
}
#widget-vue-body .bq-field:focus-within {
    border-color: var(--brand-primary);
    box-shadow: 0 0 0 3px var(--brand-primary-light);
}
#widget-vue-body .bq-field--grow { flex: 1; }
#widget-vue-body .bq-field.is-disabled { opacity: 0.6; }
#widget-vue-body .bq-field input,
#widget-vue-body .bq-field select {
    flex: 1;
    min-width: 0;
    border: none !important;
    background: none !important;
    outline: none !important;
    box-shadow: none !important;
    font-size: 14px;
    font-weight: 500;
    color: var(--bt-text);
    padding: 0 !important;
    margin: 0 !important;
    -webkit-appearance: none;
    appearance: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
#widget-vue-body .bq-field input::placeholder { color: #9c9490; }
#widget-vue-body .bq-field-ico { font-size: 13px; color: var(--bt-muted); flex-shrink: 0; }

/* ── Clear an address ─────────────────────────────────────────────────────
   A circular X inside the field, revealed on hover or focus. Sized and styled
   deliberately UNLIKE a stop's 32px outlined .bq-remove-stop sitting a few
   pixels away: that one deletes the whole row, this one only empties the box,
   and the two must not read as the same button. */
#widget-vue-body .bq-clear {
    flex: none;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--bt-soft, rgba(0, 0, 0, 0.06));
    color: var(--bt-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    line-height: 1;
    cursor: pointer;
    /* visibility, not display: a hidden flex item still holds its 20px, so the
       address text does not reflow the moment the pointer arrives. */
    opacity: 0;
    visibility: hidden;
    transition: var(--transition-smooth);
}
#widget-vue-body .bq-clear:hover { background: var(--brand-primary); color: #fff; }
#widget-vue-body .bq-field:hover .bq-clear,
#widget-vue-body .bq-field:focus-within .bq-clear { opacity: 1; visibility: visible; }
/* An empty field has nothing to clear. Outside the reveal above rather than
   folded into it, so that where :has() is missing the button still appears on
   hover — offering it on an empty box is a smaller failure than never offering
   it at all, and pressing it there does nothing. */
@supports selector(:has(*)) {
    #widget-vue-body .bq-field:has(input:placeholder-shown) .bq-clear { opacity: 0; visibility: hidden; }
}
#widget-vue-body .bq-field-ico--plane { color: #60a5fa; }

/* Endpoint dots */
#widget-vue-body .bq-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    border: 2px solid var(--bt-muted);
    flex-shrink: 0;
}
#widget-vue-body .bq-dot--filled { border: none; background: var(--brand-primary); }
#widget-vue-body .bq-dot--muted { border-color: #d1d5db; }

/* ── Via points ───────────────────────────────────────────────────────────── */
#widget-vue-body .bq-vias { display: flex; flex-direction: column; gap: 10px; }
/* One stop: its row, and under it whatever that row has to say for itself. */
#widget-vue-body .bq-via { display: flex; flex-direction: column; gap: 6px; }
#widget-vue-body .bq-via-row { display: flex; align-items: center; gap: 8px; }
#widget-vue-body .bq-remove-stop {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1.5px solid var(--field-border);
    background: var(--input-bg);
    color: #9ca3af;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .bq-remove-stop:hover { background: #fee2e2; color: #ef4444; border-color: #fecaca; }
#widget-vue-body .bq-add-stop {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    background: none;
    border: 1.5px dashed var(--field-border);
    padding: 13px 16px;
    font-size: 13px;
    font-weight: 700;
    color: var(--brand-primary);
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .bq-add-stop:hover { background: var(--brand-primary-light); }

/* ── Pills (Now/Later + duration presets) ─────────────────────────────────── */
#widget-vue-body .bq-pills,
#widget-vue-body .bq-when { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
#widget-vue-body .bq-datetime { display: flex; align-items: center; gap: 6px; flex: 1 1 0; min-width: 0; }
#widget-vue-body .bq-datetime .bq-field { padding: 11px 12px; }
#widget-vue-body .bq-pill {
    flex-shrink: 0;
    padding: 11px 16px;
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-weight: 700;
    background: var(--bg-light);
    color: var(--text-muted);
    border: none;
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .bq-pill.is-active { background: var(--brand-primary); color: #fff; }

/* ── Return ───────────────────────────────────────────────────────────────── */
#widget-vue-body .bq-check { display: flex; align-items: center; gap: 10px; }
#widget-vue-body .bq-check input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--brand-primary);
    cursor: pointer;
}
#widget-vue-body .bq-check label { font-size: 13px; font-weight: 700; color: var(--bt-text); cursor: pointer; }
#widget-vue-body .bq-return { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

/* ── Flight (step 1) ──────────────────────────────────────────────────────
   Only the number field and the spinner are styled here: the matched legs reuse
   the Book step's .bk-flight-* list, so a flight chosen on either screen looks
   the same. The Verify button this block used to style is gone — the number
   looks itself up once typing settles (see the flightNumber watcher). */
#widget-vue-body .bq-optional {
    margin-left: 6px;
    font-weight: 600;
    letter-spacing: 0.3px;
    text-transform: none;
    opacity: 0.75;
}
#widget-vue-body .bq-flight-spin { font-size: 13px; color: var(--brand-primary); flex: none; }
/* An unmatched number is a note, not a rejection — the quote is still priced —
   so it is warned in amber rather than in the red .bq-error uses for a block.
   Amber is the one warning colour in here dark enough to fail on a dark card, so
   unlike the reds above it needs the scheme's own value. */
#widget-vue-body .bq-helper--warn { color: #b45309; }
#widget-vue-body[data-scheme="dark"] .bq-helper--warn { color: #fbbf24; }
#widget-vue-body .bq-visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); border: 0;
}

/* ── Submit ───────────────────────────────────────────────────────────────── */
#widget-vue-body .bq-submit { text-transform: var(--bt-btn-transform, uppercase); letter-spacing: 0.5px; }
#widget-vue-body .bq-submit.is-loading { opacity: 0.6; cursor: not-allowed; }
#widget-vue-body .bq-spin { width: 16px; height: 16px; animation: spin 1s linear infinite; }

/* ── Mobile: card fills the viewport, and there is no map ──
   The route preview used to drop into the card here, 190px of it above the
   submit button, which pushed the form the visitor is still filling in further
   off a screen that has none to spare. The split's map is a desktop affordance
   and stays one. */
@media (max-width: 640px) {
    #widget-vue-body.step-1 .bq-split { flex-direction: column; }
    #widget-vue-body.step-1 .bq-card {
        flex: 1 1 auto;
        width: 100%;
        max-width: 100%;
        box-shadow: none;
    }
    #widget-vue-body.step-1 .bq-map--desktop { display: none; }
}

/* ── CTA Button (shared across steps) ──
   `background`, not `background-color`: --bt-btn-bg carries either a flat
   colour or a linear-gradient() and only the shorthand accepts both. The glow
   deliberately stays on --brand-primary — a gradient button still wants a
   single accent shadow, and color-mix() cannot take a gradient anyway. */
#widget-vue-body .a2z-cta-btn {
    width: 100%;
    background: var(--bt-btn-bg, var(--brand-primary));
    color: #ffffff;
    border: none;
    border-radius: var(--bt-btn-radius, 0);
    padding: var(--bt-btn-pad-y, 14px) var(--bt-btn-pad-x, 28px);
    font-family: var(--bt-btn-font, inherit);
    font-size: var(--bt-btn-size, 15px);
    font-weight: var(--bt-btn-weight, 700);
    cursor: pointer;
    transition: var(--transition-smooth);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    box-shadow: 0 6px 20px color-mix(in srgb, var(--brand-primary) 25%, transparent);
}
#widget-vue-body .a2z-cta-btn:hover {
    background: var(--bt-btn-bg-hover, var(--brand-primary-hover));
    transform: translateY(-1px);
}

/* ── Brand color overrides for hardcoded Tailwind utility classes ─────────
   Redirects fixed hex classes to the dynamic CSS variable so the admin's
   chosen web_primary_color applies everywhere without editing every template.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body .bg-\[\#ec6408\]               { background-color: var(--brand-primary)       !important; }
#widget-vue-body .bg-brand-primary             { background-color: var(--brand-primary)       !important; }
#widget-vue-body .text-\[\#ec6408\]             { color:            var(--brand-primary)       !important; }
#widget-vue-body .border-\[\#ec6408\]           { border-color:     var(--brand-primary)       !important; }
#widget-vue-body .hover\:bg-\[\#d45607\]:hover  { background-color: var(--brand-primary-hover) !important; }
#widget-vue-body .hover\:text-\[\#ec6408\]:hover{ color:            var(--brand-primary)       !important; }
#widget-vue-body .focus\:border-\[\#ec6408\]:focus { border-color:  var(--brand-primary)       !important; }
#widget-vue-body .bg-\[\#fff5ef\]               { background-color: var(--brand-primary-light)  !important; }

/* ── Dark mode palette overrides (via the data-scheme attribute) ─────────
   Tokens are overridden here; widget.css rules using var(--bt-*) auto-adapt.
   Hardcoded Tailwind utility classes (bg-white, bg-[#f6f6f6] etc.) are also
   overridden so they render correctly on dark backgrounds.

   NOTE the attribute: `data-scheme`, NOT `data-theme`. The two differ, and the
   difference is the point —

     data-theme   what the operator picked in the Theme cards (light/dark/system).
                  Only "system" is still read by CSS, by the prefers-color-scheme
                  blocks below, because that one can only resolve in the browser.
     data-scheme  what the surfaces should ACTUALLY be, computed server-side in
                  widget_theme_config(). It is "dark" when the theme is dark OR
                  when the operator set a dark custom Background colour.

   That second case is why the rename happened: an operator who sets Background
   to #222222 but leaves Theme on Light used to get a black ground with white
   Tailwind cards and near-black text still on it. Keying these rules on the
   resolved scheme makes a dark background darken the whole widget under any
   theme.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body[data-scheme="dark"],
#widget-vue-body[data-theme="system"] {
    /* system default stays light until @media query kicks in below */
}

#widget-vue-body[data-scheme="dark"] {
    --bt-bg:      #121214;
    --bt-card:    #1a1a1e;
    --bt-border:  #2c2c35;
    --bt-soft:    #1e1a16;
    --bt-text:    #f3f4f6;
    --bt-muted:   #9ca3af;
    --brand-dark: #f3f4f6;
    --text-main:  #f3f4f6;
    --text-muted: #9ca3af;
    --bg-light:   #24242b;
    --card-bg:    #1a1a1e;
    --border-color: #2c2c35;
    --scrollbar-thumb: #4b5563;
    --input-bg:     #1a1a1e;
    --input-border: #2c2c35;
    /* Deliberately lighter than --bt-border (#2c2c35). A field's outline has to
       carry the whole shape here — there is no shadow and barely any fill
       contrast against the #1a1a1e card — so it needs more separation than the
       dividers and card edges do, not the same. */
    --field-border: #3f3f4b;
    /* Lighter again than --field-border, for the same reason --field-border is
       lighter than --bt-border: in Underline style the hairline is the entire
       field, with no box or fill left beside it, and #3f3f4b reads as a dead
       edge once that support is gone. */
    --bt-field-line: rgba(255, 255, 255, .28);
    /* Native widgets the page cannot paint itself — the <select> drop-down list,
       scrollbars, the date/time keyboard pickers. Without this the browser keeps
       drawing them on the light system surface while our own `color: var(--bt-text)`
       inherits into the option rows, so the hourly Duration list came out white
       text on white. `option` is restated below because Windows Chrome ignores
       color-scheme for the popup's own rows. */
    color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
    #widget-vue-body[data-theme="system"] {
        --bt-bg:      #121214;
        --bt-card:    #1a1a1e;
        --bt-border:  #2c2c35;
        --bt-soft:    #1e1a16;
        --bt-text:    #f3f4f6;
        --bt-muted:   #9ca3af;
        --brand-dark: #f3f4f6;
        --text-main:  #f3f4f6;
        --text-muted: #9ca3af;
        --bg-light:   #24242b;
        --card-bg:    #1a1a1e;
        --border-color: #2c2c35;
        --scrollbar-thumb: #4b5563;
        --input-bg:     #1a1a1e;
        --input-border: #2c2c35;
        --field-border: #3f3f4b;
        --bt-field-line: rgba(255, 255, 255, .28);
        color-scheme: dark;
    }
}

/* Drop-down rows of every native <select> in the widget (hourly Duration, the
   passenger / bag / child-seat counts on the Book step). They render on the
   browser's own surface, which never inherits the card background — so the
   colours have to be spelled out or they follow the OS while the text follows
   the theme. */
#widget-vue-body select option,
#widget-vue-body select optgroup {
    background-color: var(--bt-card);
    color: var(--bt-text);
}

/* Shared dark-mode Tailwind class overrides — applied for both dark selectors */
:is(#widget-vue-body[data-scheme="dark"]) .bg-white,
:is(#widget-vue-body[data-scheme="dark"]) .bg-\[\#ffffff\] { background-color: var(--bt-card) !important; }

:is(#widget-vue-body[data-scheme="dark"]) .bg-\[\#f6f6f6\],
:is(#widget-vue-body[data-scheme="dark"]) .bg-gray-100     { background-color: var(--bg-light) !important; }

:is(#widget-vue-body[data-scheme="dark"]) .border-gray-100,
:is(#widget-vue-body[data-scheme="dark"]) .border-gray-200,
:is(#widget-vue-body[data-scheme="dark"]) .divide-gray-100 > * + * { border-color: var(--bt-border) !important; }

:is(#widget-vue-body[data-scheme="dark"]) .bg-\[\#f3f4f6\] { background-color: var(--bg-light) !important; }

:is(#widget-vue-body[data-scheme="dark"]) .sheet-drag-handle i { background-color: var(--bg-light); }

@media (prefers-color-scheme: dark) {
    :is(#widget-vue-body[data-theme="system"]) .bg-white,
    :is(#widget-vue-body[data-theme="system"]) .bg-\[\#ffffff\] { background-color: var(--bt-card) !important; }

    :is(#widget-vue-body[data-theme="system"]) .bg-\[\#f6f6f6\],
    :is(#widget-vue-body[data-theme="system"]) .bg-gray-100     { background-color: var(--bg-light) !important; }

    :is(#widget-vue-body[data-theme="system"]) .border-gray-100,
    :is(#widget-vue-body[data-theme="system"]) .border-gray-200,
    :is(#widget-vue-body[data-theme="system"]) .divide-gray-100 > * + * { border-color: var(--bt-border) !important; }

    :is(#widget-vue-body[data-theme="system"]) .bg-\[\#f3f4f6\] { background-color: var(--bg-light) !important; }

    :is(#widget-vue-body[data-theme="system"]) .sheet-drag-handle i { background-color: var(--bg-light); }
}

/* ── Booking submission overlay ──────────────────────────────────────────
   Replaces inline styles on the isSubmittingBooking overlay div so colors
   participate in the CSS variable theming system.
   ────────────────────────────────────────────────────────────────────────── */
.a2z-submit-overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.55);
    z-index: 9999;
    display: flex; align-items: center; justify-content: center;
}
.a2z-submit-overlay-card {
    background: var(--bt-card);
    border-radius: var(--radius-lg);
    padding: 36px 32px;
    display: flex; flex-direction: column; align-items: center; gap: 16px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.25);
    max-width: 280px; width: 90%; text-align: center;
}
.a2z-submit-spinner-wrap {
    position: relative; width: 64px; height: 64px;
}
.a2z-submit-spinner-ring {
    position: absolute; inset: 0;
    border-radius: 50%;
    border: 4px solid var(--bt-border);
    border-top-color: var(--brand-primary);
    animation: spin 0.8s linear infinite;
}
.a2z-submit-spinner-icon {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    color: var(--brand-primary);
    font-size: 20px;
}
.a2z-submit-title {
    font-size: 16px; font-weight: 700;
    color: var(--bt-text); margin: 0;
}
.a2z-submit-desc {
    font-size: 13px; color: var(--bt-muted); margin: 6px 0 0;
}

/* ── Custom Minimal Scrollbars ───────────────────────────────────────────── */
#widget-vue-body ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}
#widget-vue-body ::-webkit-scrollbar-track {
    background: transparent;
}
#widget-vue-body ::-webkit-scrollbar-thumb {
    background-color: var(--scrollbar-thumb);
    border-radius: 10px;
}
#widget-vue-body ::-webkit-scrollbar-thumb:hover {
    background-color: color-mix(in srgb, var(--scrollbar-thumb) 80%, black);
}
#widget-vue-body {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) transparent;
}

/* Prevent iOS Safari from auto-zooming on form inputs/selects on focus */
@media (max-width: 1024px) {
    #widget-vue-body input[type="text"],
    #widget-vue-body input[type="tel"],
    #widget-vue-body input[type="email"],
    #widget-vue-body input[type="number"],
    #widget-vue-body input[type="password"],
    #widget-vue-body input[type="search"],
    #widget-vue-body select,
    #widget-vue-body textarea {
        font-size: 16px !important;
    }
}

/* ── intl-tel-input ───────────────────────────────────────────────────────
   The flag + dial code sit in an absolutely-positioned button over the input's
   left edge, so the input's text has to be pushed clear of it. That distance is
   NOT a constant — it grows with the dial code, "+1" against "+376".

   iti works this out itself and writes `padding-left` inline on the input, but
   that never survives here: `.bk-field input` / `.bq-field input` below set
   `padding: 0 !important`, and an !important author rule beats a plain inline
   style. So the lead is re-declared !important — but from `--iti-lead`, which
   syncItiLead() measures off the real button (see index/embed). The old fixed
   `40px` was both a guess and 12px under iti's own no-dial-code allowance
   (--iti-selected-country-arrow-padding = 52px, which is the fallback here). */
#widget-vue-body .iti {
    width: 100% !important;
    display: block !important;
    /* Flex item of .bk-field / .bq-field. Without this it keeps its min-content
       width and refuses to shrink, which is how the Contact row's phone spilled
       out of its grid cell and over the Email field beside it. */
    flex: 1 1 auto;
    min-width: 0;
}
#widget-vue-body .iti input[type="tel"] {
    padding-left: var(--iti-lead, 52px) !important;
    /* iti replaces the field with .iti > input, so the input is no longer a flex
       child of .bk-field and loses the `flex: 1; min-width: 0` that keeps every
       other field inside its box. Left to itself it falls back to the UA's
       default ~20-character intrinsic width — wider than a third of the Contact
       row, so a full number ran straight through the Email field. */
    width: 100% !important;
    box-sizing: border-box;
    text-overflow: ellipsis;
}
/* The dial code beside the flag, in the field's own ink rather than iti's
   inherited default, and the arrow with it. */
#widget-vue-body .iti__selected-dial-code { color: var(--bt-text); font-size: 13.5px; }
#widget-vue-body .iti__arrow { border-top-color: var(--bt-muted); }
#widget-vue-body .iti__arrow--up { border-bottom-color: var(--bt-muted); }
#widget-vue-body .iti--allow-dropdown .iti__country-container:hover .iti__selected-country {
    background-color: var(--bt-soft);
}

/* ── The country list ─────────────────────────────────────────────────────
   iti ships it hard-coded to `background-color: white` with grey text, which on
   a dark widget is a white sheet of unreadable names. It renders inside
   #widget-vue-body (no dropdownContainer is set), so the tokens reach it
   directly — no copying, unlike the panels appended to <body>. */
#widget-vue-body .iti__dropdown-content {
    background-color: var(--bt-card);
    border-color: var(--bt-border);
    color: var(--bt-text);
}
#widget-vue-body .iti__country { color: var(--bt-text); }
#widget-vue-body .iti__country-name { color: var(--bt-text); }
#widget-vue-body .iti__dial-code { color: var(--bt-muted); }
#widget-vue-body .iti__country.iti__highlight { background-color: var(--bt-soft); }
#widget-vue-body .iti__country.iti__active { background-color: var(--brand-primary-light); }
#widget-vue-body .iti__search-input {
    background: var(--input-bg);
    color: var(--bt-text);
}
#widget-vue-body .iti__search-input::placeholder { color: var(--bt-muted); }
#widget-vue-body .iti__search-input + .iti__country-list { border-top-color: var(--bt-border); }
#widget-vue-body .iti__divider { border-bottom-color: var(--bt-border); }

/* ══════════════════════════════════════════════════════════════════════════
   Combined Book step (bk-) — merges vehicle + details + payment onto step 2.
   Two columns: scrollable form (left) + sticky map/fare/promo/payment (right).
   ══════════════════════════════════════════════════════════════════════════ */
/* Same left-over-space formula as .step-1 above — see the note there. */
#widget-vue-body.step-2 { padding: 0 clamp(16px, calc((100vw - 1000px) / 2), 280px); }
/* Every step + the My Rides overlay share the same edge inset so the widget frame
   (header + content) lines up throughout. */
#widget-vue-body.step-5,
#widget-vue-body.step-6,
#widget-vue-body.step-7,
#widget-vue-body.mr-open { padding: 0 clamp(16px, calc((100vw - 1000px) / 2), 280px); }
#widget-vue-body.step-2 .bk-split {
    display: flex;
    flex-direction: row;
    width: 100%;
    height: 100%;
    min-height: 0;
    flex: 1;
    background: var(--bt-bg);
}
#widget-vue-body .bk-main {
    flex: 1 1 auto;
    min-width: 0;
    /* stretch, not height:100% — .bk-split is flex-sized, so a percentage height
       resolves to auto and this column would grow instead of scrolling. */
    align-self: stretch;
    overflow-y: auto;
    padding: 24px clamp(16px, 3vw, 40px) 40px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    scrollbar-width: none;
}
#widget-vue-body .bk-main::-webkit-scrollbar { display: none; }
#widget-vue-body .bk-side {
    flex: 0 0 400px;
    width: 400px;
    max-width: 400px;
    align-self: stretch;
    background: var(--bt-bg);
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 24px 24px 40px 4px;
    overflow-y: auto;
    scrollbar-width: none;
}
#widget-vue-body .bk-side::-webkit-scrollbar { display: none; }

/* Back link */
#widget-vue-body .bk-back {
    align-self: flex-start;
    background: none;
    border: none;
    color: var(--bt-muted);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0;
}
#widget-vue-body .bk-back:hover { color: var(--brand-primary); }

/* Blocks */
#widget-vue-body .bk-block { display: flex; flex-direction: column; gap: 12px; }
#widget-vue-body .bk-block-num {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--bt-muted);
}

/* Filter chips */
#widget-vue-body .bk-filters { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; }
#widget-vue-body .bk-filters::-webkit-scrollbar { display: none; }
#widget-vue-body .bk-chip {
    flex-shrink: 0;
    padding: 7px 14px;
    border-radius: var(--radius-pill);
    font-size: 12px;
    font-weight: 700;
    background: var(--bt-card);
    border: 1px solid var(--bt-border);
    color: var(--bt-muted);
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .bk-chip.is-active { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }

/* Vehicle cards */
#widget-vue-body .bk-vehicles { display: flex; flex-direction: column; gap: 10px; }
#widget-vue-body .bk-vehicle {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    background: var(--bt-card);
    border: 1.5px solid var(--bt-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-soft);
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .bk-vehicle:hover { border-color: #d8cdc4; }
/* Empty state: same card frame, dashed + non-interactive, with a placeholder glyph */
#widget-vue-body .bk-vehicle--empty { cursor: default; border-style: dashed; box-shadow: none; background: var(--bg-light); }
#widget-vue-body .bk-vehicle--empty:hover { border-color: var(--bt-border); }
#widget-vue-body .bk-vehicle-empty-ico { width: 76px; height: 50px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 24px; color: var(--bt-muted); }
#widget-vue-body .bk-vehicle.is-selected { border-color: var(--brand-primary); border-width: 2px; }
#widget-vue-body .bk-vehicle-img { width: 76px; height: 50px; object-fit: contain; flex-shrink: 0; }
#widget-vue-body .bk-vehicle-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
#widget-vue-body .bk-vehicle-name { font-size: 14.5px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .bk-vehicle-specs { font-size: 12px; color: var(--bt-muted); }
#widget-vue-body .bk-vehicle-note { font-size: 11px; font-weight: 700; color: #15803d; }
#widget-vue-body .bk-vehicle-price { text-align: right; flex-shrink: 0; }
#widget-vue-body .bk-vehicle-amount { font-size: 16px; font-weight: 800; color: var(--bt-text); }
#widget-vue-body .bk-vehicle-lbl { font-size: 9px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; color: var(--bt-muted); }
/* Stands in for the fare on a vehicle we have no rate for. Outlined rather than
   filled: it is the same weight of choice as any other row in the list, not a
   call to action competing with the confirm button. */
/* Block + margin-left:auto, not inline-block: the price cell is text-align:right
   and the amount it stands in for is a <div>, so an inline chip would sit on the
   same line as its label instead of above it like every priced row. */
#widget-vue-body .bk-vehicle-quote { display: block; width: fit-content; margin: 0 0 0 auto; padding: 4px 10px; border: 1.5px solid var(--brand-primary); color: var(--brand-primary); font-size: 11.5px; font-weight: 800; white-space: nowrap; }
#widget-vue-body .bk-vehicle.is-selected .bk-vehicle-quote { background: var(--brand-primary); color: #fff; }

/* Cards / surfaces for contact + details (rounded, matches mockup) */
#widget-vue-body .bk-contact,
#widget-vue-body .bk-rows {
    background: var(--bt-card);
    border: 1px solid var(--bt-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-soft);
}
#widget-vue-body .bk-contact { padding: 16px; display: flex; flex-direction: column; gap: 14px; }
#widget-vue-body .bk-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
#widget-vue-body .bk-card-title { font-size: 11px; font-weight: 800; letter-spacing: 0.8px; text-transform: uppercase; color: var(--bt-muted); }
#widget-vue-body .bk-card-head .bk-seg { padding: 3px; }
#widget-vue-body .bk-card-head .bk-seg-btn { flex: 0 0 auto; padding: 6px 14px; }
/* Not `repeat(3, 1fr)`: a bare `1fr` is `minmax(auto, 1fr)`, and that auto floor
   lets a track refuse to shrink under its content — which is how the phone cell
   pushed its number out over the Email field beside it. The phone column is also
   given the extra share its 40px country-flag gutter costs. */
#widget-vue-body .bk-contact-fields { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1.2fr); gap: 10px; }

/* Shared field */
#widget-vue-body .bk-field {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-width: 0;
    background: var(--input-bg);
    border: 1.5px solid var(--field-border);
    border-radius: var(--bt-field-radius, 0);
    padding: 11px 14px;
    box-sizing: border-box;
    transition: var(--transition-smooth);
}
#widget-vue-body .bk-field:focus-within { border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--brand-primary-light); }
#widget-vue-body .bk-field input,
#widget-vue-body .bk-field textarea {
    flex: 1; min-width: 0; border: none !important; background: none !important; outline: none !important;
    box-shadow: none !important; font-size: 13.5px; font-weight: 500; color: var(--bt-text);
    padding: 0 !important; margin: 0 !important;
}
#widget-vue-body .bk-field input::placeholder { color: #9c9490; }
#widget-vue-body .bk-field-ico { font-size: 13px; color: var(--bt-muted); flex-shrink: 0; width: 16px; text-align: center; }
#widget-vue-body .bk-fields { display: flex; flex-direction: column; gap: 10px; }
/* Rider name + mobile: two columns on desktop, stacked on mobile. Each cell
   keeps its own label above its field so the labels never drift out of line. */
#widget-vue-body .bk-rider-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
#widget-vue-body .bk-field-group { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
#widget-vue-body .bk-uppercase { text-transform: uppercase; }

/* Segmented control (Guest/Sign in, Myself/Someone else, email/phone) */
#widget-vue-body .bk-seg { display: flex; gap: 6px; background: var(--bg-light); padding: 4px; border-radius: var(--radius-pill); }
#widget-vue-body .bk-seg--sm { align-self: flex-start; }
#widget-vue-body .bk-seg-btn {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
    padding: 8px 16px; border: none; background: none; border-radius: var(--radius-pill);
    font-size: 12.5px; font-weight: 700; color: var(--bt-muted); cursor: pointer; transition: var(--transition-smooth); white-space: nowrap;
}
#widget-vue-body .bk-seg-btn.is-active { background: var(--brand-primary); color: #fff; }
#widget-vue-body .bk-seg-btn i { font-size: 11px; }

/* Signed-in row */
#widget-vue-body .bk-signed { display: flex; align-items: center; gap: 14px; }
#widget-vue-body .bk-avatar { width: 48px; height: 48px; border-radius: 50%; overflow: hidden; background: var(--brand-primary); color: #fff; font-weight: 800; font-size: 18px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
#widget-vue-body .bk-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
#widget-vue-body .bk-signed-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
#widget-vue-body .bk-signed-name { font-size: 14.5px; font-weight: 700; color: var(--bt-text); line-height: 1.2; }
#widget-vue-body .bk-signed-row { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--bt-muted); min-width: 0; }
#widget-vue-body .bk-signed-row i { width: 12px; font-size: 11px; color: var(--brand-primary); flex-shrink: 0; }
#widget-vue-body .bk-signed-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#widget-vue-body .bk-signed-sub { font-size: 11.5px; color: var(--bt-muted); }

/* Inline auth OTP + recaptcha */
#widget-vue-body .bk-otp { display: flex; gap: 8px; }
/* The six code boxes have to read as wells before anything is typed into them —
   they are the only cue that there is something to fill in. `--input-bg` alone
   does not do that here: an operator who sets a Card/Secondary colour paints it
   onto --input-bg too, so in the header sign-in strip the boxes came out the
   exact colour of the bar behind them and vanished, leaving six near-invisible
   outlines. The mix lifts the fill off whatever surface it lands on and works
   in both schemes without a second rule — on dark it lightens toward the text
   colour, on light it darkens to a pale grey. --bt-field-line rather than
   --field-border for the same reason it exists at all: an edge carrying a shape
   on its own needs more contrast than one sitting on a filled box. */
#widget-vue-body .bk-otp-box { width: 40px; height: 46px; text-align: center; font-size: 18px; font-weight: 700; border: 1.5px solid var(--bt-field-line); border-radius: var(--bt-field-radius, 0); background: color-mix(in srgb, var(--bt-text) 8%, var(--input-bg)); color: var(--bt-text); outline: none; }
/* Focus matches every other field in the widget (.bq-field / .bk-field
   :focus-within), and it used to be --bt-text — the one focus ring here that
   ignored the operator's Primary Color.

   !important is required, not decorative. The global rule near the top of this
   file blanks `border-color`, `outline` and `box-shadow` on every focused
   input/select/textarea with !important, because every other field in the
   widget wears its focus on a WRAPPER via :focus-within. An OTP box has no
   wrapper — the box is the input — so the only way it can show focus at all is
   to beat that rule. Without this the previous declaration was silently dead
   and the boxes gave no focus feedback whatsoever. */
#widget-vue-body .bk-otp-box:focus {
    border-color: var(--brand-primary) !important;
    box-shadow: 0 0 0 3px var(--brand-primary-light) !important;
}
#widget-vue-body .bk-otp-actions { display: flex; align-items: center; gap: 12px; }
#widget-vue-body .bk-signin-row { display: flex; gap: 8px; align-items: stretch; }
#widget-vue-body .bk-signin-row .bk-field { flex: 1; min-width: 0; }
#widget-vue-body .bk-signin-send { align-self: stretch; flex-shrink: 0; }
#widget-vue-body .bk-recaptcha { margin: 2px 0; }
#widget-vue-body .bk-recaptcha.is-hidden { display: none; }

/* Hints, mini-labels, links */
#widget-vue-body .bk-hint { font-size: 11.5px; line-height: 1.5; color: var(--bt-muted); }
#widget-vue-body .bk-mini-label { font-size: 10.5px; font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase; color: var(--bt-muted); }
#widget-vue-body .bk-link { background: none; border: none; color: var(--brand-primary); font-size: 12px; font-weight: 700; cursor: pointer; padding: 0; }
#widget-vue-body .bk-link-danger { background: none; border: none; color: #ef4444; font-size: 12px; font-weight: 700; cursor: pointer; padding: 0; }

/* Buttons */
#widget-vue-body .bk-btn-outline {
    align-self: flex-start; padding: 9px 18px; border: 1.5px solid var(--brand-primary); background: none;
    color: var(--brand-primary); font-size: 12.5px; border-radius: var(--bt-btn-radius, 0);
    font-family: var(--bt-btn-font, inherit); font-weight: var(--bt-btn-weight, 700); text-transform: var(--bt-btn-transform, none);
    cursor: pointer; transition: var(--transition-smooth);
}
#widget-vue-body .bk-btn-outline:hover { background: var(--bt-btn-bg, var(--brand-primary)); color: #fff; }
#widget-vue-body .bk-btn-outline:disabled { opacity: 0.6; cursor: not-allowed; }
#widget-vue-body .bk-btn-solid {
    padding: 11px 18px; border: none; background: var(--bt-btn-bg, var(--brand-primary)); color: #fff; font-size: 12.5px;
    font-family: var(--bt-btn-font, inherit); font-weight: var(--bt-btn-weight, 700); border-radius: var(--bt-btn-radius, 0);
    text-transform: var(--bt-btn-transform, none);
    cursor: pointer; transition: var(--transition-smooth); flex-shrink: 0;
}
#widget-vue-body .bk-btn-solid:hover { background: var(--bt-btn-bg-hover, var(--brand-primary-hover)); }
#widget-vue-body .bk-btn-solid:disabled { opacity: 0.5; cursor: not-allowed; }

/* Accordion rows */
#widget-vue-body .bk-rows { display: flex; flex-direction: column; overflow: hidden; }
#widget-vue-body .bk-rows > * + * { border-top: 1px solid var(--bt-border); }
#widget-vue-body .bk-row-head {
    width: 100%; display: flex; align-items: center; gap: 12px; padding: 14px 16px;
    background: none; border: none; cursor: pointer; text-align: left;
}
#widget-vue-body .bk-row-ico { width: 30px; height: 30px; border-radius: 50%; background: var(--bg-light); color: var(--brand-primary); display: flex; align-items: center; justify-content: center; font-size: 12px; flex-shrink: 0; }
#widget-vue-body .bk-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
#widget-vue-body .bk-row-title { font-size: 13.5px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .bk-row-sum { font-size: 11.5px; color: var(--bt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#widget-vue-body .bk-row-chev { color: var(--bt-muted); font-size: 12px; transition: transform 0.25s ease; }
#widget-vue-body .bk-row-chev.is-open { transform: rotate(180deg); }
#widget-vue-body .bk-row-body { padding: 0 16px 16px; display: flex; flex-direction: column; gap: 10px; }

/* Steppers — passengers, luggage and every child seat sit on one row and
   wrap to equal columns when the widget is too narrow for all of them. */
#widget-vue-body .bk-steppers { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 10px; }
#widget-vue-body .bk-stepper { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
#widget-vue-body .bk-step-ctrl { display: flex; align-items: center; justify-content: space-between; gap: 4px; border: 1.5px solid var(--field-border); border-radius: var(--bt-field-radius, 0); padding: 5px 7px; }
#widget-vue-body .bk-step-btn { width: 26px; height: 26px; flex: none; border-radius: 50%; border: 1.5px solid var(--field-border); background: var(--input-bg); color: var(--bt-muted); display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 10px; transition: var(--transition-smooth); }
#widget-vue-body .bk-step-btn.is-add { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
#widget-vue-body .bk-step-val { font-size: 15px; font-weight: 700; min-width: 20px; text-align: center; }

/* Counted extras as selects. Wider min than the steppers because these carry
   the operator's own bag names, which are longer than "Luggage". */
#widget-vue-body .bk-selects { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 12px; }
#widget-vue-body .bk-select-item { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
#widget-vue-body .bk-select-input { width: 100%; min-width: 0; font-size: 14px; font-weight: 600; color: var(--bt-text); background: var(--input-bg); border: 1.5px solid var(--field-border); border-radius: var(--bt-field-radius, 0); padding: 8px 10px; cursor: pointer; transition: var(--transition-smooth); }
#widget-vue-body .bk-select-input:focus { outline: none; border-color: var(--brand-primary); }
#widget-vue-body .bk-select-hint { font-size: 10.5px; color: var(--bt-muted); }

/* Toggle rows + switch */
#widget-vue-body .bk-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 16px; }
#widget-vue-body .bk-toggle-text { display: flex; flex-direction: column; gap: 2px; }
#widget-vue-body .bk-toggle-title { font-size: 13px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .bk-toggle-sub { font-size: 11px; color: var(--bt-muted); }
#widget-vue-body .bk-switch { position: relative; width: 44px; height: 24px; border-radius: 12px; background: #d9d0c8; cursor: pointer; flex-shrink: 0; transition: background 0.25s ease; }
#widget-vue-body .bk-switch.is-on { background: var(--brand-primary); }
#widget-vue-body .bk-switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: #fff; transition: left 0.25s ease; }
#widget-vue-body .bk-switch.is-on::after { left: 22px; }

/* Note — collapsible link (native <details>) */
#widget-vue-body .bk-note { padding: 0 2px; }
#widget-vue-body .bk-note-summary {
    list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px;
    font-size: 12.5px; font-weight: 700; color: var(--brand-primary); padding: 4px 2px;
}
#widget-vue-body .bk-note-summary::-webkit-details-marker { display: none; }
#widget-vue-body .bk-note[open] .bk-note-summary { margin-bottom: 8px; }
/* Open by default, so the leading plus turns into a close cross. */
#widget-vue-body .bk-note-summary i { transition: transform 0.2s ease; }
#widget-vue-body .bk-note[open] .bk-note-summary i { transform: rotate(45deg); }
#widget-vue-body .bk-note textarea { width: 100%; border: 1.5px solid var(--field-border); border-radius: var(--bt-field-radius, 0); background: var(--input-bg); padding: 10px 12px; font-size: 13px; color: var(--bt-text); resize: none; outline: none; }
#widget-vue-body .bk-note textarea:focus { border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--brand-primary-light); }

/* Flight results (in row body) */
/* Flight: number entry on the left, matching schedules listed beside it. Each
   result is one line — IATA · route · when it lands · status. */
#widget-vue-body .bk-flight-grid { display: grid; grid-template-columns: minmax(180px, 240px) 1fr; gap: 16px; align-items: start; }
#widget-vue-body .bk-flight-entry { display: flex; flex-direction: column; gap: 6px; }
#widget-vue-body .bk-flight-results { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
#widget-vue-body .bk-flight-list { display: flex; flex-direction: column; gap: 8px; }
#widget-vue-body .bk-flight-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1.5px solid transparent; cursor: pointer; }
#widget-vue-body .bk-flight-item:hover { border-color: var(--bt-border); }
#widget-vue-body .bk-flight-item.is-selected { border-color: var(--brand-primary); background: var(--brand-primary-light); }
#widget-vue-body .bk-flight-tick { flex: none; width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--bt-border); display: flex; align-items: center; justify-content: center; transition: var(--transition-smooth); }
#widget-vue-body .bk-flight-tick i { font-size: 9px; color: #fff; opacity: 0; }
#widget-vue-body .bk-flight-item.is-selected .bk-flight-tick { background: var(--brand-primary); border-color: var(--brand-primary); }
#widget-vue-body .bk-flight-item.is-selected .bk-flight-tick i { opacity: 1; }
#widget-vue-body .bk-flight-iata { font-size: 16px; font-weight: 800; letter-spacing: 0.5px; color: var(--bt-text); }
#widget-vue-body .bk-flight-path { flex: 0 1 88px; min-width: 34px; height: 1px; position: relative; background: var(--bt-border); }
#widget-vue-body .bk-flight-path i { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 0 4px; background: var(--bt-surface, #fff); color: var(--bt-muted); font-size: 10px; }
#widget-vue-body .bk-flight-item.is-selected .bk-flight-path i { background: var(--brand-primary-light); }
#widget-vue-body .bk-flight-meta { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--bt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#widget-vue-body .bk-flight-status { flex: none; display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700; }
#widget-vue-body .bk-flight-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
#widget-vue-body .bk-flight-status.is-ok { color: #16a34a; }
#widget-vue-body .bk-flight-status.is-warn { color: #dc2626; }
#widget-vue-body .bk-hint--error { color: #dc2626; }
/* The right inset used to hold a Verify button. The number verifies itself as
   the typing settles now, so all that sits there is the spinner saying so —
   the padding stays reserved at that width so the value never shifts under it. */
#widget-vue-body .bk-field--flight { position: relative; padding-right: 34px; }
#widget-vue-body .bk-field-ico--plane { color: #60a5fa; }
#widget-vue-body .bk-flight-spin { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font-size: 13px; color: var(--brand-primary); }

/* ── Right panel — two separate rounded cards (map, then summary) ─────────── */
#widget-vue-body .bk-map {
    position: relative; height: 258px; flex-shrink: 0; background: var(--input-bg);
    border: 1px solid var(--bt-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); overflow: hidden;
}
#widget-vue-body .bk-map-canvas { position: absolute; top: 0; left: 0; right: 0; height: 212px; }
#widget-vue-body .bk-map-cap {
    position: absolute; left: 0; right: 0; bottom: 0; height: 46px;
    background: var(--bt-card); border-top: 1px solid var(--bt-border);
    display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 14px;
}
#widget-vue-body .bk-map-route { font-size: 12px; font-weight: 700; color: var(--bt-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#widget-vue-body .bk-map-meta { font-size: 11px; font-weight: 600; color: var(--bt-muted); white-space: nowrap; flex-shrink: 0; }
#widget-vue-body .bk-summary-card {
    background: var(--bt-card); border: 1px solid var(--bt-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft);
    padding: 16px; display: flex; flex-direction: column; gap: 14px;
}

/* Flat fare breakdown — a ruled ledger: muted label left, dark amount right,
   one hairline between every line including under the heading. Spacing comes
   from row padding (not a flex gap) so the rules meet edge to edge. */
#widget-vue-body .bk-fare { display: flex; flex-direction: column; }
#widget-vue-body .bk-fare-label { font-size: 11px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase; color: var(--bt-muted); padding-bottom: 12px; border-bottom: 1px solid var(--bt-border); }
#widget-vue-body .bk-fare-row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 11px 0; border-bottom: 1px solid var(--bt-border); font-size: 13px; color: var(--bt-muted); }
#widget-vue-body .bk-fare-row > span:last-child { flex: none; font-weight: 600; color: var(--bt-text); white-space: nowrap; }
#widget-vue-body .bk-fare-amt { font-weight: 600; }
/* A charge line's description stacks its label over the arithmetic behind it,
   so a bag discounted by the vehicle's free allowance can be tallied. */
#widget-vue-body .bk-fare-desc { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
#widget-vue-body .bk-fare-note { font-size: 11px; line-height: 1.35; color: var(--bt-muted); opacity: 0.85; }
#widget-vue-body .bk-fare-sub { font-weight: 600; }
#widget-vue-body .bk-fare-discount, #widget-vue-body .bk-fare-discount > span:last-child { color: #16a34a; }
#widget-vue-body .bk-fare-total { border-bottom: none; padding-bottom: 0; color: var(--bt-text); }
#widget-vue-body .bk-fare-total span:first-child { font-size: 13.5px; font-weight: 700; }
#widget-vue-body .bk-fare-total span:last-child { font-size: 21px; font-weight: 800; letter-spacing: -0.3px; }

/* Promo */
#widget-vue-body .bk-promo-entry { display: flex; gap: 8px; align-items: stretch; }
#widget-vue-body .bk-promo-entry .bk-field { flex: 1; }
#widget-vue-body .bk-promo-applied { display: flex; align-items: center; gap: 10px; background: #f0fdf4; border: 1px solid #bbf7d0; padding: 10px 12px; }
#widget-vue-body .bk-promo-applied > i { color: #16a34a; }
#widget-vue-body .bk-promo-code { flex: 1; font-size: 12.5px; font-weight: 700; color: var(--bt-text); }

/* Payment */
#widget-vue-body .bk-pay { display: flex; flex-direction: column; gap: 10px; }
#widget-vue-body .bk-pay-methods { display: flex; gap: 8px; }
#widget-vue-body .bk-pay-chip { flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px; padding: 10px; border: 1.5px solid var(--field-border); background: var(--input-bg); color: var(--bt-muted); font-size: 12.5px; font-weight: 700; cursor: pointer; transition: var(--transition-smooth); }
#widget-vue-body .bk-pay-chip.is-active { border-color: var(--brand-primary); background: var(--brand-primary-light); color: var(--brand-primary); }
#widget-vue-body .bk-card-entry { display: flex; flex-direction: column; gap: 10px; }
#widget-vue-body .bk-card-widget { background: #f7f4f1; border: 1.5px solid var(--field-border); padding: 12px 14px; min-height: 48px; }
#widget-vue-body .bk-ssl { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 600; color: #15803d; background: #f0fdf4; padding: 8px 12px; }
#widget-vue-body .bk-cards { display: flex; flex-direction: column; gap: 8px; }
#widget-vue-body .bk-cards-head { display: flex; align-items: center; justify-content: space-between; }
#widget-vue-body .bk-card { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1.5px solid var(--field-border); background: var(--input-bg); cursor: pointer; }
#widget-vue-body .bk-card.is-active { border-color: var(--brand-primary); background: var(--brand-primary-light); }
#widget-vue-body .bk-card-brand { font-size: 9px; font-weight: 800; color: var(--bt-text); background: var(--bg-light); padding: 3px 6px; }
#widget-vue-body .bk-card-num { flex: 1; font-size: 12.5px; font-weight: 600; letter-spacing: 1px; color: var(--bt-text); }
#widget-vue-body .bk-card-exp { font-size: 11px; color: var(--bt-muted); }
#widget-vue-body .bk-card-check { color: var(--brand-primary); }
/* Selected-card summary row (payment section) — mirrors a .bk-card but with a Change action */
#widget-vue-body .bk-card-summary { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1.5px solid var(--brand-primary); background: var(--brand-primary-light); }
#widget-vue-body .bk-card-summary .bk-card-num { flex: 1; }
#widget-vue-body .bk-card-none { flex: 1; font-size: 12.5px; color: var(--bt-muted); }
#widget-vue-body .bk-card-change { flex: none; font-size: 12px; font-weight: 700; padding: 4px 12px; border: 1.5px solid var(--brand-primary); background: var(--input-bg); color: var(--brand-primary); cursor: pointer; white-space: nowrap; }
#widget-vue-body .bk-card-change:hover { background: var(--brand-primary); color: #fff; }
/* Payment validation message (e.g. card method chosen but no card picked) */
/* A message that answers for a whole block rather than for one input — the card
   row's, and the contact card's "sign in or fill in your details", where which
   field is at fault depends on the tab that is open. .bk-error stays the
   per-field one. */
#widget-vue-body .bk-pay-error,
#widget-vue-body .bk-block-error { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: #dc2626; }
#widget-vue-body .bk-pay-error i,
#widget-vue-body .bk-block-error i { font-size: 11px; flex-shrink: 0; }
/* Select-card dialog: radio list + Add-new-card row */
#widget-vue-body .bk-cardpick-list { display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow-y: auto; }
#widget-vue-body .bk-cardpick { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1.5px solid var(--field-border); background: var(--input-bg); cursor: pointer; }
#widget-vue-body .bk-cardpick.is-active { border-color: var(--brand-primary); background: var(--brand-primary-light); }
#widget-vue-body .bk-cardpick-radio { flex: none; width: 17px; height: 17px; border-radius: 50%; border: 2px solid var(--bt-border); position: relative; }
#widget-vue-body .bk-cardpick-radio.is-on { border-color: var(--brand-primary); }
#widget-vue-body .bk-cardpick-radio.is-on::after { content: ''; position: absolute; inset: 3px; border-radius: 50%; background: var(--brand-primary); }
#widget-vue-body .bk-addcard-row { display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%; padding: 10px 12px; border: 1.5px dashed var(--brand-primary); background: none; color: var(--brand-primary); font-size: 12.5px; font-family: var(--bt-btn-font, inherit); font-weight: var(--bt-btn-weight, 700); cursor: pointer; }
#widget-vue-body .bk-addcard-row:hover { background: var(--brand-primary-light); }

/* Quote-request mode: what stands in for the fare breakdown, promo and payment
   when the chosen vehicle has no rate. Says why the sidebar is otherwise empty
   rather than leaving a gap above the confirm button. */
#widget-vue-body .bk-quote-note { display: flex; gap: 12px; padding: 14px 16px; background: var(--brand-primary-light); border-left: 3px solid var(--brand-primary); }
#widget-vue-body .bk-quote-note > i { flex: none; margin-top: 2px; font-size: 15px; color: var(--brand-primary); }
#widget-vue-body .bk-quote-note-title { font-size: 13px; font-weight: 800; color: var(--bt-text); }
#widget-vue-body .bk-quote-note-sub { margin-top: 4px; font-size: 11.5px; line-height: 1.5; color: var(--bt-muted); }

/* Confirm + fine print */
#widget-vue-body .bk-confirm { text-transform: var(--bt-btn-transform, uppercase); letter-spacing: 0.5px; margin-top: 2px; }
#widget-vue-body .bk-confirm.is-loading { opacity: 0.6; cursor: not-allowed; }
#widget-vue-body .bk-spin { width: 16px; height: 16px; animation: spin 1s linear infinite; }
#widget-vue-body .bk-fineprint { font-size: 10.5px; line-height: 1.5; color: var(--bt-muted); text-align: center; }

/* Add-card modal */
#widget-vue-body .bk-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; padding: 16px; }
#widget-vue-body .bk-modal-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.5); }
#widget-vue-body .bk-modal-card { position: relative; width: 100%; max-width: 380px; background: var(--bt-card); box-shadow: var(--shadow-premium); }
#widget-vue-body .bk-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px; border-bottom: 1px solid var(--bt-border); }
#widget-vue-body .bk-modal-head h3 { font-size: 15px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .bk-modal-head button { background: none; border: none; color: var(--bt-muted); cursor: pointer; }
#widget-vue-body .bk-modal-body { padding: 18px; display: flex; flex-direction: column; gap: 12px; }
#widget-vue-body .bk-modal-foot { padding: 0 18px 18px; display: flex; gap: 10px; }
#widget-vue-body .bk-modal-foot .bk-btn-outline { flex: 1; align-self: auto; text-align: center; justify-content: center; }
#widget-vue-body .bk-modal-foot .bk-btn-solid { flex: 2; }

/* Cards stay rounded; every control inside them is square-cornered
   (inputs, selects, textareas, buttons) — pills/chips keep their pill shape.

   .bk-otp-box is deliberately NOT in this list. It is a field, not a button, so
   it follows Form Fields › Corner Radius via its own rule above. It used to sit
   here and pick up Buttons › Corner Radius instead, which on a client running a
   24px pill button turned six 34×38 code boxes into circles. */
#widget-vue-body .bk-btn-outline,
#widget-vue-body .bk-btn-solid,
#widget-vue-body .bk-step-ctrl,
#widget-vue-body .bk-card-widget,
#widget-vue-body .bk-ssl,
#widget-vue-body .bk-promo-applied,
#widget-vue-body .bk-flight-item,
#widget-vue-body .bk-pay-chip,
#widget-vue-body .bk-card,
#widget-vue-body .bk-card-summary,
#widget-vue-body .bk-card-change,
#widget-vue-body .bk-cardpick,
#widget-vue-body .bk-addcard-row,
#widget-vue-body .bk-confirm { border-radius: var(--bt-btn-radius, 0); }
#widget-vue-body .bk-modal-card { border-radius: var(--radius-lg); }

/* ── Tablet / mobile: stack the two columns into one scroll ──────────────── */
@media (max-width: 1024px) {
    /* Full-bleed on smaller screens — the columns carry their own padding. */
    #widget-vue-body.step-1,
    #widget-vue-body.step-2,
    #widget-vue-body.step-5,
    #widget-vue-body.step-6,
    #widget-vue-body.mr-open { padding: 0; }
    #widget-vue-body.step-2 .bk-split { flex-direction: column; height: 100%; overflow-y: auto; }
    #widget-vue-body .bk-main { height: auto; overflow: visible; flex: 0 0 auto; }
    #widget-vue-body .bk-side {
        flex: 0 0 auto; width: 100%; max-width: 100%; height: auto; overflow: visible;
        padding: 0 clamp(16px, 3vw, 40px) 40px;
    }
    #widget-vue-body .bk-map { height: 285px; }
    #widget-vue-body .bk-map-canvas { height: 239px; }
}
@media (max-width: 640px) {
    #widget-vue-body .bk-contact-fields { grid-template-columns: 1fr; }
    #widget-vue-body .bk-rider-fields { grid-template-columns: 1fr; }
    #widget-vue-body .bk-flight-grid { grid-template-columns: 1fr; }
    /* Wrap the result line rather than squeezing the route out of it. */
    #widget-vue-body .bk-flight-item { flex-wrap: wrap; }
    #widget-vue-body .bk-flight-meta { flex-basis: 100%; white-space: normal; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Persistent top bar (bkh-) — "New Reservation" + inline Log in / account.
   Rendered by frontend/booking-tools/_header.blade.php above .bkh-body on
   every step, in both the standalone page and the embed. The sign-in controls
   inside reuse the bk- primitives (.bk-field/.bk-otp-box/.bk-btn-outline) so
   the header and the step-2 Contact card stay visually identical.
   ══════════════════════════════════════════════════════════════════════════ */
#widget-vue-body .bkh-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    width: 100%;
    /* anchor for the absolute My Rides overlay */
    position: relative;
}
/* Each step wrapper fills what the top bar leaves. The step markup asks for
   `h-full`, but a percentage height resolves against this box's `height: auto`
   (its used height comes from flex) and would collapse to content height —
   so size them as flex items instead. */
#widget-vue-body .bkh-body > div {
    flex: 1 1 auto;
    min-height: 0;
}

#widget-vue-body .bkh {
    flex: 0 0 auto;
    background: var(--bt-card);
    border-bottom: 1px solid var(--bt-border);
    padding: 12px clamp(16px, 3vw, 40px);
}
#widget-vue-body .bkh-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 20px;
    min-height: 36px;
}

/* ── Text buttons ─────────────────────────────────────────────────────────── */
#widget-vue-body .bkh-brand,
#widget-vue-body .bkh-login,
#widget-vue-body .bkh-close,
#widget-vue-body .bkh-logout {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--bt-text);
    white-space: nowrap;
    transition: color 0.2s ease;
}
#widget-vue-body .bkh-brand i,
#widget-vue-body .bkh-login i,
#widget-vue-body .bkh-close i,
#widget-vue-body .bkh-logout i { font-size: 14px; }
#widget-vue-body .bkh-brand:hover,
#widget-vue-body .bkh-login:hover { color: var(--brand-primary); }
#widget-vue-body .bkh-close:hover { color: var(--bt-muted); }
#widget-vue-body .bkh-logout { color: #ef4444; font-size: 12.5px; }
#widget-vue-body .bkh-myrides {
    display: inline-flex; align-items: center; gap: 8px;
    background: none; border: none; padding: 0; cursor: pointer;
    font-size: 13.5px; font-weight: 700; color: var(--bt-text); white-space: nowrap;
    transition: color 0.2s ease;
}
#widget-vue-body .bkh-myrides i { font-size: 13px; }
#widget-vue-body .bkh-myrides:hover { color: var(--brand-primary); }

/* ── Right-hand slot ──────────────────────────────────────────────────────── */
#widget-vue-body .bkh-auth {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
    margin-left: auto;
}
#widget-vue-body .bkh-form {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
#widget-vue-body .bkh-field { min-width: 240px; }
#widget-vue-body .bkh-btn { align-self: auto; white-space: nowrap; }

/* Compact OTP boxes — the full-size ones are 40×46 and overwhelm a 36px bar. */
#widget-vue-body .bkh-otp { gap: 6px; }
#widget-vue-body .bkh-otp .bk-otp-box { width: 34px; height: 38px; font-size: 15px; }

/* Provisional-profile row: same 3-up grid as the Contact card's guest fields. */
#widget-vue-body .bkh-profile-fields { flex: 1; min-width: 0; }

/* ── Signed in ────────────────────────────────────────────────────────────── */
#widget-vue-body .bkh-user { display: flex; align-items: center; gap: 9px; min-width: 0; }
#widget-vue-body .bkh-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    background: var(--brand-primary);
    color: #fff;
    font-size: 12px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
}
#widget-vue-body .bkh-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
#widget-vue-body .bkh-name {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--bt-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Mobile: the open form takes its own line under the brand ─────────────── */
@media (max-width: 640px) {
    #widget-vue-body .bkh { padding: 10px 16px; }
    /* Collapsed (trigger or account chip) stays on the brand's line; only the
       open form claims a row of its own — hence the .is-open flag rather than
       a :has() selector. */
    #widget-vue-body .bkh-auth.is-open { flex: 1 1 100%; margin-left: 0; flex-wrap: wrap; }
    #widget-vue-body .bkh-form { flex: 1 1 100%; flex-wrap: wrap; }
    #widget-vue-body .bkh-form--profile { flex-direction: column; align-items: stretch; }
    #widget-vue-body .bkh-field { min-width: 0; flex: 1 1 auto; }
    #widget-vue-body .bkh-profile-fields { width: 100%; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Thank-you step (ty-) — centered, minimal confirmation (no map). Rendered by
   frontend/booking-tools/_thank-you.blade.php at step 5, both index + embed.
   Deliberately does NOT reuse the `.a2z-*` map/panel-split classes (still used
   by step 6), so those `:not(.step-1)` rules don't apply here.
   ══════════════════════════════════════════════════════════════════════════ */
@keyframes checkPop {
    0%   { transform: scale(0);    opacity: 0; }
    70%  { transform: scale(1.15); }
    100% { transform: scale(1);    opacity: 1; }
}
#widget-vue-body .check-pop { animation: checkPop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both; }

#widget-vue-body .ty-wrap {
    height: 100%;
    overflow-y: auto;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: clamp(24px, 6vh, 72px) 20px 40px;
    background: var(--bt-bg);
}
#widget-vue-body .ty-card { width: 100%; max-width: 560px; text-align: center; }

#widget-vue-body .ty-check {
    width: 56px; height: 56px; margin: 0 auto 18px;
    border-radius: 50%;
    background: #e7f5ec; color: #16a34a;
    display: flex; align-items: center; justify-content: center;
    font-size: 22px;
}
#widget-vue-body .ty-eyebrow {
    font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--bt-muted); margin-bottom: 12px;
}
#widget-vue-body .ty-title { font-size: clamp(22px, 3.2vw, 28px); font-weight: 800; color: var(--bt-text); line-height: 1.15; }
#widget-vue-body .ty-sub {
    font-size: 14px; line-height: 1.55; color: var(--bt-muted);
    max-width: 46ch; margin: 10px auto 0;
}

/* Ruled summary rows */
#widget-vue-body .ty-rows { margin-top: 28px; text-align: left; }
#widget-vue-body .ty-row {
    display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
    padding: 13px 2px;
    border-top: 1px solid var(--bt-border);
}
#widget-vue-body .ty-row:last-child { border-bottom: 1px solid var(--bt-border); }
#widget-vue-body .ty-row dt { flex: 0 0 auto; font-size: 12.5px; color: var(--bt-muted); }
#widget-vue-body .ty-row dd {
    flex: 1 1 auto; min-width: 0; text-align: right;
    font-size: 13.5px; font-weight: 700; color: var(--bt-text); word-break: break-word;
}
#widget-vue-body .ty-dim { color: var(--bt-muted); font-weight: 600; }
#widget-vue-body .ty-arrow { font-size: 10px; color: var(--brand-primary); margin: 0 3px; }
#widget-vue-body .ty-paid { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
#widget-vue-body .ty-total { color: var(--bt-text); }
#widget-vue-body .ty-paid-ok { color: #16a34a; font-size: 14px; }

/* Collapsible details */
#widget-vue-body .ty-details { margin-top: 18px; border: 1px solid var(--bt-border); text-align: left; }
#widget-vue-body .ty-details > summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 13px 16px;
    font-size: 12.5px; font-weight: 700; color: var(--brand-primary);
}
#widget-vue-body .ty-details > summary::-webkit-details-marker { display: none; }
#widget-vue-body .ty-chev { font-size: 11px; transition: transform 0.25s ease; }
#widget-vue-body .ty-details[open] > summary { border-bottom: 1px solid var(--bt-border); }
#widget-vue-body .ty-details[open] .ty-chev { transform: rotate(180deg); }
#widget-vue-body .ty-details-body > .ty-block { padding: 16px; border-top: 1px solid var(--bt-border); }
#widget-vue-body .ty-details-body > .ty-block:first-child { border-top: none; }

#widget-vue-body .ty-block-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
#widget-vue-body .ty-tags { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
#widget-vue-body .ty-tag { padding: 2px 9px; font-size: 10px; font-weight: 700; border: 1px solid var(--bt-border); color: var(--bt-muted); }
#widget-vue-body .ty-tag--primary { border-color: var(--brand-primary); color: var(--brand-primary); }
#widget-vue-body .ty-tag-id { font-size: 11px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .ty-when { font-size: 11px; color: var(--bt-muted); }
#widget-vue-body .ty-block-label { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--bt-muted); margin-bottom: 10px; }

/* Route legs (dot rail) */
#widget-vue-body .ty-route { display: flex; flex-direction: column; }
#widget-vue-body .ty-leg { display: flex; align-items: stretch; gap: 12px; }
#widget-vue-body .ty-leg-rail { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
#widget-vue-body .ty-dot { width: 7px; height: 7px; border-radius: 50%; margin-top: 5px; }
#widget-vue-body .ty-dot--primary { background: var(--brand-primary); }
#widget-vue-body .ty-dot--via { background: #cbd0d6; }
#widget-vue-body .ty-dot--end { background: #8b929a; }
#widget-vue-body .ty-line { width: 1px; flex: 1; background: var(--bt-border); margin: 3px 0; }
#widget-vue-body .ty-leg-text { font-size: 12.5px; color: var(--bt-text); padding-bottom: 10px; min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#widget-vue-body .ty-leg:last-child .ty-leg-text { padding-bottom: 0; }

/* Fare / passenger rows */
#widget-vue-body .ty-fare { display: flex; flex-direction: column; gap: 8px; }
#widget-vue-body .ty-fare-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12.5px; color: var(--bt-muted); }
#widget-vue-body .ty-fare-amt { font-weight: 700; color: var(--bt-text); }
#widget-vue-body .ty-fare-row--rule { border-top: 1px solid var(--bt-border); padding-top: 8px; color: var(--bt-text); font-weight: 700; }
#widget-vue-body .ty-fare-row--discount { color: #16a34a; }
#widget-vue-body .ty-fare-row--discount .ty-fare-amt { color: #16a34a; }
#widget-vue-body .ty-fare-row--total { border-top: 1px solid var(--bt-border); padding-top: 8px; color: var(--bt-text); font-weight: 800; font-size: 14px; }

#widget-vue-body .ty-grand { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; background: var(--bt-soft); border-top: 1px solid var(--bt-border); }
#widget-vue-body .ty-grand-label { font-size: 11px; font-weight: 600; color: var(--bt-muted); }
#widget-vue-body .ty-grand-ids { font-size: 10px; color: var(--bt-muted); }
#widget-vue-body .ty-grand-amt { font-size: 18px; font-weight: 800; color: var(--brand-primary); }

/* Make another booking — bordered pill matching the mockup buttons */
#widget-vue-body .ty-again {
    margin: 26px auto 0;
    display: inline-flex; align-items: center; gap: 9px;
    padding: 12px 26px;
    border: 1.5px solid var(--brand-primary); background: none; color: var(--brand-primary);
    font-size: 13px; border-radius: var(--bt-btn-radius, 0);
    font-family: var(--bt-btn-font, inherit); font-weight: var(--bt-btn-weight, 700); text-transform: var(--bt-btn-transform, none);
    cursor: pointer; transition: var(--transition-smooth);
}
#widget-vue-body .ty-again:hover { background: var(--bt-btn-bg, var(--brand-primary)); color: #fff; }

@media (max-width: 640px) {
    #widget-vue-body .ty-row { flex-direction: column; align-items: flex-start; gap: 3px; }
    #widget-vue-body .ty-row dd { text-align: left; }
    #widget-vue-body .ty-paid { justify-content: flex-start; }
}

/* ── Quote sent (step 7) ───────────────────────────────────────────────────
   The confirmation for a quote request rather than a booking. Borrows the
   thank-you card wholesale — same check mark, eyebrow and row rhythm — and adds
   only the two things that differ: a price that is pending instead of paid, and
   a link out to the thread where it lands. */
#widget-vue-body .qs-pending { display: flex; align-items: center; justify-content: flex-end; gap: 7px; color: var(--brand-primary); font-weight: 700; }
#widget-vue-body .qs-pending i { font-size: 12px; }
#widget-vue-body .qs-track { margin-top: 24px; text-decoration: none; }

@media (max-width: 640px) {
    #widget-vue-body .qs-pending { justify-content: flex-start; }
}

/* ══════════════════════════════════════════════════════════════════════════
   My Rides (mr-) — signed-in ride history overlay, opened from the header.
   Absolute layer over .bkh-body (steps stay mounted underneath). `list` shows
   Upcoming/Past cards; `detail` is map-left / info-right (info blocks mirror the
   thank-you step, sourced from a Firestore ride doc). See _my-rides.blade.php.
   ══════════════════════════════════════════════════════════════════════════ */
/* The .mr-open edge inset (matching every step) is set with the shared padding
   rule near the step-2/5/6 block above. The overlay itself fills .bkh-body. */
#widget-vue-body .mr-overlay {
    position: absolute;
    inset: 0;
    z-index: 6;
    background: var(--bt-bg);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* ── List ─────────────────────────────────────────────────────────────────── */
#widget-vue-body .mr-list { flex: 1; min-height: 0; overflow-y: auto; }
#widget-vue-body .mr-list-inner {
    width: 100%; max-width: 860px; margin: 0 auto;
    padding: clamp(20px, 4vh, 44px) clamp(16px, 3vw, 32px) 40px;
}
#widget-vue-body .mr-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
#widget-vue-body .mr-tabs { display: flex; gap: 22px; }
#widget-vue-body .mr-tab {
    background: none; border: none; padding: 4px 0; cursor: pointer;
    font-size: 12px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--bt-muted); position: relative; transition: color 0.2s ease;
}
#widget-vue-body .mr-tab.is-active { color: var(--bt-text); }
#widget-vue-body .mr-tab.is-active::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -6px; height: 3px;
    border-radius: 3px; background: var(--brand-primary);
}
#widget-vue-body .mr-close {
    width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--bt-border);
    background: var(--bt-card); color: var(--bt-muted); cursor: pointer; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center; font-size: 13px;
    transition: var(--transition-smooth);
}
#widget-vue-body .mr-close:hover { color: var(--bt-text); border-color: var(--bt-muted); }

#widget-vue-body .mr-cards { display: flex; flex-direction: column; gap: 12px; }
#widget-vue-body .mr-card {
    display: flex; align-items: center; gap: 18px; text-align: left; cursor: pointer;
    background: var(--bt-card); border: 1px solid var(--bt-border);
    padding: 16px 18px; transition: var(--transition-smooth); width: 100%;
}
#widget-vue-body .mr-card:hover { border-color: var(--brand-primary); box-shadow: var(--shadow-soft); }
#widget-vue-body .mr-card-when { flex: 0 0 92px; min-width: 0; }
#widget-vue-body .mr-card-day { display: block; font-size: 14px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .mr-card-time { display: block; font-size: 12px; color: var(--bt-muted); margin-top: 2px; }
#widget-vue-body .mr-card-mid { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
#widget-vue-body .mr-card-route {
    font-size: 14px; font-weight: 700; color: var(--bt-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#widget-vue-body .mr-card-arrow { font-size: 10px; color: var(--brand-primary); margin: 0 3px; }
#widget-vue-body .mr-card-sub {
    font-size: 12px; color: var(--bt-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#widget-vue-body .mr-card-plane { color: var(--brand-primary); font-size: 10px; }
#widget-vue-body .mr-card-end { flex: 0 0 auto; display: flex; align-items: center; gap: 16px; }
#widget-vue-body .mr-card-amt { font-size: 15px; font-weight: 800; color: var(--bt-text); white-space: nowrap; }
#widget-vue-body .mr-card-badge {
    font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
    padding: 6px 12px; border-radius: var(--radius-pill); white-space: nowrap;
}
/* Live badge: brand fill, RED border, and a zoom-in/out pulse so an in-progress
   ride reads as "happening now". Used by the ongoing-ride card and any assigned
   upcoming ride. */
@keyframes mrLivePulse {
    0%, 100% { transform: scale(1);    border-color: #ef4444; box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.45); }
    50%      { transform: scale(1.07); border-color: #dc2626; box-shadow: 0 0 0 5px rgba(239, 68, 68, 0); }
}
#widget-vue-body .mr-card-badge.is-live {
    background: var(--brand-primary-light);
    color: var(--brand-primary);
    border: 1.5px solid #ef4444;
    animation: mrLivePulse 1.5s ease-in-out infinite;
}
#widget-vue-body .mr-live-dot {
    display: inline-block; width: 6px; height: 6px; border-radius: 50%;
    background: var(--brand-primary); margin-right: 6px; vertical-align: middle;
}
@media (prefers-reduced-motion: reduce) {
    #widget-vue-body .mr-card-badge.is-live { animation: none; }
}
#widget-vue-body .mr-card-badge.is-plain { border: 1px solid var(--bt-border); color: var(--bt-muted); }

/* ── Ongoing-ride card (above the Upcoming/Past tabs) ─────────────────────── */
#widget-vue-body .mr-current {
    display: flex; align-items: center; justify-content: space-between; gap: 18px;
    width: 100%; text-align: left; cursor: pointer;
    background: var(--bt-card); border: 1px solid var(--bt-border);
    padding: 16px 18px; margin-bottom: 18px;
    transition: var(--transition-smooth);
}
#widget-vue-body .mr-current:hover { border-color: var(--brand-primary); box-shadow: var(--shadow-soft); }
#widget-vue-body .mr-current-mid { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
#widget-vue-body .mr-current-route {
    font-size: 14.5px; font-weight: 700; color: var(--bt-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#widget-vue-body .mr-current-sub {
    font-size: 12px; color: var(--bt-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#widget-vue-body .mr-tracked { color: var(--brand-primary); font-weight: 600; }
#widget-vue-body .mr-current-end { flex: 0 0 auto; display: flex; align-items: center; gap: 16px; }

@media (max-width: 560px) {
    #widget-vue-body .mr-current { flex-wrap: wrap; }
    #widget-vue-body .mr-current-mid { flex-basis: 100%; }
    #widget-vue-body .mr-current-end { margin-left: auto; }
}

/* ── Skeleton rows while the ride lists load ──────────────────────────────── */
@keyframes mrShimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
#widget-vue-body .mr-skel { cursor: default; pointer-events: none; }
#widget-vue-body .mr-skel:hover { border-color: var(--bt-border); box-shadow: none; }
#widget-vue-body .mr-sk {
    display: block;
    border-radius: 4px;
    background: linear-gradient(90deg, #ece4dc 25%, #f8f3ee 37%, #ece4dc 63%);
    background-size: 200% 100%;
    animation: mrShimmer 1.4s linear infinite;
}
#widget-vue-body .mr-sk-day   { width: 64px; height: 13px; }
#widget-vue-body .mr-sk-time  { width: 44px; height: 11px; margin-top: 6px; }
#widget-vue-body .mr-sk-route { width: 62%;  height: 13px; }
#widget-vue-body .mr-sk-sub   { width: 44%;  height: 11px; }
#widget-vue-body .mr-sk-amt   { width: 58px; height: 14px; }
#widget-vue-body .mr-sk-badge { width: 84px; height: 26px; border-radius: var(--radius-pill); }
/* Stagger the line widths so the stack doesn't read as a repeating pattern */
#widget-vue-body .mr-skel:nth-child(2n) .mr-sk-route { width: 52%; }
#widget-vue-body .mr-skel:nth-child(2n) .mr-sk-sub   { width: 38%; }
#widget-vue-body .mr-skel:nth-child(3n) .mr-sk-route { width: 71%; }
#widget-vue-body .mr-skel:nth-child(3n) .mr-sk-sub   { width: 50%; }
@media (prefers-reduced-motion: reduce) {
    #widget-vue-body .mr-sk { animation: none; }
}

#widget-vue-body .mr-state {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 12px; padding: 64px 20px; color: var(--bt-muted); text-align: center;
}
#widget-vue-body .mr-state i { font-size: 26px; color: var(--bt-border); }
#widget-vue-body .mr-state p { font-size: 13.5px; }

/* ── Detail (map left, info right) ────────────────────────────────────────── */
#widget-vue-body .mr-detail { flex: 1; min-height: 0; display: flex; flex-direction: row; }
#widget-vue-body .mr-detail-map { position: relative; flex: 1 1 auto; min-width: 0; background: #eae7e1; }
#widget-vue-body .mr-map-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
#widget-vue-body .mr-back {
    position: absolute; top: 16px; left: 16px; z-index: 2;
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--bt-card); border: 1px solid var(--bt-border);
    padding: 9px 15px; cursor: pointer; font-size: 12.5px; font-weight: 700; color: var(--bt-text);
    box-shadow: var(--shadow-soft); transition: var(--transition-smooth);
}
#widget-vue-body .mr-back:hover { border-color: var(--brand-primary); color: var(--brand-primary); }

#widget-vue-body .mr-panel {
    flex: 0 0 380px; width: 380px; max-width: 380px;
    background: var(--bt-card); border-left: 1px solid var(--bt-border);
    display: flex; flex-direction: column; min-height: 0;
}
#widget-vue-body .mr-panel-scroll {
    flex: 1; overflow-y: auto; padding: 24px 22px 32px;
    display: flex; flex-direction: column; gap: 16px;
}
#widget-vue-body .mr-status {
    font-size: 11px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--bt-muted);
}

/* Live ride-mode chip (Driver on Way / Arrived at Pickup / Passenger on Board).
   Static chip with a pulsing dot — the chip itself doesn't zoom, so it stays
   readable next to the driver card. */
@keyframes mrDotPulse {
    0%, 100% { transform: scale(1);   opacity: 1; }
    50%      { transform: scale(1.6); opacity: 0.45; }
}
#widget-vue-body .mr-mode {
    align-self: flex-start;
    display: inline-flex; align-items: center; gap: 9px;
    padding: 7px 14px; border-radius: var(--radius-pill);
    background: var(--brand-primary-light); color: var(--brand-primary);
    border: 1.5px solid #ef4444;
    font-size: 11.5px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
}
#widget-vue-body .mr-mode-dot {
    width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
    background: #ef4444; animation: mrDotPulse 1.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    #widget-vue-body .mr-mode-dot { animation: none; }
}

#widget-vue-body .mr-driver { display: flex; align-items: center; gap: 12px; }
#widget-vue-body .mr-driver-avatar {
    width: 52px; height: 52px; border-radius: 50%; overflow: hidden; flex-shrink: 0;
    background: var(--brand-primary); color: #fff; font-weight: 800; font-size: 19px;
    display: flex; align-items: center; justify-content: center;
}
#widget-vue-body .mr-driver-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
#widget-vue-body .mr-driver-name { font-size: 15px; font-weight: 700; color: var(--bt-text); display: flex; align-items: center; gap: 8px; }
#widget-vue-body .mr-driver-rating { font-size: 12px; font-weight: 700; color: var(--bt-muted); }
#widget-vue-body .mr-driver-rating i { color: #f5a623; font-size: 11px; }
#widget-vue-body .mr-driver-veh { font-size: 12.5px; color: var(--bt-muted); margin-top: 2px; }

#widget-vue-body .mr-plate {
    align-self: flex-start; padding: 9px 16px; border: 1.5px solid var(--bt-text);
    font-size: 14px; font-weight: 800; letter-spacing: 0.08em; color: var(--bt-text);
}
#widget-vue-body .mr-chip {
    align-self: flex-start; display: inline-flex; align-items: center; gap: 8px;
    padding: 6px 12px; border-radius: var(--radius-pill); background: var(--bt-soft);
    font-size: 12px; font-weight: 700; color: var(--bt-text);
}
#widget-vue-body .mr-chip i { color: var(--brand-primary); font-size: 11px; }

#widget-vue-body .mr-block { border-top: 1px solid var(--bt-border); padding-top: 16px; }
#widget-vue-body .mr-block:first-of-type { border-top: none; padding-top: 0; }
#widget-vue-body .mr-block-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
#widget-vue-body .mr-tag { padding: 2px 9px; font-size: 10px; font-weight: 700; border: 1px solid var(--bt-border); color: var(--bt-muted); text-transform: capitalize; }
#widget-vue-body .mr-tag.is-confirmed, #widget-vue-body .mr-status.is-confirmed { color: #16a34a; }
#widget-vue-body .mr-tag.is-cancelled, #widget-vue-body .mr-status.is-cancelled { color: #ef4444; border-color: #ef4444; }
#widget-vue-body .mr-block-id { font-size: 11px; font-weight: 700; color: var(--bt-text); }
#widget-vue-body .mr-block-label { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--bt-muted); margin-bottom: 10px; }
#widget-vue-body .mr-when-row { font-size: 12px; color: var(--bt-muted); margin-bottom: 10px; }

#widget-vue-body .mr-route { display: flex; flex-direction: column; }
#widget-vue-body .mr-leg { display: flex; align-items: stretch; gap: 12px; }
#widget-vue-body .mr-leg-rail { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
#widget-vue-body .mr-dot { width: 7px; height: 7px; border-radius: 50%; margin-top: 5px; }
#widget-vue-body .mr-dot--primary { background: var(--brand-primary); }
#widget-vue-body .mr-dot--via { background: #cbd0d6; }
#widget-vue-body .mr-dot--end { background: #8b929a; }
#widget-vue-body .mr-line { width: 1px; flex: 1; background: var(--bt-border); margin: 3px 0; }
#widget-vue-body .mr-leg-text { font-size: 12.5px; color: var(--bt-text); padding-bottom: 10px; min-width: 0; flex: 1; }
#widget-vue-body .mr-leg:last-child .mr-leg-text { padding-bottom: 0; }
#widget-vue-body .mr-dim { color: var(--bt-muted); }

#widget-vue-body .mr-facts { display: flex; flex-direction: column; gap: 8px; }
#widget-vue-body .mr-fact { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12.5px; color: var(--bt-muted); }
#widget-vue-body .mr-fact-v { font-weight: 700; color: var(--bt-text); text-align: right; }

#widget-vue-body .mr-fare { display: flex; flex-direction: column; gap: 8px; }
#widget-vue-body .mr-fare-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12.5px; color: var(--bt-muted); }
#widget-vue-body .mr-fare-amt { font-weight: 700; color: var(--bt-text); }
#widget-vue-body .mr-fare-row--rule { border-top: 1px solid var(--bt-border); padding-top: 8px; color: var(--bt-text); font-weight: 700; }
#widget-vue-body .mr-fare-row--discount, #widget-vue-body .mr-fare-row--discount .mr-fare-amt { color: #16a34a; }
#widget-vue-body .mr-fare-row--total { border-top: 1px solid var(--bt-border); padding-top: 8px; color: var(--bt-text); font-weight: 800; font-size: 14px; }

/* Branded, like every other action in the widget (.a2z-cta-btn) — this was the
   one live button painted with --brand-dark, which is a *text* token: it is
   #121214 in light (a black button on a white-label widget) and flips to
   #f3f4f6 in dark, which put white text on a near-white button. */
#widget-vue-body .mr-call {
    margin-top: 4px; display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    padding: 13px 18px; background: var(--bt-btn-bg, var(--brand-primary)); color: #fff; text-decoration: none;
    font-size: 13px; border-radius: var(--bt-btn-radius, 0);
    font-family: var(--bt-btn-font, inherit); font-weight: var(--bt-btn-weight, 700); text-transform: var(--bt-btn-transform, none);
    transition: var(--transition-smooth);
}
#widget-vue-body .mr-call:hover { background: var(--bt-btn-bg-hover, var(--brand-primary-hover)); }

/* ── Responsive: stack the detail (map on top), single-column list cards ────── */
@media (max-width: 860px) {
    #widget-vue-body .mr-detail { flex-direction: column; overflow-y: auto; }
    #widget-vue-body .mr-detail-map { flex: 0 0 auto; height: 260px; }
    #widget-vue-body .mr-map-canvas { position: relative; height: 260px; }
    #widget-vue-body .mr-panel { flex: 0 0 auto; width: 100%; max-width: 100%; border-left: none; border-top: 1px solid var(--bt-border); }
    #widget-vue-body .mr-panel-scroll { overflow: visible; }
}
@media (max-width: 560px) {
    #widget-vue-body .mr-card { flex-wrap: wrap; gap: 10px 14px; }
    #widget-vue-body .mr-card-when { flex-basis: auto; }
    #widget-vue-body .mr-card-mid { flex-basis: 100%; order: 3; }
    #widget-vue-body .mr-card-end { margin-left: auto; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Quote Contact modal (_quote-contact.blade.php)
   Shown when the quote comes back with no_rate — the region has no priceable
   rate, so the visitor sends a manual quote request instead.

   Sits inside the shared `.modal` overlay but overrides two things it inherits
   from `.modal-content`, which is sized for the narrow auth dialog: the 380px
   width, and `overflow-y: auto`. The dialog is a flex column that scrolls its
   own middle section instead, so the title and the submit button stay put on a
   short viewport rather than scrolling out of reach.
   ══════════════════════════════════════════════════════════════════════════ */
#widget-vue-body .qc-modal {
    /* .modal-content is hardcoded `background: #fff`, and only .qc-footer ever
       painted over it — so on a dark scheme this panel came out white, with
       .qc-title's var(--bt-text) rendering white-on-white. It was survivable
       while the fields carried their own dark fill; in Underline style the
       fields have no fill and their white hairline vanishes too, taking the
       whole form with it. On a light scheme --bt-card IS #fff, so this changes
       nothing there. Scoped to .qc-modal: the legacy auth modal shares
       .modal-content and is a separate job. */
    background: var(--bt-card);
    max-width: 560px;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    border-radius: 0;
    border: 1px solid var(--bt-border);
}

#widget-vue-body .qc-head {
    flex-shrink: 0;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 22px 24px 18px;
    border-bottom: 1px solid var(--bt-border);
}
#widget-vue-body .qc-title { font-size: 17px; font-weight: 800; line-height: 1.3; color: var(--bt-text); }
#widget-vue-body .qc-sub { margin-top: 7px; font-size: 12.5px; line-height: 1.5; color: var(--bt-muted); }
#widget-vue-body .qc-close {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bt-soft);
    border: none;
    color: var(--bt-muted);
    font-size: 13px;
    cursor: pointer;
    transition: var(--transition-smooth);
}
#widget-vue-body .qc-close:hover { color: var(--bt-text); }

/* Form owns the remaining height: scrolling middle + pinned footer. */
#widget-vue-body .qc-form { display: flex; flex-direction: column; flex: 1; min-height: 0; }
#widget-vue-body .qc-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 20px 24px;
}
#widget-vue-body .qc-footer {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 16px 24px 20px;
    background: var(--bt-card);
    border-top: 1px solid var(--bt-border);
}

/* Read-only trip summary — the route we could not price. Reuses the quote
   step's endpoint dots so it reads as the same journey the visitor entered. */
#widget-vue-body .qc-trip {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 15px 16px;
    background: var(--bt-soft);
    border: 1px solid var(--bt-border);
}
#widget-vue-body .qc-trip-route { display: flex; flex-direction: column; gap: 14px; }
#widget-vue-body .qc-trip-row { position: relative; display: flex; align-items: flex-start; gap: 12px; }
/* Connector between the two endpoint dots — .bq-dot is 9px wide, so 4px centres it. */
#widget-vue-body .qc-trip-row + .qc-trip-row::before {
    content: '';
    position: absolute;
    left: 4px;
    top: -18px;
    height: 18px;
    width: 1px;
    background: var(--bt-border);
}
#widget-vue-body .qc-trip-row > .bq-dot { margin-top: 5px; }
#widget-vue-body .qc-trip-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
#widget-vue-body .qc-trip-value { font-size: 13.5px; font-weight: 600; line-height: 1.4; color: var(--bt-text); word-break: break-word; }
#widget-vue-body .qc-trip-when {
    display: flex;
    align-items: center;
    gap: 9px;
    padding-top: 12px;
    border-top: 1px solid var(--bt-border);
    font-size: 13px;
    font-weight: 600;
    color: var(--bt-text);
}
#widget-vue-body .qc-trip-when i { font-size: 12px; color: var(--bt-muted); }

#widget-vue-body .qc-row { display: flex; gap: 12px; }
#widget-vue-body .qc-row > .bq-section { flex: 1; min-width: 0; }
#widget-vue-body .qc-optional { font-weight: 500; text-transform: none; letter-spacing: normal; }

#widget-vue-body .qc-textarea {
    width: 100%;
    box-sizing: border-box;
    background: var(--input-bg);
    border: 1.5px solid var(--field-border);
    border-radius: var(--bt-field-radius, 0);
    padding: 13px 16px;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
    color: var(--bt-text);
    resize: vertical;
    transition: var(--transition-smooth);
}
#widget-vue-body .qc-textarea:focus {
    border-color: var(--brand-primary) !important;
    box-shadow: 0 0 0 3px var(--brand-primary-light) !important;
}
#widget-vue-body .qc-textarea::placeholder { color: #9c9490; }

@media (max-width: 560px) {
    #widget-vue-body .qc-modal { max-height: 92vh; }
    #widget-vue-body .qc-head { padding: 18px 18px 15px; }
    #widget-vue-body .qc-scroll { padding: 16px 18px; gap: 15px; }
    #widget-vue-body .qc-footer { padding: 14px 18px 16px; }
    #widget-vue-body .qc-row { flex-direction: column; gap: 15px; }
}

/* ── Per-field labels ─────────────────────────────────────────────────────
   A label sitting above its field, written into the markup for every field in
   the booking flow — but VISUALLY HIDDEN unless Appearance › Form Fields is set
   to Underline.

   Hidden by clipping rather than `display: none` on purpose: the label is a
   real <label> tied to a real control, so screen readers should keep reading it
   even on installs that never turn Underline on. That makes this an
   accessibility gain for every install while staying pixel-identical on the
   ones that have not opted in — which is the standing contract for everything
   on the Appearance panel.
   ────────────────────────────────────────────────────────────────────────── */
/* Wraps one label + one field so the label stays glued to its own control
   instead of picking up the parent section's gap. In Boxed style it is a
   transparent flex column around a single 100%-wide field, so it changes no
   layout — .bt-fgroup--grow just carries the `flex: 1` the field used to. */
#widget-vue-body .bt-fgroup { display: flex; flex-direction: column; min-width: 0; }
#widget-vue-body .bt-fgroup--grow { flex: 1 1 0; min-width: 0; }

#widget-vue-body .bt-flabel {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* The required marker. Gated too — the labels in the Quote Contact form and the
   Book step are already visible in Boxed style, so an ungated asterisk would
   appear on installs that never asked for one. */
#widget-vue-body .bt-req { display: none; color: #ef4444; }

/* ── In-field placeholder ─────────────────────────────────────────────────
   Text inputs do NOT get a label above them — they carry their name in the
   placeholder, with the required marker inside it. `::placeholder` styles the
   whole string and cannot colour part of it, so the placeholder is rendered as
   a real element sitting over the input and the native one is made transparent.

   .bt-inph is a zero-cost wrapper that gives .bt-ph something exact to anchor
   to: `inset: 0` on the input's own box means the text lands on the input's
   text origin whatever precedes it — a dot, an icon, a country flag, nothing —
   with no offset arithmetic to keep in sync.

   Inert in Boxed style: .bt-ph is display:none and the native placeholder is
   untouched, so nothing here changes an install that has not opted in.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body .bt-inph {
    position: relative;
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
}
#widget-vue-body .bt-ph { display: none; }

/* ── Field style: Underline ───────────────────────────────────────────────
   Appearance › Form Fields › Field Style. Strips the box off every text input,
   select and textarea and leaves one hairline underneath, with the field's
   label promoted above it.

   No !important anywhere in here. Every selector below adds
   [data-field-style="underline"] to a rule that is otherwise identical, so it
   wins on specificity regardless of where it sits in the file. (The !important
   the server puts on --bt-field-radius is on the custom property, not on
   `border-radius`, so a plain `border-radius: 0` here still overrides
   `border-radius: var(--bt-field-radius)`.)

   Not underlined, deliberately: .bk-otp-box (six discrete boxes ARE the
   affordance), .bk-step-ctrl / .bk-step-btn (steppers keep their shape, same
   carve-out the Buttons section makes), .bk-pay-chip / .bk-card / .bk-cardpick
   / .bk-card-change (selectable cards, not inputs), and the .a2z-pac / .a2z-ac
   / .a2z-fp / .a2z-tp popovers, which still need an edge to sit on.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body[data-field-style="underline"] .bt-flabel {
    position: static;
    display: block;
    width: auto;
    height: auto;
    margin: 0 0 3px;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--bt-muted);
}

#widget-vue-body[data-field-style="underline"] .bt-req { display: inline; }

/* The swap only happens where :has() can drive it. intl-tel-input moves the
   phone input inside its own .iti div, so a sibling combinator reaches it on
   some fields and not others; :has() on the wrapper covers both. Wrapping the
   whole thing in @supports keeps the failure safe rather than silent — without
   :has() the rules below never apply, the native placeholder stays visible and
   the only thing lost is the red asterisk. Bare `input:placeholder-shown ~
   .bt-ph` would leave fields with NO placeholder at all on those browsers,
   because the native one is transparent by then. */
@supports selector(:has(*)) {
    /* `:not(.iti__search-input)` on both rules, and it is load-bearing.
       intl-tel-input v21 ships `countrySearch: true`, so every phone field grows a
       SECOND input — the country search box inside the dropdown — nested in the
       same .bt-inph. It is permanently empty, so `:has(input:placeholder-shown)`
       matched forever and the "Phone" placeholder stayed painted over whatever
       number had been typed. Excluding it also keeps the search box's own
       placeholder visible, which the transparent rule would otherwise erase. */
    #widget-vue-body[data-field-style="underline"] .bt-inph input:not(.iti__search-input)::placeholder { color: transparent; }

    #widget-vue-body[data-field-style="underline"] .bt-inph:has(input:not(.iti__search-input):placeholder-shown) .bt-ph {
        position: absolute;
        inset: 0;
        display: flex;
        align-items: center;
        /* The text and the marker are two flex items, and flex drops the
           whitespace between them — without this they render as "Full name*". */
        gap: 4px;
        /* The value underneath must stay reachable and selectable. */
        pointer-events: none;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        color: #9c9490;
        font-weight: 500;
    }

    /* Matched to each shell's own input, which the two shells size differently. */
    #widget-vue-body[data-field-style="underline"] .bq-field .bt-ph { font-size: 14px; }
    #widget-vue-body[data-field-style="underline"] .bk-field .bt-ph { font-size: 13.5px; }

    /* Phone fields are the one case where `inset: 0` is not the text origin:
       intl-tel-input moves the input inside its own .iti div and parks the flag
       and dial code over its left edge. That width is not a constant — it grows
       with the dial code — so it is not hard-coded here either: syncItiLead()
       copies the padding iti computed for the input onto the shell as
       --iti-lead, and the placeholder standing in for that input reads the same
       number. The fallback matches iti's own arrow allowance for a field whose
       lead has not been measured yet. */
    #widget-vue-body[data-field-style="underline"] .bt-inph:has(> .iti) .bt-ph {
        padding-left: var(--iti-lead, 52px);
    }

    /* The iOS zoom guard below 1024px forces 16px on every control. .bt-ph is a
       span, so it is not caught by that rule and would drift out of step with
       the input it is standing in for. */
    @media (max-width: 1024px) {
        #widget-vue-body[data-field-style="underline"] .bq-field .bt-ph,
        #widget-vue-body[data-field-style="underline"] .bk-field .bt-ph { font-size: 16px; }
    }
}

/* Carve-out: the header's inline log-in strip keeps its labels clipped in both
   styles. It is a toolbar sitting in the header bar, not a form panel — a
   stacked label there doubles the header's height and pushes the widget down.
   The labels are still written into the markup, so assistive tech still gets
   them; only the visual promotion is withheld. */
#widget-vue-body[data-field-style="underline"] .bkh-form .bt-flabel {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* These rows sized their field with `flex: 1` on .bk-field; that job now
   belongs to the .bt-fgroup wrapper standing in its place. No alignment
   override goes with it: only the select keeps a label, and it sits in a
   column, so every field in a row still lines up on its centre as before. */
#widget-vue-body .bk-signin-row .bt-fgroup,
#widget-vue-body .bk-promo-entry .bt-fgroup { flex: 1; min-width: 0; }

/* The labels that are already visible in Boxed style — the Book step's
   .bk-mini-label and the Quote Contact form's .bq-label — restyled to match, so
   the whole flow reads as one form rather than two conventions side by side.
   .bq-label is scoped to .qc-scroll here because everywhere else in the widget
   it is a SECTION heading ("Route", "When"), not a field label, and those
   should keep their small-caps treatment. */
#widget-vue-body[data-field-style="underline"] .bk-mini-label,
#widget-vue-body[data-field-style="underline"] .qc-scroll .bq-label {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    color: var(--bt-muted);
}

/* ── The field shells ── */
#widget-vue-body[data-field-style="underline"] .bq-field,
#widget-vue-body[data-field-style="underline"] .bk-field,
#widget-vue-body[data-field-style="underline"] .bk-select-input,
#widget-vue-body[data-field-style="underline"] .bk-note textarea,
#widget-vue-body[data-field-style="underline"] .qc-textarea {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--bt-field-line);
    border-radius: 0;
}

/* Padding: the left inset goes so the value lines up under its label, and the
   bottom inset shrinks so the text sits close to its rule rather than floating
   above it. Kept per-shell because each started from a different padding. */
/* min-height, not just padding: intl-tel-input's country selector makes a phone
   field's content box 24px against a plain input's 20px, and with the box gone
   that 4px showed up as one underline hanging lower than the two beside it in
   the Name / Phone / Email row. The floor is that tallest content plus the
   field's own padding and rule. */
#widget-vue-body[data-field-style="underline"] .bq-field { padding: 10px 0 9px; min-height: 44px; }
#widget-vue-body[data-field-style="underline"] .bk-field { padding: 9px 0 8px; min-height: 42px; }
#widget-vue-body[data-field-style="underline"] .bk-select-input { padding: 8px 0; }
#widget-vue-body[data-field-style="underline"] .bk-note textarea { padding: 8px 0; }
#widget-vue-body[data-field-style="underline"] .qc-textarea { padding: 8px 0; }

/* The Book step's flight shell reserves room on the right for its absolutely
   positioned spinner; only the LEFT inset should collapse. (Step 1's flight
   field needs no reserve — its spinner is an ordinary flex child.) */
#widget-vue-body[data-field-style="underline"] .bk-field--flight { padding-right: 84px; }

/* The date/time row's tighter padding override has the same specificity as the
   rule above, so it has to be restated inside the gate or it wins by order. */
#widget-vue-body[data-field-style="underline"] .bq-datetime .bq-field { padding: 10px 0 9px; }

/* ── Focus ────────────────────────────────────────────────────────────────
   On the shell, never on the control: the global rule near the top of this file
   kills border-color, outline and box-shadow on every focused input with
   !important. The boxed style's 3px glow is dropped — a ring around nothing
   reads as a stray shadow — and replaced by thickening the rule itself. */
#widget-vue-body[data-field-style="underline"] .bq-field:focus-within,
#widget-vue-body[data-field-style="underline"] .bk-field:focus-within {
    border-bottom: 2px solid var(--bt-field-line-focus);
    box-shadow: none;
    /* Compensate the extra border pixel so the field does not jump on focus. */
    padding-bottom: 8px;
}
#widget-vue-body[data-field-style="underline"] .bq-datetime .bq-field:focus-within { padding-bottom: 8px; }
#widget-vue-body[data-field-style="underline"] .bk-field:focus-within { padding-bottom: 7px; }

/* ── Invalid ──────────────────────────────────────────────────────────────
   Restated inside the gate for the same reason focus is: the boxed rules above
   set `border-color`, which here would paint all four sides of a shell that has
   only a bottom rule left. The focused pair also has to be restated, or the
   focus rule directly above wins on order and the mark disappears the moment
   the visitor puts the caret back in the field they were sent to fix. */
#widget-vue-body[data-field-style="underline"] .bq-field.is-invalid,
#widget-vue-body[data-field-style="underline"] .bk-field.is-invalid {
    border-color: transparent;
    border-bottom-color: #ef4444;
    box-shadow: none;
}
#widget-vue-body[data-field-style="underline"] .bq-field.is-invalid:focus-within,
#widget-vue-body[data-field-style="underline"] .bk-field.is-invalid:focus-within {
    border-bottom: 2px solid #ef4444;
    box-shadow: none;
}

#widget-vue-body[data-field-style="underline"] .bk-select-input:focus,
#widget-vue-body[data-field-style="underline"] .bk-note textarea:focus {
    border-bottom: 2px solid var(--bt-field-line-focus);
    box-shadow: none;
    padding-bottom: 7px;
}

/* .qc-textarea:focus is the one field rule in this file that already uses
   !important, so beating it takes !important as well — specificity alone is
   not enough against an important declaration. */
#widget-vue-body[data-field-style="underline"] .qc-textarea:focus {
    border-color: transparent !important;
    border-bottom: 2px solid var(--bt-field-line-focus) !important;
    box-shadow: none !important;
    padding-bottom: 7px;
}

/* ── Legacy Tailwind login modal ──────────────────────────────────────────
   This modal lives inline in index.blade.php / embed.blade.php rather than in a
   shared partial, and is raw Tailwind utilities — rounded-[70px], bg-[#f6f6f6],
   hardcoded #ec6408 — reading none of the tokens. Overriding the utilities is
   the contained way to bring it in; rewriting the markup would mean editing the
   same block twice and keeping it in sync forever. !important is needed because
   Tailwind's own utilities are what we are beating, and there is precedent for
   exactly this a few hundred lines up, where the dark scheme redirects the same
   hardcoded hex utilities.

   Targeted by the two group IDs rather than by their Tailwind classes. The
   obvious selector — .bg-\[\#f6f6f6\] — also matches the six OTP boxes below
   them, which carry the same utility and are meant to stay boxed.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body[data-field-style="underline"] #emailInputGroup,
#widget-vue-body[data-field-style="underline"] #phoneInputGroup {
    background-color: transparent !important;
    border-radius: 0 !important;
    border-bottom: 1px solid var(--bt-field-line);
    padding-left: 0 !important;
    padding-right: 0 !important;
}
#widget-vue-body[data-field-style="underline"] #emailInputGroup:focus-within,
#widget-vue-body[data-field-style="underline"] #phoneInputGroup:focus-within {
    border-bottom: 2px solid var(--bt-field-line-focus);
}
/* The icon's white puck reads as a stray dot once the pill around it is gone. */
#widget-vue-body[data-field-style="underline"] #emailInputGroup > div:first-child,
#widget-vue-body[data-field-style="underline"] #phoneInputGroup > div:first-child {
    background-color: transparent !important;
    width: 22px;
    height: 22px;
}

/* ── Custom heading typography ───────────────────────────────────────────
   Applies the operator's Heading Font + Heading Weight to every headline in
   the widget.

   GATED on [data-typography="custom"], which the blades stamp only when a
   heading font or weight has actually been configured. The gate is not
   decoration: each class listed below carries its own font-weight today
   (700 on most, 800 on .bk-card-title / .bk-mini-label / .ty-block-label), and
   an ungated rule with a default weight would flatten that carefully-set
   hierarchy to a single value on every install that never asked for custom
   typography. With the gate, unconfigured installs never match this selector
   at all.

   Placed at the end of the file deliberately. These selectors have the same
   specificity as the individual rules they override (#id + one class), so the
   cascade resolves it by document order — last one wins. Move this block
   higher and it silently stops working.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body[data-typography="custom"] :is(
    h1, h2, h3, h4, h5, h6,
    .bq-headline, .bq-head, .bq-label,
    .bk-card-title, .bk-row-title, .bk-vehicle-name, .bk-mini-label,
    .bk-modal-head, .bk-signed-name, .bk-quote-note-title, .bk-toggle-title,
    .ty-title, .ty-block-label, .ty-grand-label,
    .mr-head, .mr-block-label, .mr-driver-name,
    .qc-title, .a2z-submit-title
) {
    font-family: var(--bt-font-heading);
    font-weight: var(--bt-heading-weight);
}

/* ── Google Places autocomplete dropdown ─────────────────────────────────
   Google appends `.pac-container` to <body>, NOT inside #widget-vue-body. Two
   consequences drive everything below.

   1. It cannot inherit the --bt-* tokens, because custom properties inherit
      downward and this element is not a descendant. The tokens are copied onto
      the element itself by themePacContainer() in both blades, which is why the
      var() references here resolve at all — and why they track the operator's
      theme and custom colours with no values duplicated in this block.

   2. In the embed it lands in the HOST page's DOM, and widget.css is loaded
      into that page too. So a bare `.pac-container` selector here would restyle
      a host site's own address autocomplete. Everything is scoped to the
      `.a2z-pac` class we add to our own containers, and never to `.pac-container`
      alone.
   ────────────────────────────────────────────────────────────────────────── */
.pac-container.a2z-pac {
    background-color: var(--bt-card, #fff);
    border: 1px solid var(--bt-border, #e5e7eb);
    border-radius: var(--bt-field-radius, 0);
    font-family: var(--bt-font-body, inherit);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .18);
    margin-top: 4px;
    overflow: hidden;
}

.pac-container.a2z-pac .pac-item {
    border-top: 1px solid var(--bt-border, #e5e7eb);
    padding: 9px 12px;
    font-size: 13px;
    line-height: 1.4;
    color: var(--bt-muted, #6b7280);
    cursor: pointer;
}
.pac-container.a2z-pac .pac-item:first-child { border-top: none; }

.pac-container.a2z-pac .pac-item:hover,
.pac-container.a2z-pac .pac-item-selected,
.pac-container.a2z-pac .pac-item-selected:hover {
    background-color: var(--bt-soft, #f3f4f6);
}

/* The main line of each row — the place name. */
.pac-container.a2z-pac .pac-item-query { color: var(--bt-text, #111827); font-size: 13.5px; }

/* The characters matching what was typed. Brand accent rather than Google's
   near-black, which was invisible against --bt-text on a dark card. */
.pac-container.a2z-pac .pac-matched { color: var(--brand-primary, #ec6408); font-weight: 700; }

/* ── The pin ──
   Google ships this as a raster sprite on a fixed white background, so it
   cannot be recoloured — it stayed grey-on-white and read as a hole punched in
   a dark dropdown. Dropping the sprite for a mask lets `background-color` tint
   a real vector pin with the operator's own brand colour. */
.pac-container.a2z-pac .pac-icon {
    background-image: none;
    background-color: var(--brand-primary, #ec6408);
    width: 16px;
    height: 16px;
    margin-top: 2px;
    margin-right: 8px;
    -webkit-mask-image: var(--a2z-pin);
    mask-image: var(--a2z-pin);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}
.pac-container.a2z-pac {
    --a2z-pin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2a7 7 0 0 0-7 7c0 5.25 7 13 7 13s7-7.75 7-13a7 7 0 0 0-7-7zm0 9.5A2.5 2.5 0 1 1 12 6.5a2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E");
}

/* ── "Powered by Google" ──
   Required by the Places terms, so it is swapped rather than hidden. Google
   publishes a light-on-transparent variant for dark surfaces; the default asset
   is dark-on-white and the "powered by" wording vanished against the dark card.

   NOTE the selector: `.pac-logo` is a second class on the CONTAINER ITSELF
   (Google renders `<div class="pac-container pac-logo">`), not on a child. So
   this has to be `.pac-container.a2z-pac.pac-logo::after` — a descendant
   selector silently matches nothing, which is exactly how the first cut of this
   block failed.

   The hdpi override is not optional either: Google swaps in a @2x asset behind
   a resolution media query, so without matching that block every retina screen
   — i.e. most laptops and phones — keeps the dark-on-white logo.

   Keyed the way widget.css keys everything else: data-scheme for the resolved
   choice, plus a prefers-color-scheme block for data-theme="system", which only
   the browser can settle. */
.pac-container.a2z-pac.pac-logo::after {
    background-color: transparent;
    margin-right: 10px;
}

.pac-container.a2z-pac.pac-logo[data-scheme="dark"]::after {
    background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-non-white3.png);
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx) {
    .pac-container.a2z-pac.pac-logo[data-scheme="dark"]::after {
        background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-non-white3_hdpi.png);
    }
}

@media (prefers-color-scheme: dark) {
    .pac-container.a2z-pac.pac-logo[data-theme="system"]::after {
        background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-non-white3.png);
    }
}
@media (prefers-color-scheme: dark) and (min-resolution: 1.5dppx) {
    .pac-container.a2z-pac.pac-logo[data-theme="system"]::after {
        background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-non-white3_hdpi.png);
    }
}

/* ── Address dropdown (script embed) ─────────────────────────────────────
   The embed cannot load Google's Places JS — it renders on the customer's own
   domain, where our browser Maps key is refused by its referrer restriction —
   so a2zPlaces() draws this list from our own predictions endpoint instead.

   Everything the `.a2z-pac` block above has to work around disappears here:
   this element is a child of #widget-vue-body, so the --bt-* tokens inherit
   with nothing copied onto it in JS, and there is no host-page dropdown it
   could ever be confused with. It is positioned `fixed` (from JS) only to
   escape .bq-scroll's overflow clipping.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body .a2z-ac {
    position: fixed;
    z-index: 2147483000;
    display: none;
    max-height: 260px;
    overflow-y: auto;
    box-sizing: border-box;
    background: var(--bt-card, #fff);
    border: 1px solid var(--bt-border, #e5e7eb);
    border-radius: var(--bt-field-radius, 0);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .18);
    font-family: var(--bt-font-body, inherit);
}
#widget-vue-body .a2z-ac.is-open { display: block; }

#widget-vue-body .a2z-ac-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 9px 13px;
    cursor: pointer;
    border-top: 1px solid var(--bt-border, #e5e7eb);
}
#widget-vue-body .a2z-ac-item:first-child { border-top: none; }
#widget-vue-body .a2z-ac-item.is-active { background: var(--bt-soft, #f3f4f6); }

#widget-vue-body .a2z-ac-main {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--bt-text, #111827);
    line-height: 1.3;
}
#widget-vue-body .a2z-ac-sub {
    font-size: 11.5px;
    color: var(--bt-muted, #6b7280);
    line-height: 1.3;
}

/* Google's terms require the attribution wherever Places data is shown, and
   the JS widget used to draw it into `.pac-container` itself. Nothing draws it
   for us any more, so the list carries it.

   Sticky, not just the last row: the list caps at max-height and scrolls, so a
   plain trailing strip is pushed out of the scrollport by the fifth prediction
   — which is the normal case, not an edge one. Sticking it to the bottom edge
   keeps it on screen whatever is scrolled behind it, and the opaque background
   stops the rows showing through. */
#widget-vue-body .a2z-ac::after {
    content: '';
    position: sticky;
    bottom: 0;
    display: block;
    height: 22px;
    border-top: 1px solid var(--bt-border, #e5e7eb);
    background-color: var(--bt-card, #fff);
    background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3.png);
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: auto 12px;
}
#widget-vue-body[data-scheme="dark"] .a2z-ac::after {
    background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-non-white3.png);
}

/* Resolving a pick is a round trip to our server; the field says so. */
#widget-vue-body input.is-loading {
    opacity: .65;
    cursor: progress;
}

/* ── Route map (script embed) ────────────────────────────────────────────
   Leaflet over CARTO tiles. The embed cannot run Google's map — its key is
   refused on a customer's domain — and CARTO's basemaps need no key at all,
   so there is nothing here to restrict per customer.

   The container keeps whatever size its own step gave it (.bq-map-canvas,
   .bk-map-canvas, .mr-map-canvas); Leaflet fills it.
   ────────────────────────────────────────────────────────────────────────── */
/* Fixed light neutral, NOT --bt-soft. The tiles are pinned to CARTO's light
   style whatever the operator's theme (see A2Z_TILE_URL in embed.blade.php),
   and this colour is what shows through: behind tiles still loading, and in the
   gutter above and below the world at low zoom. On a dark widget the token put
   a near-black band around a light map. #e8e6e1 is CARTO light_all's own land
   tone, so the seam is invisible. */
#widget-vue-body .a2z-route-map-canvas {
    position: relative;
    overflow: hidden;
    background: #e8e6e1;
}

/* Leaflet sets its own z-index scale starting at 400 on panes and 1000 on
   controls. Left alone, a map in the embed sits above the host page's header
   and above our own dropdowns. Contained here so it can only stack inside its
   own box. */
#widget-vue-body .a2z-route-map-canvas.leaflet-container {
    isolation: isolate;
    z-index: 0;
    font-family: var(--bt-font-body, inherit);
    background: #e8e6e1;
    outline: none;
}

/* The credit line sits ON the tiles, so it follows the tiles rather than the
   widget theme — the --bt-* tokens would paint a dark strip onto a light
   basemap. (The +/- zoom control is not rendered at all: `zoomControl: false`
   in ensureRouteMap(). If it is ever brought back it needs the same fixed
   light treatment, not the tokens.) */
#widget-vue-body .a2z-route-map-canvas .leaflet-control-attribution {
    background: rgba(255, 255, 255, .82);
    color: #6b7280;
    font-size: 10px;
}
#widget-vue-body .a2z-route-map-canvas .leaflet-control-attribution a {
    color: #6b7280;
}

/* Pickup / drop-off address labels — the Leaflet equivalent of the InfoWindow
   labels the Google map used to open on its markers. */
#widget-vue-body .a2z-map-label.leaflet-tooltip {
    background: var(--bt-card, #fff);
    color: var(--bt-text, #111827);
    border: 1px solid var(--bt-border, #e5e7eb);
    border-radius: var(--bt-field-radius, 0);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
    font-family: var(--bt-font-body, inherit);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
    padding: 3px 7px;
    /* `width: max-content` is load-bearing. Leaflet's tooltip is absolutely
       positioned at the marker, so its containing block offers almost no width
       — and a plain `white-space: normal` then shrink-wraps to the longest
       WORD, turning "Sanepa, Lalitpur 44600, Nepal" into a one-word-per-line
       column. max-content sizes to the unwrapped text first, and max-width
       brings long addresses back down to a sensible box. */
    width: max-content;
    max-width: 170px;
    white-space: normal;
}
/* The little arrow is a border triangle Leaflet paints per direction; left
   unstyled it stays the stock white and reads as a stray chip beside a dark
   label. Tooltips are bound with direction:'auto', so left and right are the
   two that actually occur — top is kept for anything bound explicitly. */
#widget-vue-body .a2z-map-label.leaflet-tooltip-top::before   { border-top-color: var(--bt-border, #e5e7eb); }
#widget-vue-body .a2z-map-label.leaflet-tooltip-left::before  { border-left-color: var(--bt-border, #e5e7eb); }
#widget-vue-body .a2z-map-label.leaflet-tooltip-right::before { border-right-color: var(--bt-border, #e5e7eb); }

/* ── Map marker labels (Google InfoWindow) ───────────────────────────────
   The pickup/drop-off address labels on the route map. These DO sit inside
   #widget-vue-body (Maps renders them within the map canvas), so unlike the
   floating panels below they inherit the --bt-* tokens directly.

   The box needs theming, not just the text: the label content is set to
   var(--bt-text) by mkMapLabel(), which on a dark theme is near-white — and
   Google's InfoWindow chrome is a hardcoded white card, so the labels came out
   white-on-white and vanished. Painting the chrome with --bt-card restores the
   contrast the token pairing assumes.
   ────────────────────────────────────────────────────────────────────────── */
#widget-vue-body .gm-style-iw,
#widget-vue-body .gm-style-iw-c {
    background-color: var(--bt-card) !important;
    border-radius: var(--bt-field-radius, 0) !important;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .28) !important;
    padding: 2px 6px !important;
}

#widget-vue-body .gm-style-iw-d { background-color: transparent !important; }

/* The little pointer under the bubble is a rotated square Google paints
   separately — left white, it reads as a stray chip below a dark label. */
#widget-vue-body .gm-style-iw-t::after {
    background: var(--bt-card) !important;
}

/* Maps 3.55+ renders the tail as its own element rather than a ::after. */
#widget-vue-body .gm-style-iw-tc::after {
    background: var(--bt-card) !important;
}

/* ── Floating panels appended to <body> ──────────────────────────────────
   flatpickr's calendar and jquery-timepicker's list, like the Places dropdown
   above, are appended outside #widget-vue-body and cannot inherit the tokens.
   applyWidgetTokens() copies what they need onto each element; the .a2z-fp /
   .a2z-tp classes keep these rules off a host page's own pickers in the embed.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Date picker ── */
.flatpickr-calendar.a2z-fp {
    background: var(--bt-card, #fff);
    border-radius: var(--bt-field-radius, 0);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .28);
    font-family: var(--bt-font-body, inherit);
    color: var(--bt-text, #111827);
}
.flatpickr-calendar.a2z-fp::before,
.flatpickr-calendar.a2z-fp::after { display: none; }   /* white arrow tail */

.flatpickr-calendar.a2z-fp .flatpickr-months,
.flatpickr-calendar.a2z-fp .flatpickr-month,
.flatpickr-calendar.a2z-fp .flatpickr-weekdays,
.flatpickr-calendar.a2z-fp span.flatpickr-weekday {
    background: var(--bt-card, #fff);
    color: var(--bt-text, #111827);
    fill: var(--bt-text, #111827);
}
.flatpickr-calendar.a2z-fp span.flatpickr-weekday { color: var(--bt-muted, #6b7280); }

.flatpickr-calendar.a2z-fp .flatpickr-current-month .flatpickr-monthDropdown-months,
.flatpickr-calendar.a2z-fp .numInput,
.flatpickr-calendar.a2z-fp .numInputWrapper span { color: var(--bt-text, #111827); }
.flatpickr-calendar.a2z-fp .flatpickr-monthDropdown-months { background: var(--bt-card, #fff); }
.flatpickr-calendar.a2z-fp .flatpickr-monthDropdown-month { background: var(--bt-card, #fff); color: var(--bt-text); }

.flatpickr-calendar.a2z-fp .flatpickr-prev-month svg,
.flatpickr-calendar.a2z-fp .flatpickr-next-month svg { fill: var(--bt-text, #111827); }
.flatpickr-calendar.a2z-fp .flatpickr-prev-month:hover svg,
.flatpickr-calendar.a2z-fp .flatpickr-next-month:hover svg { fill: var(--brand-primary, #ec6408); }

.flatpickr-calendar.a2z-fp .flatpickr-day {
    color: var(--bt-text, #111827);
    border-radius: var(--bt-field-radius, 0);
    border-color: transparent;
}
.flatpickr-calendar.a2z-fp .flatpickr-day:hover,
.flatpickr-calendar.a2z-fp .flatpickr-day:focus {
    background: var(--bt-soft, #f3f4f6);
    border-color: transparent;
}
.flatpickr-calendar.a2z-fp .flatpickr-day.today {
    border-color: var(--brand-primary, #ec6408);
}
/* Stock flatpickr paints the selection its own blue, which ignored the
   operator's brand colour entirely. */
.flatpickr-calendar.a2z-fp .flatpickr-day.selected,
.flatpickr-calendar.a2z-fp .flatpickr-day.selected:hover,
.flatpickr-calendar.a2z-fp .flatpickr-day.startRange,
.flatpickr-calendar.a2z-fp .flatpickr-day.endRange {
    background: var(--brand-primary, #ec6408);
    border-color: var(--brand-primary, #ec6408);
    color: #fff;
}
.flatpickr-calendar.a2z-fp .flatpickr-day.flatpickr-disabled,
.flatpickr-calendar.a2z-fp .flatpickr-day.prevMonthDay,
.flatpickr-calendar.a2z-fp .flatpickr-day.nextMonthDay {
    color: var(--bt-muted, #9ca3af);
    opacity: .45;
}

/* ── Time picker ── */
.ui-timepicker-wrapper.a2z-tp {
    background: var(--bt-card, #fff);
    border: 1px solid var(--bt-border, #e5e7eb);
    border-radius: var(--bt-field-radius, 0);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .28);
    font-family: var(--bt-font-body, inherit);
    scrollbar-color: var(--bt-muted, #9ca3af) transparent;
    /* Stated here, not left to the plugin's own stylesheet. That sheet was
       absent from the embed's dependency list, and with nothing bounding the
       height all 1440 rows rendered — a ~52,000px list, which then defeated the
       plugin's "does it fit below?" test and got flipped far above the field.
       The sheet is loaded for the embed now too, but a layout this load-bearing
       should not depend on a file arriving. `height: auto` overrides that
       sheet's fixed 150px so both surfaces measure the same. */
    height: auto;
    max-height: 190px;
    overflow-y: auto;
}
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li {
    color: var(--bt-text, #111827);
    padding: 6px 12px;
}
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li:hover,
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li.ui-timepicker-selected,
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li.ui-timepicker-selected:hover,
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
    background: var(--brand-primary, #ec6408);
    color: #fff;
}
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li.ui-timepicker-disabled,
.ui-timepicker-wrapper.a2z-tp .ui-timepicker-list li.ui-timepicker-disabled:hover {
    color: var(--bt-muted, #9ca3af);
    background: transparent;
    opacity: .5;
}
.ui-timepicker-wrapper.a2z-tp::-webkit-scrollbar { width: 8px; }
.ui-timepicker-wrapper.a2z-tp::-webkit-scrollbar-track { background: transparent; }
.ui-timepicker-wrapper.a2z-tp::-webkit-scrollbar-thumb {
    background: var(--bt-muted, #9ca3af);
    border-radius: 4px;
}
