/* ============================================================================
   lv-popup — storefront promotional popups (Admin → Popups)
   ----------------------------------------------------------------------------
   One dialog, nine compositions. The composition is chosen server-side by
   App\Support\PopupPresentation from the fields a campaign actually fills in
   and lands on the dialog as a `lv-pop--<composition>` modifier; layout
   modifiers (`lv-pop--split`, `--narrow`, `--title-only`, `--reading`, `--wide`,
   `--long`) refine it from the amount of copy rather than the campaign type. Everything
   below is scoped to .lv-pop* so no storefront component is touched.

   Visual language: espresso brand ink on warm paper, Urbanist display over
   DM Sans copy, hairline rules instead of boxes, and depth from a single deep
   soft shadow rather than stacked borders.

   1.  Tokens
   2.  Overlay + scroll lock
   3.  Dialog shell
   4.  Close control
   5.  Media (image, video)
   6.  Copy: badge, title, body
   7.  Coupon
   8.  Package offer
   9.  Featured products
   10. Call to action + dismissal
   11. Composition rules
   12. Responsive: split, tablet, phone sheet
   13. RTL
   14. Reduced motion + forced colors
   ========================================================================== */

/* ===== 1. Tokens =========================================================== */
.lv-pop-overlay {
    /* Ink is derived from the brand so Admin → Theme Settings keeps working,
       but always resolves to a readable warm dark. */
    --lvpop-ink: color-mix(in srgb, var(--color-primary, #3d210c) 82%, #120c08);
    /* A scrim still reads as a tint until it is dark enough to sit behind a
       white card, so the brand ink is pulled most of the way to black before
       the alpha is applied. */
    --lvpop-scrim: color-mix(in srgb, var(--lvpop-ink) 45%, #080503);
    --lvpop-paper: var(--color-card-bg, #fff);
    --lvpop-cream: color-mix(in srgb, var(--color-primary-lighter, #f1e7de) 70%, #fff);
    --lvpop-text: var(--color-light-primary-text, #212529);
    --lvpop-muted: var(--color-light-secondary-text, #495057);
    --lvpop-hairline: color-mix(in srgb, var(--color-primary, #3d210c) 14%, transparent);
    --lvpop-accent: var(--color-primary, #3d210c);
    --lvpop-accent-strong: var(--color-primary-dark, #5f381b);
    --lvpop-danger: var(--color-error, #cb0233);

    --lvpop-radius: 18px;
    --lvpop-radius-sm: 10px;
    --lvpop-pad: clamp(1.25rem, 0.85rem + 1.6vw, 2.25rem);
    --lvpop-gap: clamp(0.875rem, 0.7rem + 0.7vw, 1.125rem);

    --lvpop-shadow:
        0 40px 80px -32px rgb(18 12 8 / 0.5),
        0 12px 28px -18px rgb(18 12 8 / 0.35);
    --lvpop-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --lvpop-dur: 260ms;

    /* Widest the dialog ever gets, per composition. */
    --lvpop-w: 620px;
}

/* Arabic falls through to script-capable faces instead of the Latin-only
   display family; no extra webfont request is made for it. */
.lv-pop {
    font-family: "DM Sans", "Noto Naskh Arabic", "Segoe UI", Tahoma, "Geeza Pro", Arial, sans-serif;
    color: var(--lvpop-text);
    -webkit-font-smoothing: antialiased;
}

.lv-pop-title,
.lv-pop-badge__value,
.lv-pop-coupon__code,
.lv-pop-package__discount {
    font-family: "Urbanist", "Noto Kufi Arabic", "Segoe UI", Tahoma, "Geeza Pro", Arial, sans-serif;
}

.lv-pop svg {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ===== 2. Overlay + scroll lock ============================================ */
.lv-pop-overlay {
    position: fixed;
    inset: 0;
    /* Above storefront chrome, below toasts so a cart confirmation is never
       hidden behind a campaign. */
    z-index: 1080;
    display: grid;
    place-items: center;
    padding: clamp(0.75rem, 3vh, 2.5rem);
    background: color-mix(in srgb, var(--lvpop-scrim) 72%, transparent);
    opacity: 0;
    transition: opacity 180ms ease;
}

@supports (backdrop-filter: blur(2px)) {
    .lv-pop-overlay {
        backdrop-filter: blur(2px);
    }
}

.lv-pop-overlay[hidden] {
    display: none;
}

.lv-pop-overlay.is-open {
    opacity: 1;
}

.lv-pop-overlay.is-closing {
    opacity: 0;
}

body.lv-pop-open {
    overflow: hidden;
    /* Compensates for the removed scrollbar so dismissing a campaign does not
       shove the storefront sideways. Set by lv-popup.js. */
    padding-inline-end: var(--lvpop-gutter, 0px);
}

/* ===== 3. Dialog shell ==================================================== */
.lv-pop {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(var(--lvpop-w), 100%);
    max-height: min(86svh, 760px);
    overflow: hidden;
    background: var(--lvpop-paper);
    border-radius: var(--lvpop-radius);
    box-shadow: var(--lvpop-shadow);
    transform: translate3d(0, 14px, 0) scale(0.985);
    transition: transform var(--lvpop-dur) var(--lvpop-ease);
}

@supports not (max-height: 86svh) {
    .lv-pop {
        max-height: min(86vh, 760px);
    }
}

.lv-pop-overlay.is-open .lv-pop {
    transform: none;
}

.lv-pop-overlay.is-closing .lv-pop {
    transform: translate3d(0, 8px, 0) scale(0.99);
}

.lv-pop--narrow {
    --lvpop-w: 500px;
}

/* A headline with nothing under it reads as a strip across the dialog, so it
   gets a tighter frame and more air instead of the standard measure. */
.lv-pop--title-only {
    --lvpop-w: 420px;
}

.lv-pop--title-only .lv-pop-body {
    padding-block: clamp(1.75rem, 3vw, 2.5rem);
}

/* Policy-style copy: the widest column the dialog will take, because the
   measure matters more than the frame once there are paragraphs to read. */
.lv-pop--reading {
    --lvpop-w: 660px;
}

.lv-pop--wide {
    --lvpop-w: 840px;
}

.lv-pop--image,
.lv-pop--video {
    --lvpop-w: 720px;
}

/* The scrolling region. Kept inside the dialog so the frame, the close control
   and the call to action stay put while long copy moves. */
.lv-pop-body {
    display: flex;
    flex-direction: column;
    gap: var(--lvpop-gap);
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--lvpop-pad);
    scrollbar-width: thin;
}

/* Nothing inside a flex column may refuse to shrink, or a long product title
   or an unbroken URL would push the dialog wider than the viewport. */
.lv-pop-body > * {
    min-width: 0;
}

/* ===== 4. Close control =================================================== */
/* A solid paper disc with a hairline and its own shadow: legible over campaign
   photography, over a dark bleed image and over plain white alike. */
.lv-pop-close {
    position: absolute;
    inset-inline-end: clamp(0.625rem, 1.5vw, 1rem);
    inset-block-start: clamp(0.625rem, 1.5vw, 1rem);
    z-index: 3;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--lvpop-hairline);
    border-radius: 50%;
    background: rgb(255 255 255 / 0.94);
    color: var(--lvpop-ink);
    cursor: pointer;
    box-shadow: 0 6px 18px -6px rgb(18 12 8 / 0.4);
    transition: background var(--lvpop-dur) var(--lvpop-ease),
        color var(--lvpop-dur) var(--lvpop-ease),
        transform var(--lvpop-dur) var(--lvpop-ease);
}

.lv-pop-close svg {
    width: 1.0625rem;
    height: 1.0625rem;
    stroke-width: 1.9;
}

/* When the headline is the first thing in the panel it shares the top row with
   the close control, so its line box gives the corner up rather than letting a
   long title run under the disc. Later elements start below the disc already. */
.lv-pop-body > .lv-pop-title:first-child {
    padding-inline-end: 3rem;
}

.lv-pop-close:hover {
    background: var(--lvpop-accent);
    color: #fff;
    border-color: transparent;
    transform: rotate(90deg);
}

.lv-pop-close:active {
    transform: rotate(90deg) scale(0.94);
}

/* ===== 5. Media =========================================================== */
.lv-pop-media {
    position: relative;
    flex: none;
    overflow: hidden;
    background: var(--lvpop-cream);
}

.lv-pop-media img {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 12rem;
    max-height: 22rem;
    object-fit: cover;
    object-position: center;
}

.lv-pop-media--video {
    background: #0d0906;
}

.lv-pop-media--video iframe,
.lv-pop-media--video video {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
    background: #0d0906;
}

/* ===== 6. Copy ============================================================ */
.lv-pop-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    margin: 0;
}

.lv-pop-badge::before {
    content: "";
    flex: none;
    width: 1.75rem;
    height: 1px;
    background: color-mix(in srgb, var(--lvpop-accent) 45%, transparent);
}

.lv-pop-badge__label {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--lvpop-muted);
}

.lv-pop-badge__value {
    font-size: 1.125rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.01em;
    color: var(--lvpop-accent);
}

.lv-pop-title {
    margin: 0;
    font-size: clamp(1.375rem, 1.05rem + 1.25vw, 2rem);
    font-weight: 700;
    line-height: 1.18;
    letter-spacing: -0.011em;
    color: var(--lvpop-text);
    /* Long single-word headlines and product names must wrap, not burst out. */
    overflow-wrap: anywhere;
}

.lv-pop-text {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    font-size: 0.9375rem;
    line-height: 1.66;
    color: var(--lvpop-muted);
    max-width: 52ch;
}

.lv-pop-text p {
    margin: 0;
    overflow-wrap: anywhere;
}

.lv-pop-text p + p {
    margin: 0;
}

.lv-pop--long .lv-pop-text {
    font-size: 0.875rem;
    line-height: 1.7;
}

/* ===== 7. Coupon ========================================================== */
.lv-pop-coupon {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.625rem;
    padding: 0.875rem 1rem;
    border: 1px dashed color-mix(in srgb, var(--lvpop-accent) 40%, transparent);
    border-radius: var(--lvpop-radius-sm);
    background: var(--lvpop-cream);
}

.lv-pop-coupon__ticket {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    margin-inline-end: auto;
}

.lv-pop-coupon__label {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--lvpop-accent) 72%, var(--lvpop-muted));
}

.lv-pop-coupon__code {
    font-size: 1.25rem;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: 0.1em;
    color: var(--lvpop-accent);
    overflow-wrap: anywhere;
}

.lv-pop-coupon__copy {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    padding: 0.5rem 0.875rem;
    border: 1px solid color-mix(in srgb, var(--lvpop-accent) 32%, transparent);
    border-radius: var(--lvpop-radius-sm);
    background: var(--lvpop-paper);
    color: var(--lvpop-accent);
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--lvpop-dur) var(--lvpop-ease),
        color var(--lvpop-dur) var(--lvpop-ease),
        border-color var(--lvpop-dur) var(--lvpop-ease);
}

.lv-pop-coupon__copy svg {
    width: 0.9375rem;
    height: 0.9375rem;
}

.lv-pop-coupon__copy:hover {
    background: var(--lvpop-accent);
    border-color: transparent;
    color: #fff;
}

.lv-pop-coupon__copy.is-copied {
    background: color-mix(in srgb, var(--color-success, #54d62c) 16%, var(--lvpop-paper));
    border-color: color-mix(in srgb, var(--color-success-dark, #229a16) 45%, transparent);
    color: var(--color-success-dark, #229a16);
}

.lv-pop-terms {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 0;
    padding: 0.625rem 0 0;
    border-top: 1px solid var(--lvpop-hairline);
    list-style: none;
    font-size: 0.75rem;
    line-height: 1.5;
    color: color-mix(in srgb, var(--lvpop-muted) 85%, var(--lvpop-paper));
}

.lv-pop-terms li {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    overflow-wrap: anywhere;
}

.lv-pop-terms li::before {
    content: "";
    flex: none;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--lvpop-accent) 55%, transparent);
    transform: translateY(-2px);
}

/* ===== 8. Package offer =================================================== */
.lv-pop-package {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.75rem;
    border: 1px solid var(--lvpop-hairline);
    border-radius: var(--lvpop-radius-sm);
    background: color-mix(in srgb, var(--lvpop-cream) 55%, var(--lvpop-paper));
}

.lv-pop-package__media {
    flex: none;
    width: 3.5rem;
    height: 3.5rem;
    overflow: hidden;
    border-radius: 8px;
    background: var(--lvpop-cream);
}

.lv-pop-package__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.lv-pop-package__text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

.lv-pop-package__label {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--lvpop-muted);
}

.lv-pop-package__name {
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1.35;
    color: var(--lvpop-text);
    overflow-wrap: anywhere;
}

.lv-pop-package__discount {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--lvpop-accent);
}

/* ===== 9. Featured products ============================================== */
/* A rail on narrow screens, a grid where there is room. Cards are anchors and
   contain inline elements only, so the block stays trivial to locate in markup. */
.lv-pop-products {
    display: flex;
    gap: 0.75rem;
    margin: 0;
    padding: 0.25rem 0.125rem 0.25rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
}

.lv-pop-product {
    display: flex;
    flex: 0 0 min(62%, 12rem);
    flex-direction: column;
    scroll-snap-align: start;
    border: 1px solid var(--lvpop-hairline);
    border-radius: var(--lvpop-radius-sm);
    background: var(--lvpop-paper);
    color: inherit;
    text-decoration: none;
    overflow: hidden;
    transition: border-color var(--lvpop-dur) var(--lvpop-ease),
        box-shadow var(--lvpop-dur) var(--lvpop-ease),
        transform var(--lvpop-dur) var(--lvpop-ease);
}

.lv-pop-product:hover {
    border-color: color-mix(in srgb, var(--lvpop-accent) 38%, transparent);
    box-shadow: 0 10px 24px -16px rgb(18 12 8 / 0.5);
    transform: translateY(-2px);
    color: inherit;
}

.lv-pop-product__media {
    position: relative;
    display: block;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: var(--lvpop-cream);
}

.lv-pop-product__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.lv-pop-product__flag {
    position: absolute;
    inset-inline-start: 0.375rem;
    inset-block-end: 0.375rem;
    padding: 0.125rem 0.5rem;
    border-radius: 9999px;
    background: rgb(18 12 8 / 0.78);
    color: #fff;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.lv-pop-product__info {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.625rem 0.75rem 0.75rem;
}

.lv-pop-product__title {
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--lvpop-text);
    /* Two lines then an ellipsis: a 90-character product name cannot be allowed
       to decide the height of the dialog. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
}

.lv-pop-product__price {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--lvpop-text);
    font-variant-numeric: tabular-nums;
}

.lv-pop-product--out .lv-pop-product__price,
.lv-pop-product--out .lv-pop-product__title {
    color: var(--lvpop-muted);
}

.lv-pop-product__action {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: auto;
    padding-top: 0.375rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--lvpop-accent);
}

.lv-pop-product__action svg {
    width: 0.75rem;
    height: 0.75rem;
    stroke-width: 2;
    transition: transform var(--lvpop-dur) var(--lvpop-ease);
}

.lv-pop-product:hover .lv-pop-product__action svg {
    transform: translateX(3px);
}

/* Two or three products share a row as soon as the column can hold them. */
@media (min-width: 720px) {
    .lv-pop-products {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
        overflow: visible;
        scroll-snap-type: none;
    }

    .lv-pop-product {
        flex: none;
    }
}

/* One featured product reads as a single horizontal feature, not a lone tile
   stranded in a three-column grid. */
.lv-pop--product .lv-pop-products {
    display: block;
    overflow: visible;
}

.lv-pop--product .lv-pop-product {
    flex-direction: row;
    align-items: stretch;
}

.lv-pop--product .lv-pop-product__media {
    flex: 0 0 7.5rem;
    aspect-ratio: 3 / 4;
    width: 7.5rem;
}

.lv-pop--product .lv-pop-product__info {
    justify-content: center;
    padding: 0.875rem 1rem;
}

.lv-pop--product .lv-pop-product__title {
    font-size: 0.9375rem;
}

/* ===== 10. Call to action + dismissal ===================================== */
.lv-pop-cta {
    position: sticky;
    bottom: calc(var(--lvpop-pad) * -1);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    /* 44px keeps the primary action comfortably tappable on a phone. */
    min-height: 2.75rem;
    margin: 0.25rem calc(var(--lvpop-pad) * -1) calc(var(--lvpop-pad) * -1);
    padding: 0.75rem 1.75rem;
    background: var(--lvpop-accent);
    color: #fff;
    font-family: inherit;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-decoration: none;
    box-shadow: 0 -14px 24px -22px rgb(18 12 8 / 0.9);
    transition: background var(--lvpop-dur) var(--lvpop-ease),
        transform var(--lvpop-dur) var(--lvpop-ease);
}

/* The same control is a link when the campaign names a destination and a button
   when it does not, so the two must be indistinguishable. */
button.lv-pop-cta {
    border: 0;
    cursor: pointer;
    width: 100%;
}

@media (min-width: 641px) {
    button.lv-pop-cta {
        width: auto;
    }
}

/* Not sticky on wide screens where the dialog never scrolls past its actions;
   there it should simply sit at the end of the copy, inset like its siblings. */
@media (min-width: 641px) {
    .lv-pop-cta {
        position: static;
        align-self: flex-start;
        margin: 0.25rem 0 0;
        border-radius: 9999px;
        padding: 0.8125rem 2rem;
    }
}

.lv-pop-cta:hover {
    background: var(--lvpop-accent-strong);
    color: #fff;
}

.lv-pop-cta:active {
    transform: translateY(1px);
}

.lv-pop-cta__arrow {
    width: 1.0625rem;
    height: 1.0625rem;
    transition: transform var(--lvpop-dur) var(--lvpop-ease);
}

.lv-pop-cta:hover .lv-pop-cta__arrow {
    transform: translateX(4px);
}

.lv-pop-dismiss {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--lvpop-muted);
    cursor: pointer;
    justify-self: center;
}

.lv-pop-dismiss:hover {
    color: var(--lvpop-text);
}

.lv-pop-dismiss input {
    flex: none;
    width: 1rem;
    height: 1rem;
    margin: 0;
    accent-color: var(--lvpop-accent);
    cursor: pointer;
}

/* ===== 11. Composition: image + copy side by side ========================= */
/* Only ever set when there is real artwork *and* real copy, so a campaign that
   is missing either never shows an empty column. */
@media (min-width: 900px) {
    .lv-pop--split {
        flex-direction: row;
        --lvpop-w: 880px;
    }

    /* A floor on the artwork column keeps a two-line headline from collapsing
       the photograph into a letterbox band. */
    .lv-pop--split .lv-pop-media {
        flex: 0 0 46%;
        min-height: 22rem;
    }

    .lv-pop--split .lv-pop-media img {
        height: 100%;
        min-height: 0;
        max-height: none;
    }

    .lv-pop--split .lv-pop-body {
        flex: 1 1 auto;
        justify-content: center;
        padding: clamp(1.75rem, 2.6vw, 2.75rem);
    }

    /* Full-bleed artwork is allowed to be genuinely large on a desktop. */
    .lv-pop--image .lv-pop-media img {
        min-height: 20rem;
        max-height: min(72svh, 620px);
    }
}

/* Artwork with no copy of its own gets a caption bar rather than a scrim: the
   photograph is whatever the admin uploaded — a dark editorial shot or a
   product on a white background — and no gradient is reliably legible over
   both. A solid bar is legible over everything and keeps the actions the same
   as every other composition. */
.lv-pop--image .lv-pop-body {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
    padding: 0.875rem clamp(1rem, 2vw, 1.5rem);
    border-block-start: 1px solid var(--lvpop-hairline);
    background: var(--lvpop-paper);
    overflow-y: visible;
}

.lv-pop--image .lv-pop-cta {
    position: static;
    min-height: 2.5rem;
    margin-inline-start: auto;
    margin-block: 0;
    border-radius: 9999px;
    padding: 0.625rem 1.375rem;
}



/* Video keeps a single column at every width: the player is the composition. */
.lv-pop--video .lv-pop-body {
    padding-block-start: clamp(1.25rem, 2.2vw, 2rem);
}

/* ===== 12. Responsive ===================================================== */
/* Tablet: the artwork stacks above the copy instead of forming half of the
   dialog. The band still has to respect the photograph — a flat 15rem cap
   turns a square campaign shot into a panoramic strip in which nothing can be
   recognised — so the ceiling tracks the viewport and keeps the dialog inside
   it. */
@media (max-width: 899px) {
    .lv-pop-media img {
        min-height: 11rem;
        max-height: min(44svh, 24rem);
    }

    /* Full-bleed artwork is the message, so it is allowed more of the screen
       than a supporting image. */
    .lv-pop--image .lv-pop-media img {
        min-height: 16rem;
        max-height: min(56svh, 30rem);
    }
}

/* Phones: the dialog becomes a bottom sheet. Centring a modal on a phone wastes
   the thumb's reach and forces the close control into the top corner, so the
   sheet pins to the bottom edge, keeps safe-area padding and stays scrollable. */
@media (max-width: 640px) {
    .lv-pop-overlay {
        place-items: end center;
        padding: 0;
    }

    .lv-pop {
        --lvpop-w: 100%;
        --lvpop-pad: 1.125rem;
        max-height: min(92svh, 760px);
        border-end-start-radius: 0;
        border-end-end-radius: 0;
        border-radius: 20px 20px 0 0;
        transform: translate3d(0, 24px, 0);
    }

    .lv-pop-overlay.is-closing .lv-pop {
        transform: translate3d(0, 16px, 0);
    }

    /* The grabber reads as a sheet, and the safe area keeps the sticky CTA clear
       of the home indicator. */
    .lv-pop::before {
        content: "";
        position: absolute;
        inset-block-start: 0.4375rem;
        inset-inline-start: 50%;
        transform: translateX(-50%);
        z-index: 3;
        width: 2.25rem;
        height: 3px;
        border-radius: 9999px;
        background: color-mix(in srgb, var(--lvpop-ink) 22%, transparent);
        pointer-events: none;
    }

    .lv-pop-body {
        padding-block-start: 1.625rem;
        padding-block-end: calc(1.125rem + env(safe-area-inset-bottom, 0px));
    }

    /* The sticky action bleeds to the physical bottom edge and grows its own
       bottom padding by the safe area, so the label never sits under the home
       indicator even while it is pinned above scrolling copy. */
    .lv-pop-cta {
        bottom: calc(-1.125rem - env(safe-area-inset-bottom, 0px));
        margin-bottom: calc(-1.125rem - env(safe-area-inset-bottom, 0px));
        padding: 0.875rem 1.5rem calc(0.875rem + env(safe-area-inset-bottom, 0px));
    }

    /* The caption bar is the last thing in the sheet, so it carries the safe
       area itself instead of relying on the sticky-action treatment. */
    .lv-pop--image .lv-pop-body {
        padding-block: 0.875rem calc(0.875rem + env(safe-area-inset-bottom, 0px));
    }

    /* Artwork on a phone is a headline band, never a half-empty column. */
    .lv-pop-media img {
        min-height: 8rem;
        max-height: 12.5rem;
    }

    .lv-pop--image .lv-pop-media img {
        min-height: 13rem;
        max-height: min(50svh, 380px);
    }

    .lv-pop-product {
        flex-basis: min(70%, 11rem);
    }
}

/* Very small phones: drop to a single product per rail view and tighten the
   type scale rather than shrinking everything proportionally. */
@media (max-width: 360px) {
    .lv-pop-title {
        font-size: 1.3125rem;
    }

    .lv-pop-text {
        font-size: 0.875rem;
    }

    .lv-pop-coupon {
        flex-direction: column;
        align-items: stretch;
    }

    .lv-pop-coupon__copy {
        justify-content: center;
    }
}

/* ===== 13. RTL ============================================================ */
/* The layout is written with logical properties, so mirroring is automatic.
   These are the cases where direction genuinely changes the design: directional
   icons must flip, and Arabic copy needs a slightly looser measure. */
html[dir="rtl"] .lv-pop-cta__arrow,
html[dir="rtl"] .lv-pop-product__action svg {
    transform: scaleX(-1);
}

html[dir="rtl"] .lv-pop-product:hover .lv-pop-product__action svg,
html[dir="rtl"] .lv-pop-cta:hover .lv-pop-cta__arrow {
    transform: scaleX(-1) translateX(4px);
}

html[dir="rtl"] .lv-pop-title {
    letter-spacing: 0;
    line-height: 1.35;
}

html[dir="rtl"] .lv-pop-text {
    max-width: 48ch;
    line-height: 1.8;
}

html[dir="rtl"] .lv-pop-badge__value {
    letter-spacing: 0;
}

/* Arabic reads better flush-right against the badge rule; the rule itself must
   not sit to the left of the label. */
html[dir="rtl"] .lv-pop-badge {
    flex-direction: row-reverse;
}

/* ===== 14. Reduced motion + forced colors ================================ */
@media (prefers-reduced-motion: reduce) {
    .lv-pop-overlay,
    .lv-pop,
    .lv-pop-close,
    .lv-pop-cta,
    .lv-pop-coupon__copy,
    .lv-pop-product,
    .lv-pop-product__action svg,
    .lv-pop-cta__arrow {
        transition-duration: 1ms !important;
    }

    .lv-pop {
        transform: none !important;
    }

    .lv-pop-close:hover,
    .lv-pop-close:active {
        transform: none;
    }

    .lv-pop-product:hover {
        transform: none;
    }

    .lv-pop-cta:hover .lv-pop-cta__arrow,
    .lv-pop-product:hover .lv-pop-product__action svg {
        transform: none;
    }
}

@media (forced-colors: active) {
    .lv-pop {
        border: 1px solid CanvasText;
    }

    .lv-pop-close,
    .lv-pop-cta,
    .lv-pop-coupon__copy {
        border: 1px solid ButtonText;
    }
}

/* ===== 15. Flush campaigns (no padding / margin) ========================== */
/* One builder switch (popups.is_flush) strips every inner padding, the gap
   between elements and the gutter around the dialog, so a campaign that is
   nothing but artwork can bleed edge to edge. Kept last in the sheet so it
   wins over the composition paddings and the responsive overrides above. */
.lv-pop--flush {
    --lvpop-pad: 0px;
}

.lv-pop-overlay--flush {
    padding: 0;
}

.lv-pop--flush .lv-pop-body {
    padding: 0;
    gap: 0;
}

.lv-pop--flush.lv-pop--title-only .lv-pop-body {
    padding-block: 0;
}

.lv-pop--flush.lv-pop--image .lv-pop-body {
    padding: 0;
}

@media (min-width: 900px) {
    .lv-pop--flush.lv-pop--split .lv-pop-body {
        padding: 0;
    }
}

@media (max-width: 640px) {
    .lv-pop--flush .lv-pop-body {
        padding-block: 0;
    }

    /* The sticky action keeps its safe-area padding but no longer bleeds
       through a body padding it no longer has. */
    .lv-pop--flush .lv-pop-cta {
        bottom: 0;
        margin-bottom: 0;
    }

    .lv-pop--flush.lv-pop--image .lv-pop-body {
        padding-block: 0;
    }
}

/* ===== Overlay CTA on media-only campaigns (popups.cta_position) ========== */
/* When a campaign is only an image (or clip) plus its single CTA, the builder
   can pin that CTA ON the artwork at one of nine grid positions:
   vertical top/center/bottom × horizontal left/center/right. Physical
   left/right keep the admin picker WYSIWYG in both writing directions; the
   close disc (z-index 3) always stays clickable above the button. */
.lv-pop--cta-overlay .lv-pop-media {
    position: relative;
}

.lv-pop--cta-overlay {
    --lvpop-cta-gutter: clamp(0.75rem, 2vw, 1.5rem);
}

/* `.lv-pop--image .lv-pop-cta` and friends pin the panel CTA (static, auto
   margins) at specificity 0-2-0, so every overlay rule here carries the
   dialog class too — same specificity, and these come later in the sheet. */
.lv-pop .lv-pop-cta--overlay,
.lv-pop button.lv-pop-cta--overlay {
    position: absolute;
    bottom: auto;
    z-index: 2;
    width: auto;
    margin: 0;
    border-radius: 9999px;
    box-shadow: 0 12px 28px -10px rgb(18 12 8 / 0.55);
}

.lv-pop--cta-top-left .lv-pop-cta--overlay {
    top: var(--lvpop-cta-gutter);
    left: var(--lvpop-cta-gutter);
}

.lv-pop--cta-top-center .lv-pop-cta--overlay {
    top: var(--lvpop-cta-gutter);
    left: 50%;
    transform: translateX(-50%);
}

.lv-pop--cta-top-right .lv-pop-cta--overlay {
    top: var(--lvpop-cta-gutter);
    right: var(--lvpop-cta-gutter);
}

.lv-pop--cta-center-left .lv-pop-cta--overlay {
    top: 50%;
    left: var(--lvpop-cta-gutter);
    transform: translateY(-50%);
}

.lv-pop--cta-center .lv-pop-cta--overlay {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.lv-pop--cta-center-right .lv-pop-cta--overlay {
    top: 50%;
    right: var(--lvpop-cta-gutter);
    transform: translateY(-50%);
}

.lv-pop--cta-bottom-left .lv-pop-cta--overlay {
    bottom: var(--lvpop-cta-gutter);
    left: var(--lvpop-cta-gutter);
}

.lv-pop--cta-bottom-center .lv-pop-cta--overlay {
    bottom: var(--lvpop-cta-gutter);
    left: 50%;
    transform: translateX(-50%);
}

.lv-pop--cta-bottom-right .lv-pop-cta--overlay {
    bottom: var(--lvpop-cta-gutter);
    right: var(--lvpop-cta-gutter);
}
