/* Sold-out gate (Slice C5) — visual disabled state on the add-to-cart button when
   the resolved variant is tracked and at 0 (backorders off). The button STAYS
   clickable so the blocked click can toast the out-of-stock message
   (variations_cl.hasErrors reads data-vr-soldout set by Product_cl).
   Two classes, not the id it had until 15-10-2026 (G103): the button also carries `is-disabled`, and a button
   design with its Disabled state on (`.cl-preset-N.cl-preset-N.is-disabled`) outranks this dim — for the properties
   it sets. So the dim is opacity only (its grayscale(0.4) went on 16-10-2026, G115: no Disabled state ever undid it):
   the shipped Disabled state (`opacity:0.6`) is then the whole look, and a merchant's Disabled state must set an
   opacity of its own to replace 0.55. It reaches the thank-you upsell's button (no id) and the sticky bar's too. */
.cl-addtocart-button.cl-is-soldout,
.cl-sticky-bt.cl-is-soldout {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Back-in-stock waitlist (Slice F) — revealed by the stock gate when sold out */
.cl-stock-waitlist {
    margin-top: 12px;
}
.cl-stock-waitlist-title {
    font-weight: 600;
    margin-bottom: 6px;
}
.cl-stock-waitlist-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
/* flex-basis 150px + wrap: each field keeps a usable width and drops to the
   next line instead of squeezing to ~80px when 2-3 fields are enabled on a
   narrow (mobile) screen. */
.cl-stock-waitlist-row .cl-stock-waitlist-email,
.cl-stock-waitlist-row .cl-stock-waitlist-phone,
.cl-stock-waitlist-row .cl-stock-waitlist-name {
    flex: 1 1 150px;
    min-width: 0;
}

/* Colour swatch: the view prints the colour as a variable and this rule paints it (views carry
   no inline CSS). Until 08-10-2026 it was an inline background-color, and the admin preview's
   live edit of the swatch size (vr_colorbox_style, which sizes this span), which then replaced
   the span's whole inline style, blanked it until the preview reloaded. Only the product's own
   variations box: a listing card's dot prints the same variable and plist1.css paints it. */
.cl_variations.cl_product_block .cl-vr-colorbox ul li span:nth-child(1) {
    background-color: var(--cl-vr-swatch-color);
}

/* A sold-out option (15-10-2026, G103): product.js puts vr-is-soldout on every option whose combination is sold out,
   given the other groups' picks; it stays pickable, so the waitlist can show. vr_soldout_option_display (a class on
   .cl_variations) draws it as Shopify Dawn does: a colour or a photo at 40 % with a line across the option, a text
   button at 60 % and struck through. Only a swatch's fill dims, so a picked one keeps its full picked frame. */
.cl_variations.vr-soldout-cross .cl-vr-colorbox ul li.vr-is-soldout span:nth-child(1),
.cl_variations.vr-soldout-dim .cl-vr-colorbox ul li.vr-is-soldout span:nth-child(1),
.cl_variations.vr-soldout-cross .cl-vr-images ul li.vr-is-soldout img,
.cl_variations.vr-soldout-dim .cl-vr-images ul li.vr-is-soldout img {
    opacity: 0.4;
}
.cl_variations.vr-soldout-cross .cl-vr-buttons ul li.vr-is-soldout,
.cl_variations.vr-soldout-dim .cl-vr-buttons ul li.vr-is-soldout {
    opacity: 0.6;
}
/* !important: an option design with "Force styles" on compiles `text-decoration: none !important` (dev1's preset 11,
   measured 15-10-2026), and the mark must still show. */
.cl_variations.vr-soldout-cross .cl-vr-buttons ul li.vr-is-soldout {
    text-decoration: line-through !important;
}
/* The line, from the bottom-left corner of the option to its top-right (Dawn's -45°; the option is already
   position:relative, variations generated_css.php), in the option's text colour with a white edge so it shows on a
   dark colour too. */
.cl_variations.vr-soldout-cross .cl-vr-colorbox ul li.vr-is-soldout::after,
.cl_variations.vr-soldout-cross .cl-vr-images ul li.vr-is-soldout::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
        linear-gradient(to top left, transparent calc(50% - 1px), currentColor calc(50% - 1px), currentColor calc(50% + 1px), transparent calc(50% + 1px)),
        linear-gradient(to top left, transparent calc(50% - 2.5px), rgba(255, 255, 255, 0.85) calc(50% - 2.5px), rgba(255, 255, 255, 0.85) calc(50% + 2.5px), transparent calc(50% + 2.5px));
}

