/*
 * Dispatch widget — compact "estimated delivery" notice.
 * Shown on the cart page, side cart drawer, first-party checkout, product page
 * and post-payment page. The arrival date leads; the operational reason
 * follows. Calm, no card fill — all colours use --ds-* tokens.
 */

.ds-dispatch {
    margin: 12px 0;
    padding-top: 10px;
    border-top: 1px solid var(--ds-border-color-light);
    line-height: 1.4;
}

.ds-dispatch p {
    margin: 0;
}

.ds-dispatch-delivery {
    font-size: 14px;
    color: var(--ds-dark-text-color);
}

.ds-dispatch-delivery strong {
    font-weight: 600;
}

.ds-dispatch-line {
    font-size: 13px;
    color: var(--ds-dark-text-color);
    margin-top: 3px;
}

.ds-dispatch-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--ds-interactive-color);
    vertical-align: middle;
}

.ds-dispatch-time {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ds-dispatch-sub {
    font-size: 12px;
    color: var(--ds-light-text-color-light);
    margin-top: 3px;
}

/* Cart and cart drawer: match the checkout's compact reassurance treatment. */
.ds-cart-dispatch {
    padding: 14px 0 16px;
    border-bottom: 1px solid var(--ds-border-color-light);
}

.ds-cart-dispatch:empty {
    display: none;
}

.ds-cart-dispatch > .ds-dispatch {
    display: grid;
    gap: 4px;
    margin: 0;
    padding: 1px 0 1px 14px;
    border-top: 0;
    border-left: 2px solid var(--ds-primary-color);
}

.ds-cart-dispatch .ds-dispatch-line,
.ds-cart-dispatch .ds-dispatch-sub {
    margin-top: 0;
}

#cartModal .ds-cart-dispatch {
    padding: 12px 0 14px;
    border-bottom: 0;
}

#cartModal .ds-cart-dispatch > .ds-dispatch {
    gap: 2px;
}

#cartModal .modal-cart-bottom > .pb-4 {
    padding-bottom: 0 !important;
}

/* Shared reassurance panel on product and post-payment pages. Keep the outer
   geometry identical while the product slot is loading so option changes do
   not move the purchase controls below it. */
.ds-dispatch-panel {
    box-sizing: border-box;
    min-height: 97px;
    margin: 0;
    padding: 16px 0 18px;
    border-bottom: 1px solid var(--ds-border-color-light);
    background: var(--ds-white-color);
}

.ds-dispatch-panel:empty:not(.is-loading) {
    display: none;
}

.ds-dispatch-panel > .ds-dispatch {
    display: grid;
    gap: 4px;
    margin: 0;
    padding: 1px 0 1px 14px;
    border-top: 0;
    border-left: 2px solid var(--ds-primary-color);
}

.ds-dispatch-panel .ds-dispatch-delivery {
    color: var(--ds-dark-text-color);
    font-size: 14px;
    line-height: 1.45;
}

.ds-dispatch-panel .ds-dispatch-line {
    display: flex;
    align-items: center;
    margin-top: 0;
    color: var(--ds-secondary-text-color);
    font-size: 13px;
    line-height: 1.4;
}

.ds-dispatch-panel .ds-dispatch-dot {
    flex: 0 0 auto;
    margin-right: 8px;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--ds-interactive-color) 12%, transparent);
}

.ds-dispatch-panel .ds-dispatch-sub {
    margin-top: 0;
    color: var(--ds-light-text-color);
    font-size: 12px;
    line-height: 1.45;
}

/* Product price block: arrival estimate with an airplane icon. */
.ds-dispatch-compact .ds-dispatch {
    margin: 0;
    padding-top: 0;
    border-top: 0;
}

.ds-dispatch-compact .ds-dispatch-sub,
.ds-dispatch-compact .ds-dispatch-line {
    display: none;
}

.ds-dispatch-compact .ds-dispatch-delivery {
    font-size: 14px;
}

.ds-dispatch-compact .ds-dispatch-delivery::before {
    content: "";
    display: inline-block;
    width: 16px;
    height: 16px;
    margin-right: 4px;
    vertical-align: -3px;
    background-color: currentColor;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M21 16v-2l-8-5V3.5a1.5 1.5 0 0 0-3 0V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5L21 16Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* In-stock status ahead of the arrival date. Only the product price block shows it; every
   other placement already carries the status in its own dispatch line. */
.ds-dispatch-stock {
    display: none;
}

/* The product price row shows it (#ds-price-stock), styled like the status line of the dispatch
   panel above the buy button: grey text, green dot with a soft halo. */
.ds-price-stock .ds-dispatch-stock {
    display: inline-flex;
    align-items: center;
    color: var(--ds-secondary-text-color);
    font-size: 14px;
    white-space: nowrap;
    animation: ds-dispatch-in .3s ease;
}

.ds-price-stock .ds-dispatch-dot {
    flex: 0 0 auto;
    margin-right: 8px;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--ds-interactive-color) 12%, transparent);
}

/* "Choose an option to check availability" prompt (no resolvable variant) */
.ds-dispatch-choose {
    font-size: 13px;
    color: var(--ds-blue-color);
}

/* Reserve the arrival line's 14px × 1.4 height while its live estimate loads. */
.ds-dispatch-slot.ds-dispatch-compact {
    min-height: 19.6px;
}

/* Three classes must out-rank the generic loading rule below. */
.ds-dispatch-slot.ds-dispatch-compact.is-loading {
    min-height: 19.6px;
    margin: 0;
    border-top: 0;
}

/* --- product page: placeholder slot, filled via AJAX on page load ------ */
.ds-dispatch-slot.is-loading {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    min-height: 48px;
    margin: 12px 0;
    border-top: 1px solid var(--ds-border-color-light);
}

/* The shimmer is a gradient layer four times the slot's width that slides by transform.
   It used to be a background-position animation, which cannot run on the compositor and
   repainted the slot on every frame. */
.ds-dispatch-slot.is-loading::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 400%;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(90deg, transparent 25%, var(--ds-border-color-light) 50%, transparent 75%);
    animation: ds-dispatch-shimmer 1.4s ease infinite;
}

/* The full product slot uses the same 97px panel in both states. The old
   generic loading rule changed its margins, padding and borders, which caused
   the option controls and buy buttons to jump on every AJAX refresh. */
.ds-dispatch-slot.ds-dispatch-panel.is-loading {
    min-height: 97px;
    margin: 0;
    padding: 16px 0 18px;
    border-top: 0;
    border-bottom: 1px solid var(--ds-border-color-light);
}

/* A changed estimate fades in instead of snapping (the slot keeps its height, so nothing moves). */
.ds-dispatch-slot.ds-dispatch-swapped > .ds-dispatch {
    animation: ds-dispatch-in .3s ease;
}

@keyframes ds-dispatch-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes ds-dispatch-shimmer {
    0% { transform: translateX(-75%); }
    100% { transform: translateX(75%); }
}

@media (prefers-reduced-motion: reduce) {
    .ds-dispatch-slot.is-loading,
    .ds-dispatch-slot.is-loading::after,
    .ds-dispatch-slot.ds-dispatch-swapped > .ds-dispatch {
        animation: none;
    }
}
