/* The layout's flash-toast stack already owns top:80px, so the page's own
   toasts sit under it instead of on the same coordinates. */
.v3-book-toasts {
    top: 152px;
    z-index: 10002;
}

/* A multi-reason refusal is one newline-joined message; keep the line breaks. */
.v3-book-toasts .v2-toast > span {
    white-space: pre-line;
}

/* Informative refusals: blue outline, read-and-close, never the red rejection panel. */
.v3-book-toasts .v2-toast--info {
    align-items: flex-start;
    background: #fff;
    border: 1px solid var(--blue-color, #1A89C8);
    border-left-width: 5px;
    box-shadow: 0 10px 26px rgba(16, 42, 67, 0.16);
    color: #16324a;
    font-weight: 500;
    line-height: 1.45;
}

.v3-book-toasts .v2-toast--info i {
    color: var(--blue-color, #1A89C8);
    margin-top: 1px;
}

.v3-toast-dismiss {
    align-self: flex-start;
    background: none;
    border: 0;
    color: #6b8199;
    cursor: pointer;
    line-height: 1;
    margin-left: auto;
    padding: 2px 0 2px 12px;
}

.v3-toast-dismiss i {
    font-size: 14px;
}

.v3-toast-dismiss:hover,
.v3-toast-dismiss:focus-visible {
    color: #16324a;
}

.v3-field-notice {
    color: #33536f;
    font-size: 11.5px;
    line-height: 1.35;
    margin: 6px 0 0;
}

body.v3-book-page .v2-booking-shell .v2-map-container {
    z-index: 0;
}

/* The route rows come from one x-for, so the swap button cannot sit between them
   in flow the way it does on the legacy form. With exactly two equal-height rows,
   the halfway mark of the list is the seam between pickup and dropoff. */

.v3-route-rows {
    position: relative;
}

body.v3-book-page .v2-booking-shell .v3-swap-row {
    position: absolute;
    top: 50%;
    right: 0;
    margin: 0;
    transform: translateY(-50%);
}

body.v3-book-page .v2-booking-shell .v2-swap-btn:disabled {
    opacity: 1;
    background: #f8f9fa;
    border-color: #e8eaed;
    border-style: dashed;
    color: #c4c7c9;
    box-shadow: none;
}

body.v3-book-page .v2-booking-shell .v2-direction-add-stop[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* The schedule now lives at the top of the route card, above the points. */

body.v3-book-page .v2-booking-shell .v3-route-card-schedule {
    overflow: visible;
    margin-bottom: 8px;
    padding-bottom: 8px;
    border-radius: 0;
}

/* Desktop has room for date and time on one line at close to the original
   type size; the 767.98px mobile override below stacks them instead. */
.v2-schedule-col-datetime {
    display: flex;
    align-items: baseline;
    gap: 5px;
    min-width: 0;
}

body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-col-value {
    white-space: nowrap;
    overflow: visible;
    text-overflow: clip;
    font-size: 14px;
}

.v2-schedule-col-time {
    font-size: 13px;
    font-weight: 600;
    color: #5f6368;
    line-height: 1.3;
    white-space: nowrap;
}

/* Summary rows — one line per decision, each opening a focused modal. */

.v3-summary-row {
    min-height: 52px;
}

.v3-summary-row .v2-schedule-col:focus-visible {
    outline: 2px solid var(--blue-color, #1A89C8);
    outline-offset: 1px;
}

/* Keyboard focus and the arrow-key highlight inside the address suggestion lists. */

body.v3-book-page .v2-booking-shell :focus-visible,
body.v3-book-page .v2-modal :focus-visible,
body.v3-book-page .v2-hybrid-hero-overlay :focus-visible {
    outline: 2px solid var(--blue-color, #1A89C8);
    outline-offset: 2px;
}

/* The hero address fields are underlines, not boxes: focus brightens the rule
   instead. `!important` is unavoidable here — the generic keyboard focus ring in
   css/v3/app.css (a:focus-visible, input:focus-visible, …) declares both outline
   properties `!important`, so plain specificity cannot unset it. `box-shadow: none`
   clears that same ring's near-white halo. Deliberately scoped to the two hero
   address inputs; every other control on the shell keeps its focus ring. */
body.v3-book-page .v2-hybrid-hero-overlay .v2-hero-input:focus,
body.v3-book-page .v2-hybrid-hero-overlay .v2-hero-input:focus-visible {
    outline: none !important;
    box-shadow: none;
    border-bottom-width: 2px;
    border-bottom-color: rgba(255, 255, 255, 0.95);
}

body.v3-book-page .v2-hybrid-hero-overlay .v2-hero-dropoff-card .v2-hero-input:focus,
body.v3-book-page .v2-hybrid-hero-overlay .v2-hero-dropoff-card .v2-hero-input:focus-visible {
    border-bottom-color: #1f2668;
}

body.v3-book-page .v2-hero-dropdown--dark .v2-hero-dropdown-item.is-active {
    background: rgba(255, 255, 255, 0.16);
}

body.v3-book-page .v2-hero-dropdown--light .v2-hero-dropdown-item.is-active,
body.v3-book-page .v2-address-dropdown-item.is-active {
    background: rgba(26, 137, 200, 0.12);
}

body.v3-book-page .v2-drum-col:focus-visible {
    outline-offset: -2px;
}

.v3-modal-hint {
    margin: 6px 0 10px 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: #5d666e;
}

/* Modal shell: header and footer pinned, only the body scrolls. */

body.v3-book-page .v2-modal {
    display: flex;
    flex-direction: column;
}

body.v3-book-page .v2-modal > .v2-modal-header,
body.v3-book-page .v2-modal > .v2-modal-footer {
    flex: 0 0 auto;
}

body.v3-book-page .v2-modal > .v2-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

body.v3-book-page .v2-modal-body.v2-additional-services,
body.v3-book-page .v2-modal-body.v2-vehicle-selector {
    padding: 2px 16px 10px;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

body.v3-book-page .v2-modal .v2-vs-list {
    max-height: none;
    overflow: visible;
    padding: 0;
}

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

.v3-pallet-actions .v2-pallet-add-btn {
    flex: 1 1 0;
}

.v3-pallet-cap-note {
    min-height: 18px;
    margin: 6px 0 0;
    font-size: 12px;
    line-height: 18px;
    color: #5f6b7a;
}

.v3-standard-pallet-link {
    display: block;
    width: 100%;
    margin-top: 6px;
    padding: 0;
    border: 0;
    background: none;
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    color: var(--blue-color, #1A89C8);
}

.v3-standard-pallet-link:hover {
    text-decoration: underline;
}

.v3-edit-banner {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start;
    gap: 10px;
    margin: 0 0 10px 0;
    padding: 10px 12px;
    border: 1px solid #f0c67a;
    border-left: 4px solid #e8991f;
    border-radius: 6px;
    background: #fff8ea;
}

.v3-edit-banner-icon {
    margin-top: 2px;
    font-size: 14px;
    color: #b9761a;
}

.v3-edit-banner-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.v3-edit-banner-title {
    font-size: 13px;
    font-weight: 700;
    color: #7a4d05;
}

.v3-edit-banner-text {
    font-size: 11.5px;
    line-height: 1.45;
    color: #8a6a35;
}

.v3-edit-banner-exit {
    align-self: center;
    flex-shrink: 0;
    padding: 4px 9px;
    border: 1px solid #d9ab5e;
    border-radius: 4px;
    background: #fff;
    font-size: 11px;
    font-weight: 600;
    color: #8a5c10;
}

.v3-edit-banner-exit:hover {
    background: #fdf1dc;
}

.v3-edit-delta {
    margin-top: 10px;
    padding: 9px 11px;
    border-radius: 6px;
    border: 1px solid transparent;
}

.v3-edit-delta--more {
    border-color: #f3cf9a;
    background: #fff6e8;
}

.v3-edit-delta--less {
    border-color: #a9dcb8;
    background: #f0fbf3;
}

.v3-edit-delta--same {
    border-color: #d9dee4;
    background: #f6f8fa;
}

.v3-edit-delta-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    font-size: 12.5px;
    font-weight: 700;
    color: #33393f;
}

.v3-edit-delta-amount {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.v3-edit-delta--more .v3-edit-delta-amount {
    color: #b96e0b;
}

.v3-edit-delta--less .v3-edit-delta-amount {
    color: #1e7a41;
}

.v3-edit-delta-text {
    margin: 3px 0 0 0;
    font-size: 11.5px;
    line-height: 1.5;
    color: #5d666e;
}

.v3-edit-result-note {
    margin: 8px 0 0 0;
    font-size: 11.5px;
    line-height: 1.5;
    text-align: center;
    color: #5d666e;
}

/* Price Breakdown — one consolidated transport line, then an indented add-on group. */

.v3-price-rule {
    margin: 6px 0;
    border: 0;
    border-top: 1px solid #e5e7eb;
    opacity: 1;
}

.v3-price-rule--dashed {
    border-top-style: dashed;
    border-top-color: #d3d8de;
}

.v3-price-row-icon {
    margin-right: 6px;
    color: #9aa0a6;
    font-size: 12px;
}

.v3-price-group-head {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 0 2px 0;
    font-size: 13px;
    font-weight: 700;
    color: var(--blue-color, #1a73e8);
}

.v3-price-row--child {
    padding-left: 20px;
    font-weight: 400;
}

.v2-price-display {
    font-size: 19px;
    font-weight: 700;
    color: var(--blue-color, #1a73e8);
}

/* Total line before a quote exists. */

.v2-price-pending {
    font-size: 13px;
    font-weight: 600;
    color: #6b7280;
}

/* Waiting on the customer's nod, not an error: amber, not the red field glow. */

.v2-adjust-notice.v3-adjust-notice-flagged {
    border-color: #e8991f;
    border-left: 4px solid #e8991f;
    box-shadow: 0 0 0 3px #fdf1dc;
}

/* ═══════════════════════════════════════════════════════════
   /book mobile layer — owns everything below 768px.
   Scoped to body.v3-book-page so it outranks the
   body.v2-home-page block in css/v2/home.css without editing it.
   ═══════════════════════════════════════════════════════════ */

@media (max-width: 767.98px) {

    /* ── Shell: the map leads, the card is scrolled into beneath it ──
       V2's mobile map is 70dvh over a 30dvh panel (css/v2/home.css:4913-4948).
       This page used to add a 68px band on top of 57dvh to pay for the opaque
       header sitting over the map. The phone navbar is translucent now (the
       ≤767.98px block further down ports V2's scrim), so the map shows through
       it and there is nothing to compensate for: 57dvh of map is 57dvh of map,
       and the 68px goes to the form panel instead. */

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-map-container {
        order: 1;
        flex: 0 0 auto;
        height: 57dvh;
        min-height: 260px;
        max-height: 70dvh;
    }

    /* The one scrolling surface on mobile. .booking-form-container inside it
       is forced back to visible below, and the shell row is exactly 100dvh
       (home.css:4900), so neither the page nor the panel's child can scroll. */
    body.v3-book-page.v2-home-page .v2-booking-shell .form-content {
        order: 2;
        flex: 1 1 auto;
        height: auto;
        min-height: 0;
        max-height: none;
        margin-top: 0 !important;
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior: contain;
        scroll-padding-bottom: 76px;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .booking-form-container {
        height: auto !important;
        max-height: none !important;
        padding: 0 12px 10px 12px !important;
        overflow: visible !important;
    }

    body.v3-book-page.v2-home-page.v2-mobile-booking-summary-step .v2-booking-shell .v2-map-container,
    body.v3-book-page.v2-home-page.v2-mobile-booking-success-step .v2-booking-shell .v2-map-container {
        flex: 0 0 auto;
        height: clamp(120px, 24dvh, 200px);
        min-height: 0;
        max-height: none;
    }

    body.v3-book-page.v2-home-page.v2-mobile-booking-summary-step .v2-booking-shell .form-content,
    body.v3-book-page.v2-home-page.v2-mobile-booking-success-step .v2-booking-shell .form-content {
        flex: 1 1 auto;
        height: auto;
        max-height: none;
    }

    /* One scroll container per step: .form-content, never a nested pair. */
    body.v3-book-page.v2-home-page.v2-mobile-booking-summary-step .v2-booking-shell .booking-form-container,
    body.v3-book-page.v2-home-page.v2-mobile-booking-success-step .v2-booking-shell .booking-form-container {
        overflow: visible !important;
        padding: 0 12px 16px 12px !important;
    }

    body.v3-book-page.v2-home-page.v2-mobile-booking-summary-step .v2-booking-shell .v2-order-summary,
    body.v3-book-page.v2-home-page.v2-mobile-booking-success-step .v2-booking-shell .v2-order-summary {
        max-height: none;
        overflow: visible;
    }

    /* ── Sticky primary action ── */

    body.v3-book-page .v2-booking-shell .v3-form-cta {
        position: sticky;
        bottom: 0;
        z-index: 20;
        margin: 14px -12px 0 -12px !important;
        padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px)) 12px;
        background: #ffffff;
        border-top: 1px solid #e5e7eb;
        box-shadow: 0 -8px 18px -10px rgba(16, 32, 56, 0.28);
    }

    body.v3-book-page .v2-booking-shell .v3-form-cta .btn {
        min-height: 46px;
        font-size: 15px;
    }

    body.v3-book-page.v2-home-page.v2-mobile-booking-summary-step .v2-booking-shell .v2-order-summary .v2-place-order-btn {
        height: 46px;
    }

    body.v3-book-page.v2-home-page.v2-mobile-booking-summary-step .v2-booking-shell .v2-order-summary .v2-edit-btn {
        width: 46px;
        height: 46px;
        flex: 0 0 46px;
    }

    /* ── Toast floats over the top of the map, under the header. The form
       panel is only a third of the screen here, so anything anchored to it
       buries a row the message is usually about.
       The offset is the authored navbar height (style.css:127) plus a gap:
       the logo overhangs the bar by ~3px, so 12px still leaves ~9px of clear
       map between the two. The toast keeps its own opaque white card, so it
       reads as a separate object from the now-translucent bar above it. ── */

    body.v3-book-page .v2-toast-container {
        top: calc(65px + 12px) !important;
        bottom: auto;
        left: 10px;
        width: calc(100% - 20px);
    }

    body.v3-book-page .v2-toast-container .v2-toast {
        gap: 8px;
        padding: 9px 11px;
        border-radius: 9px;
        font-size: 12.5px;
    }

    body.v3-book-page .v2-toast-container .v2-toast i {
        font-size: 14px;
    }

    body.v3-book-page .v2-toast-container .v3-toast-dismiss {
        position: relative;
        padding: 0 0 0 8px;
    }

    /* The glyph box is only 18.5x15; a centred pseudo-element carries the 44px
       target the way the swap circle does below, so neither the toast's own
       height nor the icon's size changes. */
    body.v3-book-page .v2-toast-container .v3-toast-dismiss::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
    }

    /* ── Input ergonomics: 16px kills iOS focus-zoom, 44px is the HIG target ── */

    body.v3-book-page.v2-home-page .v2-booking-shell .form-content input:not([type="checkbox"]):not([type="radio"]),
    body.v3-book-page.v2-home-page .v2-booking-shell .form-content select,
    body.v3-book-page.v2-home-page .v2-booking-shell .form-content textarea {
        font-size: 16px !important;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .form-content input:not([type="checkbox"]):not([type="radio"]),
    body.v3-book-page.v2-home-page .v2-booking-shell .form-content select {
        height: auto !important;
        min-height: 44px !important;
        padding: 6px 10px !important;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .form-content textarea {
        min-height: 76px !important;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .form-content .form-check-input {
        width: 24px;
        height: 24px;
        margin-right: 2px;
    }

    /* The 24px box stays; its paired <label for> carries the 44px target. */
    body.v3-book-page .v3-addl-head {
        min-height: 44px;
    }

    body.v3-book-page .v3-addl-head .v2-addl-label {
        display: flex;
        align-items: center;
        align-self: stretch;
        min-height: 44px;
        cursor: pointer;
    }

    /* home.css:5126 shrinks the swap circle to 24px; keep the look, grow the tap box. */
    body.v3-book-page .v2-booking-shell .v3-swap-row .v2-swap-btn {
        position: relative;
    }

    body.v3-book-page .v2-booking-shell .v3-swap-row .v2-swap-btn::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-dir-field-label,
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-addl-field-label {
        font-size: 10px;
        top: -7px;
    }

    /* Timeline dots re-centre on the taller 44px fields */
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-direction-timeline {
        min-height: 44px;
        padding-top: 15px;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-direction-timeline.has-line::after {
        top: calc(15px + 14px);
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-add-dest-timeline,
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-add-dest-text {
        height: 44px;
        font-size: 14px;
    }

    /* ── Mode switcher: the full width split in two, plain labels on a
       hairline. The active half carries a blue bar that reads as a filled
       segment of that hairline — V2's treatment (css/v2/app.css:77-119),
       compacted the way V2's own mobile layer does (home.css:5016). ── */

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-tabs-row .v2-shipment-tabs {
        display: flex;
        gap: 0;
        border-bottom: 1px solid #e6e9ee !important;
        padding: 0 !important;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-tabs-row .v2-shipment-tabs .nav-item {
        display: block;
        flex: 1 1 0;
        min-width: 0;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-tabs-row .v2-shipment-tabs .nav-item > button.nav-link {
        display: block !important;
        width: 100%;
        height: auto !important;
        min-height: 0 !important;
        padding: 0 0 3px 0 !important;
        margin-bottom: -1px !important;
        font-size: 12px !important;
        font-weight: 600;
        line-height: 1 !important;
        text-align: center;
        color: #8b939c;
        background: transparent;
        border: 0 !important;
        border-bottom: 2px solid transparent !important;
        border-radius: 0;
        position: relative;
    }

    /* The label itself is only 17px tall at V2's type size. Grow the hit box
       to the 24px WCAG 2.5.8 minimum without growing the row: 3.5px of reach
       above and below stays inside the row's own margins, so it cannot cover
       the mode selector beneath. */
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-tabs-row .v2-shipment-tabs .nav-item > button.nav-link::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: 50%;
        height: 24px;
        transform: translateY(-50%);
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-tabs-row .v2-shipment-tabs .nav-item > button.nav-link.active {
        color: var(--blue-color, #1A89C8);
        background: transparent;
        border-bottom-color: var(--blue-color, #1A89C8) !important;
    }

    /* The label stacks: name on one line, the caption below it. A flex box
       would break "<i> Standard" into two items and stack those too, so this
       stays a block with centred text the way V2's desktop button is.
       Operator ruling: compact toward V2's own mobile proportions (home.css:
       5033-5036, 3px 4px / 10px/1) while keeping the subtitle visible and the
       44px tap target — both hold at V2's own numbers, so this uses them
       outright: 10 + 10 + 6 = 26px label, ~27.6px with the group border. The
       ::after below carries the tap target, unaffected by the label shrinking
       further. */
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-ltl-mode-selector .btn-group .btn-outline-primary {
        display: block;
        position: relative;
        padding: 3px 4px !important;
        font-size: 10px !important;
        line-height: 1 !important;
        text-align: center;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-ltl-mode-selector .btn-group .btn-outline-primary > i {
        font-size: 0.85em;
    }

    /* 9px of reach above and below the 26px label brings the hit box to 44px.
       Below, the selector's 2px margin (home.css:5031) absorbs it. Above, it
       reaches further into the LTL/FTL tab above than before, but that tab's
       own 24px reach at :652 still keeps it hittable. */
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-ltl-mode-selector .btn-group .btn-outline-primary::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: 50%;
        height: 44px;
        transform: translateY(-50%);
    }

    /* home.css:5039 hides these captions on phones; "Custom" is explained
       nowhere else, so V3 keeps them at V2's own caption size (home.css:3423-
       3424, 10px/1). nowrap is the guarantee the operator asked for: at 11px
       this string wrapped to two lines at 320px and took the control to 57px. */
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-ltl-mode-selector .btn-group .btn-outline-primary small {
        display: block;
        font-size: 10px;
        line-height: 1;
        white-space: nowrap;
        /* home.css:3422 dims it to 0.6 of #888 — unreadable at this size. Full
           opacity, and the checked state's own white (home.css:3433) still
           wins because that rule carries !important on colour. */
        opacity: 1;
        color: #6b7280;
    }

    /* ── Row-level icon buttons ── */

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-col-action {
        min-width: 44px;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-stop-remove,
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-pallet-remove,
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-breakdown-toggle-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        padding: 0;
        font-size: 18px;
    }

    /* home.css:3506-3519 keeps the remove button at opacity 0 until the card is
       hovered. A phone has no hover, so the only way to delete a pallet was
       invisible. Desktop keeps V2's reveal-on-hover; here it is simply on. */
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-pallet-remove {
        opacity: 1;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v2-pallet-add-btn {
        min-height: 44px;
        font-size: 13px;
    }

    /* ── Address suggestions: 44px rows, both lines readable ── */

    /* 232px opened past the fold from a field low in the panel. The hero's own
       dropdown keeps to 170px (~3 items, home.css:332) and scrolls inside
       itself; the in-form one now does the same, so both read alike.
       The clip stays on .v2-address-dropdown — it already carries
       overflow-y:auto (css/v2/app.css:1189) — rather than on the inner
       .v2-address-section, which would nest a second scroller. */
    body.v3-book-page .v2-booking-shell .v2-address-dropdown {
        max-height: 170px;
    }

    body.v3-book-page .v2-booking-shell .v2-address-dropdown-item {
        min-height: 44px;
        padding: 7px 10px;
    }

    body.v3-book-page .v2-booking-shell .v2-address-dropdown-item .v2-addr-main {
        font-size: 13px;
    }

    body.v3-book-page .v2-booking-shell .v2-address-dropdown-item .v2-addr-secondary {
        font-size: 11px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    body.v3-book-page .v2-hero-dropdown-item {
        min-height: 44px;
    }

    body.v3-book-page.v2-home-page .v2-booking-shell .v3-standard-pallet-link {
        display: flex;
        align-items: center;
        min-height: 44px;
        margin-top: 2px;
        font-size: 13px;
    }

    /* ── Modals carry the same ergonomics as the panel behind them ── */

    body.v3-book-page .v2-modal {
        max-height: 88dvh;
    }

    body.v3-book-page .v2-modal input:not([type="checkbox"]):not([type="radio"]),
    body.v3-book-page .v2-modal select,
    body.v3-book-page .v2-modal textarea {
        font-size: 16px !important;
    }

    body.v3-book-page .v2-modal input:not([type="checkbox"]):not([type="radio"]),
    body.v3-book-page .v2-modal select {
        height: auto !important;
        min-height: 44px !important;
        padding: 6px 10px !important;
    }

    body.v3-book-page .v2-modal .form-check-input {
        width: 24px;
        height: 24px;
    }

    body.v3-book-page .v2-modal .v2-modal-close {
        width: 44px;
        height: 44px;
    }

    body.v3-book-page .v2-modal-footer {
        padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    }

    body.v3-book-page .v2-booking-shell .v3-summary-row {
        min-height: 56px;
    }

    body.v3-book-page .v2-booking-shell .v3-summary-row .v2-schedule-col-value {
        font-size: 15px;
    }

    /* Reclaim the row's own dead space: it shares the route rows' 4-column
       grid (spacer, icon, content, action) for alignment, but the leading
       spacer column carries nothing on this row, the same way the route rows
       below drop their drag-handle column here. The icon and trailing tracks
       stay at the original 24px so this row's columns line up with the
       address rows' below it. Date over time (not side by side) is what lets
       13px fit: the widest date is "30 September", ~6.4em = 83px at 13px, in
       a 108px column at 320px. */
    body.v3-book-page .v2-booking-shell .v3-route-card-schedule {
        grid-template-columns: 24px 1fr 24px;
        column-gap: 6px;
        padding-left: 15px;
    }

    /* Stacking date over time made the row's own content taller, so the
       inherited 8px/8px band pushed it past the 56px it is meant to sit at.
       Trim the band and let the row keep the desktop 52px floor instead of
       the 56px one — the type, the stacking and the 44px tap target are all
       untouched; only the dead space around them goes.
       Measured: the stacked content box is 50.9px, so 4px/4px landed the row
       at 58.9px. 2.5px/2.5px puts it at 50.9 + 5 = 55.9px, on the 56px
       target; empty, it falls back to the 52px floor. */
    body.v3-book-page .v2-booking-shell .v3-summary-row--schedule {
        min-height: 52px;
        padding-top: 2.5px;
        padding-bottom: 2.5px;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule > div:first-child {
        display: none;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-col-action {
        min-width: 24px;
        width: 24px;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-col-value,
    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-col-time {
        font-size: 13px;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-col-label {
        font-size: 9px;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-col-datetime {
        flex-direction: column;
        align-items: flex-start;
        gap: 0;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-col {
        justify-content: center;
        min-height: 44px;
        padding: 2px 0;
    }

    body.v3-book-page .v2-booking-shell .v3-route-card-schedule .v2-schedule-row-content {
        gap: 2px;
    }

    /* ── Route rows: the drag handle is already invisible on touch (it only
       reveals on hover), so its column is dead space here — reclaim it for
       the address text instead of leaving established place names to clip. ── */

    body.v3-book-page .v2-booking-shell .v3-route-rows .v2-direction-row {
        grid-template-columns: 24px 1fr 24px;
        column-gap: 6px;
        padding-left: 15px;
    }

    body.v3-book-page .v2-booking-shell .v3-route-rows .v2-direction-drag-handle {
        display: none;
    }

    /* Custom LTL's read-only rows sit outside .v3-route-rows, so the rule
       above never reaches them — mirror it here to keep the rail aligned. */
    body.v3-book-page .v2-booking-shell .v3-custom-route-rows .v2-direction-row {
        grid-template-columns: 24px 1fr 24px;
        column-gap: 6px;
        padding-left: 15px;
    }

    body.v3-book-page .v2-booking-shell .v3-custom-route-rows .v2-direction-drag-handle {
        display: none;
    }

    body.v3-book-page .v2-booking-shell .v2-direction-add-stop {
        grid-template-columns: 24px 1fr 24px;
        column-gap: 6px;
        padding-left: 15px;
    }

    /* Add Stop borrows the point rows' 4-column desktop grid (an unclassed
       leading spacer div stands in for the drag handle). Hide it here too,
       by position rather than class since it carries none — this keeps
       working if a class is added later, and stops matching the moment
       anything else becomes the first child. */
    body.v3-book-page .v2-booking-shell .v2-direction-add-stop > div:first-child {
        display: none;
    }

}

/* Reduced motion: still animate the busy spinners, drop everything decorative. */
@media (prefers-reduced-motion: reduce) {
    body.v3-book-page * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    body.v3-book-page .spinner-border {
        animation-duration: 0.75s !important;
        animation-iteration-count: infinite !important;
    }
}

/* Tablet portrait: the map column filled only 512px of a 959px column. */
@media (min-width: 768px) and (max-width: 991.98px) {
    body.v3-book-page .v2-booking-shell .v2-map-container {
        height: calc(100vh - 65px);
        min-height: 0;
        align-self: stretch;
    }
}

/* Header palette. The navbar partial only hands the home treatment to a fixed
   list of routes, which /book is not on, so it inherited the opaque white bar
   from style.css. These mirror home.css's home-navbar colours (2823-2985),
   except the desktop fill and shadow, which home.css:5521-5524 repaints blue
   later in the same file — that later block is what V2 actually renders. */

@media (min-width: 992px) {
    body.v3-book-page #navbar {
        background: linear-gradient(125deg, #0f3d78 0%, #1158aa 58%, #1b6cd2 100%) !important;
        backdrop-filter: blur(12px);
        -webkit-backdrop-filter: blur(12px);
        border-bottom: 1px solid rgba(255, 255, 255, 0.10) !important;
        box-shadow: 0 8px 24px rgba(16, 61, 120, 0.22) !important;
        transition: background 0.3s ease !important;
    }

    body.v3-book-page #navbar.scrolled {
        background: linear-gradient(125deg, #0f3d78 0%, #1158aa 58%, #1b6cd2 100%) !important;
        border-bottom: 1px solid rgba(255, 255, 255, 0.10);
        box-shadow: 0 8px 24px rgba(16, 61, 120, 0.22);
    }

    body.v3-book-page #navbar .Logo {
        filter: brightness(1.05) drop-shadow(0 1px 6px rgba(0, 0, 0, 0.4));
    }

    body.v3-book-page #navbar .navbar-nav .nav-link {
        color: rgba(255, 255, 255, 0.88) !important;
    }

    body.v3-book-page #navbar .navbar-nav .nav-link:hover {
        color: #f7e50f !important;
    }

    body.v3-book-page #navbar .navbar-nav .nav-link.active {
        color: #ffffff !important;
    }

    body.v3-book-page #navbar .v2-guest-auth-link {
        color: rgba(255, 255, 255, 0.85);
    }

    body.v3-book-page #navbar .v2-guest-auth-link:hover {
        color: #f7e50f;
    }

    body.v3-book-page #navbar .v2-guest-auth-divider {
        color: rgba(255, 255, 255, 0.22);
    }

    body.v3-book-page #navbar .v2-guest-auth a:last-of-type {
        background: var(--blue-color, #1A89C8);
        color: #ffffff !important;
        box-shadow: 0 3px 10px rgba(26, 137, 200, 0.40);
    }

    body.v3-book-page #navbar .v2-guest-auth a:last-of-type:hover {
        background: #1572a8;
        color: #ffffff !important;
    }

    body.v3-book-page #navbar .navbar-toggler {
        border-color: rgba(255, 255, 255, 0.35);
    }

    body.v3-book-page #navbar .navbar-toggler-icon {
        filter: invert(1);
    }

    body.v3-book-page #navbar .user-btn,
    body.v3-book-page #navbar .v2-notif-bell-btn {
        color: rgba(255, 255, 255, 0.88) !important;
    }

    body.v3-book-page #navbar .user-btn:hover,
    body.v3-book-page #navbar .user-btn:focus-visible,
    body.v3-book-page #navbar .v2-notif-bell-btn:hover,
    body.v3-book-page #navbar .v2-notif-bell-btn:focus-visible {
        color: #f7e50f !important;
    }
}

@media (max-width: 991.98px) {
    body.v3-book-page #navbar,
    body.v3-book-page #navbar.scrolled {
        background: linear-gradient(135deg, #686d84 0%, #5f647c 52%, #575d75 100%) !important;
        border-bottom: none !important;
        box-shadow: none !important;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    body.v3-book-page #navbar .navbar-toggler {
        border-color: rgba(255, 255, 255, 0.45);
    }

    body.v3-book-page #navbar .navbar-toggler .navbar-toggler-icon {
        filter: invert(1);
    }

    body.v3-book-page #navbar .navbar-collapse,
    body.v3-book-page #navbar .navbar-collapse.show,
    body.v3-book-page #navbar .navbar-collapse.collapsing {
        margin-top: 10px;
        padding: 12px;
        border-radius: 14px;
        background: rgba(81, 86, 106, 0.98);
    }

    body.v3-book-page #navbar .navbar-collapse .navbar-nav .nav-link {
        color: rgba(255, 255, 255, 0.93) !important;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.28);
    }

    body.v3-book-page #navbar .navbar-collapse .navbar-nav .nav-link:hover,
    body.v3-book-page #navbar .navbar-collapse .navbar-nav .nav-link.active {
        color: #ffffff !important;
    }

    body.v3-book-page #navbar .v2-notif-bell-btn,
    body.v3-book-page #navbar .v2-notif-bell-icon,
    body.v3-book-page #navbar .v2-mobile-user-icon,
    body.v3-book-page #navbar .v2-mobile-user-icon i,
    body.v3-book-page #navbar .user-btn,
    body.v3-book-page #navbar .user-btn i {
        color: #ffffff !important;
    }
}

/* Phone header. V2's own phone navbar is translucent — a 160deg scrim with a
   3px blur (home.css:4543-4556) — and /book never got it only because
   navbar.blade.php:2-10 withholds .v2-navbar-home from route book.page, so the
   tablet-opaque gradient in the block above leaked down to phone widths.
   This must stay AFTER that ≤991.98px block: same specificity and same
   importance, so source order is what decides.

   Transparency on its own would be unreadable over pale map tiles, so V2's
   contrast devices come with it: the scrim itself, a logo drop-shadow
   (home.css:2833), the yellow-stroke hamburger with its own shadow
   (home.css:4589-4601), a shadow under the bar icons (home.css:4490), and the
   near-solid open-menu plate — that last one is already in the block above. */

@media (max-width: 767.98px) {
    body.v3-book-page #navbar,
    body.v3-book-page #navbar.scrolled {
        background: linear-gradient(
            160deg,
            rgba(255, 255, 255, 0.12) 0%,
            rgba(82, 81, 81, 0.18) 90%,
            rgba(0, 0, 0, 0.25) 100%
        ) !important;
        border-bottom: none !important;
        box-shadow: none !important;
        backdrop-filter: blur(3px);
        -webkit-backdrop-filter: blur(3px);
    }

    body.v3-book-page #navbar .Logo {
        filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.55));
    }

    /* V2's outlined box reads as a floating rectangle once the bar behind it is
       see-through, so the outline goes — but the icon cannot carry itself here:
       the yellow is LIGHTER than the scrim over pale map tiles (yellow
       luminance 0.7585 vs a local 0.38-0.48), which caps contrast at ~1.9:1 and
       cannot reach the 3:1 non-text minimum by any change to the stroke — no
       colour is bright enough. So the icon keeps a plate — but a neutral,
       softer one than the solid navy chip it used to be: a plain 55% black
       scrim reads as shading rather than as a filled button, and still clears
       the bar. Composite luminance is 0.1707 over pure white (the worst case,
       3.66:1 against the yellow) and 0.1490 over a pale Google land tile
       #f2efe9 (4.06:1); the navbar's own scrim sits between the two and can
       only darken it further. Rounded, not boxed, so it reads as a map control
       rather than a stray rectangle. */
    body.v3-book-page #navbar .navbar-toggler {
        background: rgba(0, 0, 0, 0.55);
        border: none;
        padding: 6px 9px;
        border-radius: 10px;
    }

    /* Overwrites the invert(1) in the ≤991.98px block from the same selector —
       that filter assumes a white icon, and this one is yellow. Both
       declarations are set here, so the pair can never come apart. */
    body.v3-book-page #navbar .navbar-toggler .navbar-toggler-icon {
        background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23f7e50f' stroke-linecap='round' stroke-miterlimit='10' stroke-width='3' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") !important;
        width: 1.4em;
        height: 1.4em;
        filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.8));
        transition: transform 0.35s ease-in-out;
        transform: rotate(0deg);
    }

    body.v3-book-page #navbar .navbar-toggler[aria-expanded="true"] .navbar-toggler-icon {
        background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23f7e50f' stroke-linecap='round' stroke-miterlimit='10' stroke-width='3' d='M7 7l16 16M23 7L7 23'/%3e%3c/svg%3e") !important;
        transform: rotate(90deg);
    }

    /* ── Open menu: V2's phone panel (home.css:4559-4657, 4786-4800) ──
       V2 draws no card. The panel is fully transparent and the readability
       comes from the blurred bar behind it plus per-item text shadows, so the
       grey inset card in the ≤991.98px block above is unwound here rather
       than re-tinted. Same specificity as that block, so source order is what
       decides — these rules must stay below it.

       The two padding/margin declarations are !important for the same reason
       V2's are (home.css:4616-4617): style.css:132
       `#navbar.navbar-expand-lg .navbar-collapse.show { padding-bottom:1rem }`
       is (1,3,0) and style.css:5332 `#navbar .navbar-collapse.show
       { margin-top:1rem }` is (1,2,0) — the first outranks the (1,2,1)
       selector used here on class count, so weight alone would lose. Padding
       must also be stable across states: Bootstrap measures scrollHeight on
       this element to compute the collapse animation target. */
    body.v3-book-page #navbar .container-fluid {
        flex-wrap: wrap;
        align-items: center;
    }

    body.v3-book-page #navbar .navbar-collapse,
    body.v3-book-page #navbar .navbar-collapse.show,
    body.v3-book-page #navbar .navbar-collapse.collapsing {
        background: transparent !important;
        border: none;
        border-radius: 0;
        box-shadow: none;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        padding: 0 !important;
        margin: 0 !important;
        flex-basis: 100%;
        width: 100%;
        overflow: hidden;
        transition: height 0.32s ease-in-out !important;
    }

    body.v3-book-page #navbar .navbar-collapse .navbar-nav {
        text-align: right;
        align-items: flex-end;
        padding-top: 6px;
        padding-right: 10px;
        margin: 0;
    }

    body.v3-book-page #navbar .navbar-collapse .navbar-nav .nav-link {
        padding: 5px 0;
        font-size: 18px;
        font-weight: 700;
        color: #ffffff !important;
        text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9), 0 3px 10px rgba(0, 0, 0, 0.7);
        white-space: nowrap;
    }

    body.v3-book-page #navbar .navbar-collapse .navbar-nav .nav-link:hover,
    body.v3-book-page #navbar .navbar-collapse .navbar-nav .nav-link:focus-visible {
        color: #ffe44d !important;
        text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9), 0 3px 10px rgba(0, 0, 0, 0.6);
    }

    body.v3-book-page #navbar .navbar-collapse .button-group {
        justify-content: flex-end;
        margin: 0;
        padding: 2px 10px 10px;
        border-top: none;
        gap: 4px;
    }

    /* Guest auth row — app.css:895 leaves these at var(--black-color), which
       over a transparent panel reads as disabled. */
    body.v3-book-page #navbar .navbar-collapse .v2-guest-auth-link {
        color: #ffffff !important;
        font-weight: 700;
        text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9), 0 3px 10px rgba(0, 0, 0, 0.7);
        padding: 3px 6px;
    }

    body.v3-book-page #navbar .navbar-collapse .v2-guest-auth-link:hover,
    body.v3-book-page #navbar .navbar-collapse .v2-guest-auth-link:focus-visible {
        color: #ffe44d !important;
        text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9), 0 3px 10px rgba(0, 0, 0, 0.6);
    }

    body.v3-book-page #navbar .navbar-collapse .v2-guest-auth-divider {
        color: rgba(255, 255, 255, 0.45);
        text-shadow: none;
        padding: 0 2px;
    }
}