/* ── Variation option list: slider mode (vr_{buttons,colorbox,images}_layout) ──
   Mirrors the card's rules (plist1.css ~733-806) scoped to this compo instead.
   Duplicated rather than shared on purpose: the card's copy is `.plist1`-scoped
   and slider.css's rules target `.cl_list`, which the variations <ul>
   never carries — so neither reaches here. Per CLAUDE.md, a class used by 2-3
   compos lives in each compo's own CSS.

   Grid mode is NOT here: its column counts are merchant-set, so they compile
   per-instance in generated_css.php. Only the structural slider bits are
   static enough to live in a stylesheet. */
.cl_variations .cl-vr-parent.cl_slider {
    position: relative;
}
.cl_variations .cl-vr-items ul.cl-vr-elements[data-slider="true"] {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    /* Deliberately NO `scroll-behavior: smooth`. In this exact layout (flex UL
       inside a flex row, scroll-snap mandatory) Chrome silently drops scrollLeft
       mutations when scroll-behavior is smooth, so the arrows become no-ops.
       slider_cl still passes behavior explicitly in its scrollTo() calls. The
       view also sends data-slider-scroll-behavior="auto" for the same reason —
       belt and braces, both verified on the card before being copied here. */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.cl_variations .cl-vr-items ul.cl-vr-elements[data-slider="true"]::-webkit-scrollbar {
    display: none;
}
/* Intentionally NO `min-width: 0` on the LI — the merchant's per-variation
   Min Width compiles to `#cl_variations [data-vr-slug="…"] ul li`, and a blanket
   min-width here would silently beat it on every slider chip. Same call the
   card documents at plist1.css:758. */
.cl_variations .cl-vr-items ul.cl-vr-elements[data-slider="true"] > li.cl_item {
    scroll-snap-align: start;
    flex: 0 0 auto;
}
.cl_variations .cl-vr-parent.cl_slider .cl_slider_nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 6px 0 0;
}

/* Inline arrows: prev/next sit on the SIDES of the track rather than below it.
   `display:contents` lets the nav's buttons participate directly in the row's
   flex layout while slider_cl still resolves them via
   wrapper.find('.cl_slider_nav').find('.cl_slider_prev'). */
.cl_variations .cl-vr-parent.cl_slider.cl-vr-arrows-inline .cl-vr-slider-row {
    display: flex;
    align-items: center;
    gap: 4px;
}
.cl_variations .cl-vr-parent.cl_slider.cl-vr-arrows-inline .cl-vr-slider-row > .cl_slider_nav_arrows_only,
.cl_variations .cl-vr-parent.cl_slider.cl-vr-arrows-inline .cl-vr-slider-row > .cl_slider_nav_arrows_only > .cl_slider_arrows {
    display: contents;
}
.cl_variations .cl-vr-parent.cl_slider.cl-vr-arrows-inline .cl-vr-slider-row .cl_slider_prev {
    order: 1;
    flex-shrink: 0;
}
.cl_variations .cl-vr-parent.cl_slider.cl-vr-arrows-inline .cl-vr-slider-row > ul.cl-vr-elements {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
}
.cl_variations .cl-vr-parent.cl_slider.cl-vr-arrows-inline .cl-vr-slider-row .cl_slider_next {
    order: 3;
    flex-shrink: 0;
}

/* ─── Upsell confirmation modal — the product-quickview close-button concept ───────────────
   The × is the shared global visual (.cl-modal-close-x, public.css) rendered as a DIRECT
   child of .cl_modal_container, and these rules pin it HALF OUTSIDE the top-trailing corner
   — the same distinctive position, and the same single `top:-15px` override, that
   .cl-product-quickview .cl-product-quickview-close uses in product_quickview.css.

   Why all three belong together: the × is position:absolute, so hanging it above the card's
   edge only works while the SHELL itself does not scroll. The shared
   `.cl_modal_center .cl_modal_container` rule (public.css) puts `overflow:auto` on the
   container, which would both clip the × and scroll it away with the content. So the scroll
   moves INWARD to .cl_modal_body and the shell stays visible. Scoped by id, so the cart /
   checkout / summary / filter modals keep the shared behaviour untouched.

   Why HERE and not in the block's generated_css.php: that file is a frozen snapshot compiled
   at save time, so a structural rule there reaches an existing store only after an admin
   re-saves the settings page — and a settings-migration cannot close that gap either, because
   migrations are admin-gated by construction (CLAUDE.md, "Migrations are ADMIN-ONLY"). A
   static stylesheet ships as a file and lands on the next asset-version bump. The quickview
   made the same call for the same reason.

   Safe against the settings string: the container's user-facing key allows exactly one
   property (`single_css_supported => ['max-width']`), so the compiled rule can never declare
   overflow / display / flex-direction / max-height and the two files cannot fight — even
   though generated_css is emitted later in <head> and would win a tie. */
