/* Cart drawer styling.
 *
 * The ERP keeps these rules in global/css/main.css — a 44KB full site theme that
 * would flatten any cms2 design, so it is not loaded. Only the container is
 * styled here; everything inside a cart line is markup cart.js clones from the
 * templates in layouts/a.php.
 *
 * Neutral on purpose: a site's custom_css restyles it, the same way the themes
 * already restyle the consent banner.
 */
.sb-cart { position: static; }
.sb-cart-anchor { height: 0; }
.sb-cart .sb-cart-snippets { display: none !important; }

/* Header-driven drawer: the theme's own cart icon is the trigger, so the tab
   would be a second cart control on every page. Moved off-screen rather than
   display:none — sbcart.js opens the drawer by clicking this element, and an
   off-screen node still takes a programmatic click and can still be measured. */
.sb-cart.sb-cart-notab .cartButton {
    position: absolute;
    left: -9999px;
    top: auto;
    right: auto;
}

/* the drawer's own trigger — themes that open it from the header cart icon
   instead can hide this with .sb-cart .cartButton { display: none } */
.sb-cart .cartButton {
    position: fixed;
    top: 50%;
    right: 0;
    z-index: 401;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px 12px;
    background: #111;
    color: #fff;
    border-radius: 6px 0 0 6px;
    text-decoration: none;
}
.sb-cart .nrOfItemsInCart_preview:empty { display: none; }
.sb-cart .nrOfItemsInCart_preview {
    min-width: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: #d92d20;
    color: #fff;
    font: 600 11px/18px system-ui, sans-serif;
    text-align: center;
}

/* ── Drawer panel ────────────────────────────────────────────────────────────
 *
 * Geometry copied from the brandsites' own rules (global/css/main.css:1748+),
 * because cart.js drives the states and they have to match: it adds `cartOpen`
 * to .cartWrapper and then `cartOpenShow` one tick later, so the panel needs to
 * become displayed FIRST and fade in second — one combined rule would skip the
 * transition. `cartAtTop` follows the header out of view, and `noItemsInCart`
 * hides the totals footer.
 *
 * A dropdown under the header rather than a full-height side drawer: that is
 * what the ShaperBuddy shops look like, and the panel is small enough that a
 * full-height sheet would be mostly empty.
 *
 * Two knobs for themes: --sb-cart-top (distance from the top of the viewport)
 * and --sb-cart-right (how far in from the viewport edge, so the panel can line
 * up with the header's own cart icon). Left unset, the top comes from
 * --sb-cart-header, which sbcart.js measures off the real header.
 */
.sb-cart .cartWrapper {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 402;
}
.sb-cart .cartContentsWrapper {
    position: absolute;
    top: var(--sb-cart-top, var(--sb-cart-header, 80px));
    right: var(--sb-cart-right, 20px);
    width: min(560px, calc(100vw - 24px));
    display: none;
    opacity: 0;
    transition: opacity .2s ease;
    background: #fff;
    color: #222;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .25);
}
.sb-cart .cartWrapper.cartAtTop .cartContentsWrapper { top: var(--sb-cart-top-scrolled, 12px); }
.sb-cart .cartWrapper.cartOpen .cartContentsWrapper { display: block; }
.sb-cart .cartWrapper.cartOpenShow .cartContentsWrapper { opacity: 1; }