/* ── Primary action: V2's booking-card CTA yellow (home.css:5561-5568) ── */

body.v3-book-page .v3-next-btn {
    background: linear-gradient(120deg, #f4c531, #f6d45f);
    color: #0f2f57;
    border: none;
    box-shadow: 0 12px 24px rgba(244, 197, 49, 0.3);
}

body.v3-book-page .v3-next-btn:hover:not(:disabled),
body.v3-book-page .v3-next-btn:focus-visible {
    background: linear-gradient(120deg, #f6d45f, #f4c531);
    color: #0f2f57;
}

body.v3-book-page .v3-next-btn:disabled {
    opacity: 0.65;
}

body.v3-book-page .v3-draft-line {
    margin: 8px 0 0;
    font-size: 12px;
    line-height: 1.4;
    color: #8a9199;
    text-align: center;
}

body.v3-book-page .v3-draft-clear {
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

body.v3-book-page .v3-draft-clear:hover {
    color: #b42318;
}

/* ── The sticky CTA belongs to the form step, not to the hero ──
   .v3-form-cta is z-index:20 and .v2-hybrid-hero-overlay is z-index:8
   (css/v2/home.css:32-43) in the same stacking context, so the sticky Next
   paints over the landing hero — on a 360x640 phone it lands right under the
   hero's own Book Now and is clipped by the bottom edge. While the hero is up
   the CTA is not merely mis-layered, it does not apply, so it is suppressed
   here rather than by raising the hero (home.css is shared with V2 home and
   the admin panel). visibility, not display, so nothing under the hero
   reflows; visibility:hidden is also not hit-testable. The class is static in
   the markup and driven by Alpine's heroVisible thereafter. */

body.v3-book-page .v2-booking-shell.v3-hero-up .v3-form-cta {
    visibility: hidden;
}

/* ── Custom LTL route timeline: the same rows as the editable route, but the
   address is read-only text, so it wears a flat tinted field instead of an
   input the customer would try to type into. ── */

body.v3-book-page .v2-booking-shell .v3-custom-route-address {
    display: block;
    height: 42px;
    line-height: 27px;
    margin: 0;
    padding: 6px 12px;
    border: 1.5px solid #e0e0e0;
    border-radius: 8px;
    background: #f8f9fb;
    color: #3c4043;
    font-size: 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.v3-book-page .v2-booking-shell .v3-custom-route-rows .v2-direction-drag-handle {
    visibility: hidden;
}

/* On a phone the derived list can run to four rows and would push the panel
   heads under the sticky CTA. Read-only rows need no tap target, so they take
   the tighter height rather than the 42px of the editable ones. */

@media (max-width: 767.98px) {
    body.v3-book-page .v2-booking-shell .v3-custom-route-address {
        height: 34px;
        line-height: 19px;
        padding: 6px 10px;
        font-size: 13px;
    }
}

/* ── Short phones: the map yields, the drop-off row comes above the CTA ──
   On a 568px-tall viewport the LTL drop-off address row lands at y518.8-572.8
   while the opaque sticky .v3-form-cta occupies y505-568, so the field is not
   just below the fold — it is fully occluded and a tap on it is intercepted.
   LTL carries ~57px of Standard/Custom sub-mode selector that FTL does not,
   which is why only LTL falls off the screen.

   57dvh of map is 323.8px here; 43dvh is 244.2px, so the whole column rises
   79.6px and the row settles at y439-493, clear of the CTA with ~12px to
   spare. The 260px floor above would clamp that back to 260px, so it moves
   too — 200px is the smallest map still usable for pin-dropping, and it only
   binds below a 466px viewport.

   Height-gated, not width-gated: 568 is inside max-height:600px while 640 and
   844 are not, so every ordinary phone keeps the 57dvh map untouched.

   This must stay AFTER the ≤767.98px block at :419 — same specificity, same
   (absent) importance, so source order is what decides. The summary/success
   overrides at :450 carry an extra class and still outrank this regardless of
   order, so those steps keep their 24dvh map. */

@media (max-width: 767.98px) and (max-height: 640px) {
    body.v3-book-page.v2-home-page .v2-booking-shell .v2-map-container {
        height: 43dvh;
        min-height: 200px;
    }
}