#cl_p_upsell_celebration .cl_modal_container {
    overflow: visible;
    display: flex;
    flex-direction: column;
    /* The shared cap is max-height:96% (public.css); 96% of a TRANSFORM-CENTRED box leaves
       only (100-96)/2 = 2% of the visible viewport per side as headroom, while the × needs a
       hard 15px above the edge — that clips on any viewport shorter than ~750px, i.e. most
       phones. calc(100% - 40px) reserves 20px per side instead. */
    max-height: calc(100% - 40px);
}
#cl_p_upsell_celebration .cl_modal_body {
    /* min-height:0 lets a flex child shrink below its content so overflow-y can engage —
       without it the body grows past the container's max-height instead of scrolling. */
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    /* The quickview's own body padding. It moved here from the container when the design
       preset was dropped: the container must stay padding-free so the footer can run
       edge-to-edge and the × can sit at the true corner — which is what this block's
       generated_css.php already documented ("padding goes to .cl_modal_body ... everything
       else stays on .cl_modal_container so the card frame still renders").
       Specificity is deliberately (1,1,0) — the SAME as the compiled
       `#cl_p_upsell_celebration .cl_modal_body { <?= $modalPadding ?> }` rule, which is
       emitted later in <head> and therefore still wins. So this is a DEFAULT a merchant's
       own Container Style padding overrides, never a lock. */
    padding: 20px;
}
/* Half-outside position, mirroring .cl-product-quickview .cl-product-quickview-close. */
#cl_p_upsell_celebration .cl-modal-close-x {
    top: -15px;
}
/* Neutralise the STALE `position:sticky; bottom:0` that existing installs still carry in their
   frozen generated_css snapshot. That pair was correct only while the CONTAINER owned the
   scroll; now that the container is a flex column with overflow:visible and the BODY scrolls,
   a sticky flex item is pulled up out of flow and the "View cart" button lands in the middle
   of the message instead of under it (measured: actions at y=407 inside a body spanning
   113→558). The block's generated_css.php no longer emits those two declarations, but a
   snapshot only recompiles when an admin re-saves — so this override is what makes the layout
   correct on every existing store today.
   Specificity is deliberate: `#id .container > .actions` is (1,2,0), which beats the snapshot's
   `#id .actions` (1,1,0) regardless of the fact that generated_css is emitted later in <head>
   and would otherwise win the tie. */
#cl_p_upsell_celebration .cl_modal_container > .cl_p_upsell_celebration_actions {
    position: static;
    /* The quickview footer's two load-bearing declarations, ported:
       `flex-shrink:0` so the bar never compresses when the message is long (it is a flex item
       beside a `flex:1` body, so without this it is the thing that gives), and the `border-top`
       hairline that separates a footer from the content scrolling above it. Same colour token
       and same fallback the quickview uses. */
    flex-shrink: 0;
    border-top: 1px solid var(--cl-border-color1, #e5e7eb);
    /* Edge-to-edge now that the container carries no padding, so the bar needs the card's
       own bottom corners or its background would square off the rounded shell. `inherit`
       takes the container's computed radius rather than hardcoding one — the quickview can
       write `0 0 12px 12px` because its shell is a fixed 12px, whereas this shell inherits
       whatever `.cl_modal_center .cl_modal_container` sets (10px today, public.css). */
    border-bottom-left-radius: inherit;
    border-bottom-right-radius: inherit;
    /* The quickview footer's own padding — 4px alone is too tight once edge-to-edge. */
    padding: 4px 10px;
}
/* Quickview parity: `.cl-product-quickview-footer button { max-height: 40px }` keeps the bar
   compact. Measured here at 41px, so this trims 1px. Specificity (1,2,0) beats the snapshot's
   (1,1,0) rule for this button, which is emitted later in <head>. */
#cl_p_upsell_celebration .cl_modal_container .cl_p_upsell_view_cart_bt {
    max-height: 40px;
}

/* Stories / reviews section titles. They were an <h3> inside this div, and the gap
   under the title was the browser's h3 margin (1em, so it grew with the font size).
   Since 26-09-2026 the preset sits on this div and there is no browser margin, so the
   gap is set here. Space above the section = the block's container style
   (`{stories,reviews}_container_style`, margin-top). */
.cl-stories-title,
.cl-reviews-title {
    margin-bottom: 16px;
}

/* Upsell card photo: the box the badges on the photo are placed in (G29, public/partials/photo_badges.php). */
.cl-p-upsell-image {
    position: relative;
}