.sb-cart .cartContentsHeader {
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    /* background: var(--main_color0, #111); */
    background: black;
    color: #fff;
    /* font: 600 14px/1 system-ui, sans-serif; */
    letter-spacing: .08em;
    text-transform: uppercase;
}
.sb-cart .cartContentsBody,
.sb-cart .cartContentsFooter { box-sizing: border-box; padding: 20px; }
.sb-cart .cartContentsFooter { padding-top: 0; }
.sb-cart .cartContentsBody_inner {
    box-sizing: border-box;
    max-height: calc(70vh - 120px);
    overflow-y: auto;
}
.sb-cart .noItemsMessage { padding: 24px 0; color: #777; text-align: center; }

/* One cart line: thumb | name + description | remove over sub-total. */
.sb-cart .cartContent_Item {
    display: flex;
    align-items: stretch;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid #eee;
}
.sb-cart .cartContentsBody_inner .cartContent_Item:last-child { border-bottom: 0; }
.sb-cart .ccb_left { flex: 0 0 22%; display: flex; align-items: center; justify-content: center; }
.sb-cart .ccb_left img { width: 100%; height: auto; object-fit: contain; }
.sb-cart .ccb_center { flex: 1; min-width: 0; }
.sb-cart .ccb_name {
    margin: 0 0 8px;
    font: 600 14px/1.35 system-ui, sans-serif;
    text-transform: uppercase;
}
.sb-cart .ccb_aditionalinfo {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    margin: 0;
    font: 13px/1.5 system-ui, sans-serif;
    color: #555;
}
.sb-cart .ccb_right {
    flex: 0 0 22%;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: space-between;
    text-align: right;
}
.sb-cart .removeFromCart { color: #999; line-height: 0; text-decoration: none; }
.sb-cart .removeFromCart:hover { color: #c00; }
.sb-cart .removeFromCart .material-icons { font-size: 20px; }
.sb-cart .ccbr_priceLabel { display: block; font: 12px/1.4 system-ui, sans-serif; color: #666; }
.sb-cart .ccbr_priceDetails {
    display: flex;
    justify-content: flex-end;
    font: 14px/1.4 system-ui, sans-serif;
    white-space: nowrap;
}

/* The quantity line. Surfboards are single-qty upstream, and cart.js marks those
   lines .isSingleQty — the steppers go, the number stays. */
.sb-cart .ccbItemDescQty { display: inline-flex; align-items: center; gap: 10px; }
.sb-cart .ccbItemDescQty label { font-weight: 600; }
.sb-cart .ccbItemDescQty_wrapp { display: inline-flex; align-items: center; }
.sb-cart .ccbItemDescQty_wrapp a { color: #111; line-height: 0; text-decoration: none; }
.sb-cart .ccbidQty_number { min-width: 20px; text-align: center; }
.sb-cart .isSingleQty .ccbidQty_up,
.sb-cart .isSingleQty .ccbidQty_down { display: none; }

.sb-cart .ccfPriceWrapper,
.sb-cart .ccfNavWrapper { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sb-cart .ccfPriceWrapper { padding: 16px 0; border-top: 1px solid #eee; }
.sb-cart .ccfPriceTitle {
    font: 600 13px/1 system-ui, sans-serif;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.sb-cart .ccfPriceTotal { display: flex; font: 700 20px/1 system-ui, sans-serif; }
.sb-cart .continueShopping { color: #666; font-size: 13px; text-decoration: none; }
.sb-cart .continueShopping:hover { color: #111; }
/* The checkout button carries materialize's `btn waves-effect` classes, whose
   base lives in public_assets/erp_shop.css — scoped to .sb-shop, which the
   drawer is deliberately NOT under. So it styles itself. */
.sb-cart .cartBtn_goToCheckout {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 42px;
    padding: 0 22px;
    background: var(--main_color0, #111);
    color: #fff;
    font: 600 13px/1 system-ui, sans-serif;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-decoration: none;
    border: 0;
    border-radius: 100px;
}
.sb-cart .cartBtn_goToCheckout:hover { background: var(--main_color1, #333); color: #fff; }
/* cart.js flags an empty basket — no totals to show, and no checkout to offer. */
.sb-cart .cartWrapper.noItemsInCart .cartContentsFooter { display: none; }

/* cart.js toggles these two while a request is in flight */
.sb-cart .cartContentsWrapper_loading,
.sb-cart .cartInit_loading { display: none; }
.sb-cart .cartContentsWrapper.cartContentLoading .cartContentsWrapper_loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .7);
    z-index: 1;
}

@media (max-width: 600px) {
    .sb-cart .cartContentsWrapper { right: var(--sb-cart-right-mobile, 12px); }
    .sb-cart .ccb_left { flex-basis: 26%; }
    .sb-cart .ccb_right { flex-basis: 28%; }
}

/* -- Loading spinner ------------------------------------------------------
 *
 * The ERP templates already emit Materialize's preloader markup ($preloaderBig
 * / $preloaderSmall from global/php/htmlsnippets.php, passed through by
 * erp_bridge.php), and shop.js and cart.js already show and hide it. Only the
 * shape was missing: the geometry and keyframes live in materialize.min.css,
 * which this project deliberately does not load (142KB, with global resets on
 * html/body/a/ul/button). The elements were rendering 0x0 with no animation.
 *
 * Drawn here as a plain ring rather than by reproducing that file's four-layer
 * clipped-arc spinner: one colour, a few lines, and nothing that has to stay in
 * sync with a vendor stylesheet. The layers Materialize would have animated are
 * hidden -- they are what carries its four-colour cycle, which a single-brand
 * shop has no use for.
 *
 * Reduced motion slows the spin rather than stopping it: a still ring would
 * read as a broken image, and the whole point is to say "working".
 */
.sb-cart .preloader-wrapper {
    display: inline-block;
    position: relative;
    width: 48px;
    height: 48px;
}
.sb-cart .preloader-wrapper.small { width: 32px; height: 32px; }
.sb-cart .preloader-wrapper > * { display: none; }
.sb-cart .preloader-wrapper::after {
    content: "";
    position: absolute;
    inset: 0;
    box-sizing: border-box;
    border: 3px solid rgba(18, 18, 18, .15);
    border-top-color: var(--main_color0, #be202e);
    border-radius: 50%;
    animation: cms2-erp-spin .75s linear infinite;
}
@keyframes cms2-erp-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .sb-cart .preloader-wrapper::after { animation-duration: 2.4s; }
}

/* -- Header icon while the basket is still loading ------------------------
 *
 * On the brandsites the cart icon is a spinner until the first GET resolves,
 * and only then becomes a clickable cart with its count. cart.js already
 * carries the signal: the drawer starts with .cartInitLoading and the class is
 * dropped in all three places the request can end -- processCart() on success,
 * the .fail() handler, and the cart-emptied path -- so the icon can never be
 * left spinning.
 *
 * The flag sits on the drawer and the icon sits in the header, with only <body>
 * between them, so :has() is what connects the two. Where :has() is not
 * supported the icon simply shows as it does now; the ring is an affordance,
 * not information, and nothing is lost.
 *
 * visibility rather than display so the icon keeps its box and the header does
 * not reflow when the spinner is swapped out, and pointer-events: none so the
 * icon cannot be clicked before there is a basket to open -- which is the part
 * of the brandsite behaviour that actually matters.
 */
body:has(.cartWrapper.cartInitLoading) .cms2-cart {
    position: relative;
    pointer-events: none;
}
body:has(.cartWrapper.cartInitLoading) .cms2-cart > svg,
body:has(.cartWrapper.cartInitLoading) .cms2-cart .cms2-cart-badge { visibility: hidden; }
body:has(.cartWrapper.cartInitLoading) .cms2-cart::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    box-sizing: border-box;
    border: 2px solid rgba(18, 18, 18, .15);
    border-top-color: var(--main_color0, #be202e);
    border-radius: 50%;
    animation: cms2-erp-spin .75s linear infinite;
}
