/* ═══════════════════════════════════════════════════════════
   LAUXURIA — features.css  (additive, never overrides base)
   All new feature styles scoped to avoid conflicts
═══════════════════════════════════════════════════════════ */

/* ── LOGIN MODAL ──────────────────────────────────────────── */
.login-overlay{position:fixed;inset:0;background:rgba(14,12,11,.55);backdrop-filter:blur(4px);z-index:998;opacity:0;pointer-events:none;transition:opacity .3s ease}
.login-overlay.open{opacity:1;pointer-events:all}
.login-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-46%);z-index:999;background:#faf7f2;width:min(460px,94vw);max-height:90vh;overflow-y:auto;padding:40px 40px 36px;opacity:0;pointer-events:none;transition:opacity .3s ease,transform .3s ease;border:1px solid #e8e0d4;box-shadow:0 24px 80px rgba(14,12,11,.18)}
.login-modal.open{opacity:1;pointer-events:all;transform:translate(-50%,-50%)}
.login-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:28px}
.login-header h2{font-family:var(--font-display);font-size:26px;font-weight:400;letter-spacing:.02em}
.login-close{background:none;border:none;font-size:24px;color:var(--muted);line-height:1;padding:4px 8px;transition:color var(--tr)}
.login-close:hover{color:var(--ink)}
.login-form .login-group{margin-bottom:20px;position:relative}
.login-form label{display:block;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;font-weight:500}
.login-form input[type=email],.login-form input[type=password],.login-form input[type=text]{width:100%;border:1px solid var(--border);background:#fff;padding:12px 16px;font-family:var(--font-body);font-size:14px;color:var(--ink);outline:none;transition:border-color var(--tr)}
.login-form input:focus{border-color:var(--gold)}
.login-form input.input-error{border-color:#c0392b}
.login-form input.input-ok{border-color:#27ae60}
.login-pw-group{position:relative}
.login-pw-toggle{position:absolute;right:14px;top:36px;background:none;border:none;font-size:14px;cursor:pointer;color:var(--muted);padding:2px}
.login-forgot{display:block;font-size:12px;color:var(--gold);margin-top:8px;text-align:right;letter-spacing:.04em}
.login-forgot:hover{text-decoration:underline}
.login-remember{display:flex;align-items:center;gap:8px;margin-bottom:24px}
.login-remember input{accent-color:var(--gold)}
.login-remember label{font-size:13px;color:var(--muted);cursor:pointer}
.login-error-msg{background:#fdf2f2;border:1px solid #f5c6c6;color:#c0392b;padding:10px 14px;font-size:13px;margin-bottom:16px;border-radius:2px}
.login-field-error{display:block;font-size:11px;color:#c0392b;margin-top:5px;min-height:16px}
.login-btn{width:100%;background:var(--ink);color:var(--cream);border:none;padding:14px;font-size:12px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;transition:background var(--tr);display:block;text-align:center;cursor:pointer}
.login-btn:hover{background:#2a2520}
.login-btn-ghost{width:100%;background:none;border:1px solid var(--border);color:var(--muted);padding:12px;font-size:12px;letter-spacing:.1em;text-transform:uppercase;transition:all var(--tr);display:block;text-align:center;cursor:pointer;margin-top:8px}
.login-btn-ghost:hover{border-color:var(--ink);color:var(--ink)}
.login-divider{text-align:center;margin:20px 0;position:relative;color:var(--muted);font-size:12px}
.login-divider:before{content:'';position:absolute;top:50%;left:0;right:0;height:1px;background:var(--border)}
.login-divider span{background:#faf7f2;padding:0 12px;position:relative}
.login-social{width:100%;background:#fff;border:1px solid var(--border);padding:12px 16px;font-size:13px;display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:10px;transition:border-color var(--tr),box-shadow var(--tr);cursor:pointer;font-family:var(--font-body);color:var(--ink)}
.login-social:hover{border-color:var(--gold);box-shadow:0 2px 8px rgba(184,150,62,.12)}
.login-signup{text-align:center;font-size:13px;color:var(--muted);margin-top:16px}
.login-signup-link{color:var(--gold);font-weight:500}
.login-logged-in{text-align:center;padding:20px 0}
.login-avatar{width:64px;height:64px;background:var(--gold);color:var(--ink);border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:var(--font-display);font-size:28px;margin:0 auto 16px}

/* ── ANNOUNCEMENT BAR CLOSE ───────────────────────────────── */
.ann{position:relative}
/* Set by the inline script in header.php before first paint when this shopper
   has already closed the bar under the current rule (LAUXURIA -> Hero). */
.ann.is-dismissed{display:none!important}
.ann-close{background:none;border:none;color:rgba(255,255,255,.5);font-size:18px;cursor:pointer;padding:0 0 0 16px;line-height:1;transition:color var(--tr)}
.ann-close:hover{color:var(--gold2)}
.ann-close:focus-visible{color:var(--gold2);outline:2px solid var(--gold2);outline-offset:2px}
/* Two problems on a narrow or touch screen, one rule.
   1. In flow the close button is just another flex item, so on a wrapping bar
      it wraps too: with two or three messages on a phone it lands centred on a
      line of its own, under the text, reading as a stray glyph rather than a
      control.
   2. The 18px glyph measures 27x18 - well under the 44px touch target the bulk
      tier controls already keep on the same (hover:none) query.
   Pinning it to the right edge fixes both: 44px wide, spanning the bar's full
   height however many lines the messages take, so the whole right-hand strip is
   tappable. Height comes from the bar rather than a min-height, which on a
   touch tablet would have pushed a 36px bar out to 62px. The matching padding
   on the left keeps the messages optically centred, and neither applies unless
   the close button actually renders - a bar set to "Never dismissible" keeps
   its full width for its message. */
@media(max-width:768px),(hover:none){
  .ann.is-dismissible{padding-left:44px;padding-right:44px}
  .ann.is-dismissible .ann-close{position:absolute;top:0;right:0;bottom:0;width:44px;margin:0;padding:0;display:flex;align-items:center;justify-content:center}
}

/* ── NOTIFICATION BELL & PANEL ────────────────────────────── */
.notif-trigger{position:relative}
.notif-badge{position:absolute;top:-6px;right:-6px;background:#c0392b;color:#fff;width:18px;height:18px;border-radius:50%;font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center;pointer-events:none}
.notif-overlay{position:fixed;inset:0;z-index:996;display:none}
.notif-overlay.open{display:block}
.notif-panel{position:fixed;top:78px;right:24px;width:360px;max-height:480px;background:#fff;border:1px solid var(--border);box-shadow:0 16px 48px rgba(14,12,11,.14);z-index:997;display:flex;flex-direction:column;transform:translateY(-8px) scale(.97);opacity:0;pointer-events:none;transition:transform .25s ease,opacity .25s ease}
.notif-panel.open{transform:translateY(0) scale(1);opacity:1;pointer-events:all}
.notif-panel-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}
.notif-panel-header h3{font-family:var(--font-display);font-size:18px;font-weight:400}
.notif-mark-all{background:none;border:none;color:var(--gold);font-size:12px;letter-spacing:.06em;cursor:pointer;padding:0}
.notif-mark-all:hover{text-decoration:underline}
.notif-close{background:none;border:none;font-size:22px;color:var(--muted);cursor:pointer;padding:0 4px;line-height:1}
.notif-panel-body{overflow-y:auto;flex:1;padding:8px 0}
.notif-loading{padding:32px;text-align:center;color:var(--muted);font-size:13px}
.notif-item{display:flex;align-items:flex-start;gap:12px;padding:14px 20px;border-bottom:1px solid rgba(232,224,212,.5);transition:background var(--tr);cursor:default}
.notif-item:hover{background:#faf7f2}
.notif-item.unread{background:rgba(184,150,62,.05)}
.notif-item.unread .notif-item-title{font-weight:600}
.notif-icon{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}
.notif-icon.order{background:rgba(184,150,62,.12);color:var(--gold)}
.notif-icon.promo{background:rgba(39,174,96,.1);color:#27ae60}
.notif-icon.system{background:rgba(14,12,11,.06);color:var(--muted)}
.notif-item-body{flex:1;min-width:0}
.notif-item-title{font-size:13px;color:var(--ink);margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.notif-item-msg{font-size:12px;color:var(--muted);line-height:1.5}
.notif-item-time{font-size:11px;color:var(--muted);margin-top:4px;opacity:.7}
.notif-unread-dot{width:7px;height:7px;border-radius:50%;background:var(--gold);flex-shrink:0;margin-top:5px}
.notif-empty{padding:48px 20px;text-align:center;color:var(--muted);font-size:13px}
.notif-empty svg{margin:0 auto 12px;opacity:.3}

/* ── SHARED SMALL BUTTON ──────────────────────────────────── */
/* The cart drawer's coupon UI, its applied-coupon tags and .cd-cart-link used
   to live here too, several hundred lines from the drawer shell they belong to
   — and the two copies had drifted. Everything drawer-specific is in the one
   CART DRAWER block in style.css now; only this button, which the offers UI
   also uses, is still shared from here. */
.btn-gold-sm{background:var(--gold);color:var(--ink);border:none;padding:10px 16px;font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;cursor:pointer;transition:background var(--tr);white-space:nowrap}
.btn-gold-sm:hover{background:var(--gold2)}

/* ── SHOP PAGE LAYOUT ─────────────────────────────────────── */
.shop-layout{display:grid;grid-template-columns:260px 1fr;gap:0;max-width:1360px;margin:0 auto;padding:48px 32px;align-items:start}
.shop-sidebar{background:#fff;border:1px solid var(--border);padding:28px 24px;position:sticky;top:90px}
.sidebar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px}
.sidebar-header h3{font-family:var(--font-display);font-size:20px;font-weight:400}
.sidebar-close-btn{display:none;background:none;border:none;font-size:22px;color:var(--muted);cursor:pointer}
.sidebar-section{border-top:1px solid var(--border);padding:20px 0}
.sidebar-section-title{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:14px;font-weight:600}
.sidebar-cat-list{list-style:none;display:flex;flex-direction:column;gap:6px}
.sidebar-cat-link{display:flex;align-items:center;justify-content:space-between;font-size:13px;color:var(--muted);padding:6px 0;transition:color var(--tr)}
.sidebar-cat-link:hover,.sidebar-cat-link.active{color:var(--ink)}
.sidebar-cat-link.active{font-weight:600;border-left:2px solid var(--gold);padding-left:8px}
.sidebar-cat-count{font-size:11px;background:var(--warm);padding:2px 7px;border-radius:100px}
.price-range-inputs{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.price-input-group{display:flex;flex-direction:column;gap:4px;flex:1}
.price-input-group label{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.price-input{width:100%;border:1px solid var(--border);padding:8px 10px;font-size:13px;font-family:var(--font-body);outline:none;transition:border-color var(--tr)}
.price-input:focus{border-color:var(--gold)}
.price-sep{color:var(--muted);font-size:14px;margin-top:18px}
.sidebar-check-label{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--muted);cursor:pointer;padding:5px 0;transition:color var(--tr)}
.sidebar-check-label:hover{color:var(--ink)}
.sidebar-check{accent-color:var(--gold)}
.sidebar-reset-btn{width:100%;background:none;border:1px solid var(--border);color:var(--muted);padding:10px;font-size:11px;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;margin-top:8px;transition:all var(--tr)}
.sidebar-reset-btn:hover{border-color:var(--ink);color:var(--ink)}
.shop-sidebar-overlay{display:none;position:fixed;inset:0;background:rgba(14,12,11,.5);z-index:299}
.shop-main{padding-left:32px}
.shop-toolbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}
.shop-toolbar-left{display:flex;align-items:center;gap:16px}
.filter-toggle-btn{display:none;background:none;border:1px solid var(--border);padding:9px 16px;font-size:12px;font-weight:500;letter-spacing:.08em;color:var(--ink);cursor:pointer;align-items:center;gap:6px;transition:all var(--tr)}
.filter-toggle-btn:hover{border-color:var(--gold);color:var(--gold)}
.shop-results-count{font-size:13px;color:var(--muted)}
.active-filters{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
.active-filter-chip{display:inline-flex;align-items:center;background:rgba(184,150,62,.1);border:1px solid rgba(184,150,62,.3);color:var(--gold);padding:5px 12px;font-size:11px;font-weight:600;letter-spacing:.06em;transition:all var(--tr)}
.active-filter-chip:hover{background:rgba(184,150,62,.2)}
.active-filter-clear{font-size:12px;color:var(--muted);padding:5px 8px;text-decoration:underline}
.shop-coupon-banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;background:#fdf9f3;border:1px solid rgba(184,150,62,.25);padding:12px 16px;margin-bottom:20px;font-size:12px;color:var(--muted)}
.shop-coupon-banner>span:first-of-type{font-weight:600;color:var(--gold);letter-spacing:.06em}
.shop-coupon-chip{display:inline-flex;align-items:center;gap:6px;background:#fff;border:1px dashed rgba(184,150,62,.4);padding:5px 10px}
.shop-coupon-chip code{font-family:monospace;font-size:12px;font-weight:700;color:var(--ink);letter-spacing:.08em;background:rgba(184,150,62,.1);padding:2px 6px}
.shop-coupon-chip span{font-size:11px;color:var(--muted)}
.copy-code-btn{background:var(--gold);color:var(--ink);border:none;padding:4px 8px;font-size:10px;font-weight:600;letter-spacing:.08em;cursor:pointer;transition:background var(--tr)}
.copy-code-btn:hover{background:var(--gold2)}
.copy-code-btn.copied{background:#27ae60;color:#fff}
.pcard-offer-tag{position:absolute;top:12px;right:12px;z-index:3;background:rgba(184,150,62,.9);color:var(--ink);font-size:9px;font-weight:600;letter-spacing:.1em;padding:3px 8px;display:flex;align-items:center;gap:4px}
.shop-empty-state{grid-column:1/-1;text-align:center;padding:80px 24px}
.shop-empty-icon{font-size:48px;margin-bottom:16px}
.shop-empty-state h3{font-family:var(--font-display);font-size:24px;font-weight:400;margin-bottom:8px}
.shop-empty-state p{color:var(--muted);font-size:14px;margin-bottom:24px}
.shop-pagination{margin-top:48px;display:flex;justify-content:center}
.shop-pagination .woocommerce-pagination ul{display:flex;gap:4px;list-style:none}
.shop-pagination .woocommerce-pagination a,.shop-pagination .woocommerce-pagination span{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:1px solid var(--border);font-size:13px;color:var(--muted);transition:all var(--tr)}
.shop-pagination .woocommerce-pagination a:hover{border-color:var(--gold);color:var(--gold)}
.shop-pagination .woocommerce-pagination .current{background:var(--ink);color:var(--cream);border-color:var(--ink)}

/* ── SINGLE PRODUCT — OFFERS SECTION ─────────────────────── */
.pdp-offers{border:1px solid var(--border);margin:20px 0}
.pdp-offers-toggle{width:100%;background:#fdf9f3;border:none;padding:14px 16px;display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--gold);cursor:pointer;text-align:left}
.pdp-offers-toggle:hover{background:rgba(184,150,62,.1)}
.offers-chevron{margin-left:auto;transition:transform .3s ease}
.pdp-offers-toggle.open .offers-chevron{transform:rotate(180deg)}
.pdp-offers-loading{padding:16px}
.offers-skeleton{height:38px;background:linear-gradient(90deg,var(--warm) 25%,#f9f5ee 50%,var(--warm) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite;margin-bottom:8px}
@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
.pdp-offers-list{padding:8px 12px 12px;display:flex;flex-direction:column;gap:8px}
.offer-item{display:flex;align-items:center;gap:10px;background:#fff;border:1px dashed rgba(184,150,62,.35);padding:10px 12px}
.offer-code{font-family:monospace;font-size:13px;font-weight:700;letter-spacing:.1em;background:rgba(184,150,62,.1);padding:4px 10px;color:var(--ink)}
.offer-label{flex:1;font-size:13px;color:var(--muted)}
.offer-expiry{font-size:11px;color:var(--muted);opacity:.7}
.offer-copy-btn{background:var(--gold);color:var(--ink);border:none;padding:6px 12px;font-size:10px;font-weight:700;letter-spacing:.1em;cursor:pointer;transition:background var(--tr);white-space:nowrap}
.offer-copy-btn:hover{background:var(--gold2)}
.offer-copy-btn.copied{background:#27ae60;color:#fff}
.pdp-offers-empty{padding:16px;font-size:13px;color:var(--muted);text-align:center}

/* ── TOAST ENHANCEMENTS ─────────────────────────────────────
   Sits bottom-right; the WooCommerce notice stack (.lx-notices) is top-right,
   deliberately, so the two never overlap on a phone. */
.toast{position:fixed;bottom:24px;right:24px;display:flex;align-items:center;gap:10px;background:var(--ink);color:var(--cream);padding:14px 18px;font-size:13.5px;line-height:1.45;letter-spacing:.03em;z-index:99999;max-width:min(340px,calc(100vw - 32px));border-radius:10px;box-shadow:0 14px 34px rgba(0,0,0,.28);opacity:0;transform:translateY(14px) scale(.98);pointer-events:none;visibility:hidden;transition:opacity .28s ease,transform .28s cubic-bezier(.22,1,.36,1),visibility 0s linear .28s;border-left:3px solid var(--gold)}
.toast.show{opacity:1;transform:translateY(0) scale(1);visibility:visible;transition-delay:0s}
.toast::before{content:"";flex:0 0 8px;width:8px;height:8px;border-radius:50%;background:var(--gold)}
.toast strong,.toast b{color:#fff;font-weight:600}
.toast.toast-success{border-left-color:#27ae60}
.toast.toast-success::before{background:#27ae60}
.toast.toast-error{border-left-color:#c0392b}
.toast.toast-error::before{background:#c0392b}
.toast.toast-warning{border-left-color:#f39c12}
.toast.toast-warning::before{background:#f39c12}
@media (max-width:600px){.toast{left:16px;right:16px;bottom:16px;max-width:none}}
@media (prefers-reduced-motion:reduce){.toast{transition:opacity .2s ease,visibility 0s}.toast,.toast.show{transform:none}}

/* `.ci.is-busy` and `.cd-empty-cta` moved to the CART DRAWER block in
   style.css. features.css is enqueued after style.css, so leaving copies here
   silently outranked the drawer's own design. */

/* Add-to-cart forms lock while a submit is in flight (double-tap protection). */
.is-submitting{opacity:.65;pointer-events:none;position:relative}

/* ══ BULK DISCOUNTS ("Buy 2, save 10%") ═══════════════════════
   Badge + live hint + tier table, rendered by inc/bulk-discounts.php on four
   surfaces (product card, product page, classic variation form, modern shade
   modal). --lx-bulk-accent is printed into the page head from the setting on
   LAUXURIA → Bulk Discounts; the fallback keeps every rule usable on its own.
═══════════════════════════════════════════════════════════ */

/* ── Offer badge ──────────────────────────────────────────── */
.lx-bulk-chip{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:4px 10px;border-radius:999px;border:1px solid color-mix(in srgb, var(--lx-bulk-accent,var(--gold)) 34%, transparent);background:color-mix(in srgb, var(--lx-bulk-accent,var(--gold)) 11%, #fff);color:#6b4c12;font-size:11px;font-weight:500;letter-spacing:.03em;line-height:1.35;transition:background var(--tr),border-color var(--tr),color var(--tr)}
/* color-mix() is unsupported on older Safari/Firefox ESR, where those two
   declarations are dropped as invalid and the badge loses its background
   entirely. This block is the floor. It sits ABOVE the .is-active rule on
   purpose: in a non-supporting browser that later rule's color-mix values are
   dropped too, so these survive; in a supporting one the @supports query never
   matches and the later rule wins normally. */
@supports not (background: color-mix(in srgb, red 10%, white)){
  .lx-bulk-chip{border-color:rgba(184,150,62,.34);background:rgba(184,150,62,.11)}
  .lx-bulk-chip.is-active{border-color:rgba(39,174,96,.4);background:rgba(39,174,96,.12)}
}
.lx-bulk-chip[hidden]{display:none}
.lx-bulk-chip-icon{flex:0 0 auto;opacity:.8}
.lx-bulk-chip-text{min-width:0}

/* ── Clickable badge ──────────────────────────────────────────
   Rendered as a real <button> by lauxuria_bulk_chip_html() on any surface that
   owns a quantity control, so it has to be stripped back to the chip it looks
   like — a UA button brings its own font, background, border and centring. */
button.lx-bulk-chip{font-family:inherit;text-align:left;-webkit-appearance:none;appearance:none}
.lx-bulk-chip--pick{cursor:pointer}
.lx-bulk-chip--pick:hover{border-color:color-mix(in srgb, var(--lx-bulk-accent,var(--gold)) 60%, transparent);background:color-mix(in srgb, var(--lx-bulk-accent,var(--gold)) 20%, #fff)}
.lx-bulk-chip--pick:focus-visible{outline:2px solid var(--lx-bulk-accent,var(--gold));outline-offset:2px}
/* Pressed = this bundle is the one currently selected. It rides on top of
   .is-active's green, so the ring is the only extra signal needed. */
.lx-bulk-chip--pick.is-selected{box-shadow:0 0 0 2px rgba(39,174,96,.18)}
@supports not (background: color-mix(in srgb, red 10%, white)){
  .lx-bulk-chip--pick:hover{border-color:rgba(184,150,62,.6);background:rgba(184,150,62,.2)}
}

/* Earned. Green rather than gold, because "you have it" and "you could have
   it" must not look the same at a glance. */
.lx-bulk-chip.is-active{border-color:color-mix(in srgb,#27ae60 40%,transparent);background:color-mix(in srgb,#27ae60 12%,#fff);color:#1a7f37}

.lx-bulk-chip--card{margin:8px 0 0}
.lx-bulk-chip--modal,.lx-bulk-chip--classic{margin:0 0 10px}
.lx-bulk-chip--pdp{margin:10px 0 0}

/* A pill is only a pill while its text fits on one line. In a 2-up mobile grid
   a card is ~145px wide and "Buy 2, save 10% · up to 15% off" is three lines —
   a 999px radius on a three-line box reads as a mistake, and truncating instead
   would throw away the deeper tier the badge exists to advertise. The two narrow
   surfaces get a rounded rectangle that wraps cleanly; the roomy ones keep the
   pill. */
.lx-bulk-chip--card,.lx-bulk-chip--modal{border-radius:10px;align-items:flex-start}
.lx-bulk-chip--card .lx-bulk-chip-icon,
.lx-bulk-chip--modal .lx-bulk-chip-icon{margin-top:2px}

/* WooCommerce's own .woocommerce-variation-add-to-cart is a flex ROW in
   style.css (qty stepper + Add to cart, gap 12px). Dropped in as-is the badge
   and hint would line up as two more items in that row and squash the button;
   these claim a full row of their own and let the container's gap do spacing. */
.woocommerce-variation-add-to-cart>.lx-bulk-chip--classic,
.woocommerce-variation-add-to-cart>.lx-bulk-hint--classic,
/* Per-shade ladders wrap their surface in one of these two, so the wrapper is
   what the flex row sees — without them a product with per-shade rules put its
   offer back into the button row the two rules above exist to keep it out of. */
.woocommerce-variation-add-to-cart>.lx-bulk-parentoffer,
.woocommerce-variation-add-to-cart>.lx-bulk-varset{flex:0 0 100%;margin:0}

/* ── Per-shade ladders ───────────────────────────────────────
   One surface per variation, all hidden, swapped in by features.js on
   `found_variation` (see lauxuria_bulk_variation_offers_html). Neither wrapper
   sets a display of its own, so the UA's [hidden] would be enough — declared
   anyway, because every other [hidden] rule in this file exists precisely
   because someone later gave the element a display and broke it silently. */
.lx-bulk-varoffer[hidden],
.lx-bulk-parentoffer[hidden]{display:none}

/* ══ PACK SELECTOR (the `pills` layout) ══════════════════════
   "1pc | 2pcs (Save 10%) | 3pcs (Save 15%)" — the ladder as a row of options
   the shopper picks between, rendered by lauxuria_bulk_selector_html(). One
   markup, four densities: the PDP and the classic variation form get the full
   treatment, product cards and shade cards get --compact.
═══════════════════════════════════════════════════════════ */

.lx-bulk-sel{margin:16px 0}
.lx-bulk-sel-head{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);font-weight:600;margin-bottom:10px}

/* auto-fit rather than a fixed count: two tiers should fill the row and five
   should wrap, without the template needing to know how many there are.
   min(112px, 100%) rather than a bare 112px: a plain minmax() floor is a HARD
   minimum, so in any container narrower than it — a homepage rail stays 2-up
   down to 320px, which is a ~100px card — the track would overflow its own
   card and push the page sideways. */
.lx-bulk-sel-opts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(112px,100%),1fr));gap:10px;align-items:stretch}

/* One rule for both elements the renderer emits: a <button> when the surface has
   a quantity to set, a <span> when it does not (a card for a variable product,
   which links to the product page first). The UA button box — its own font,
   background, border and centring — is stripped rather than styled around. */
.lx-bulk-opt{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:58px;margin:0;padding:10px 12px;border:1.5px solid var(--border);border-radius:999px;background:#fff;color:var(--ink);font-family:inherit;font-size:inherit;text-align:center;-webkit-appearance:none;appearance:none;transition:border-color var(--tr),background var(--tr),color var(--tr),box-shadow var(--tr)}
/* A tier's Custom wording is free text an admin can make arbitrarily long, and
   a single unbreakable run of it would otherwise widen the whole grid track. */
/* Stock can retire a pack: pick a shade with two left and the three-pack has to
   go (features.js, found_variation). The attribute alone is not enough — the
   rule above sets display:flex, and an author declaration beats the user agent's
   own [hidden]{display:none}. Same for the wrapper, which hides itself entirely
   when the chosen shade can reach no pack at all. */
.lx-bulk-opt[hidden],
.lx-bulk-sel[hidden]{display:none}
.lx-bulk-opt-main{max-width:100%;font-size:13px;font-weight:600;line-height:1.25;overflow-wrap:anywhere}
.lx-bulk-opt-unit{font-size:11px;line-height:1.3;color:var(--muted);font-variant-numeric:tabular-nums}
/* A variable product has no unit price until a shade is chosen. The line stays
   in the layout and only loses its text, so choosing a shade fills three gaps
   rather than growing every option in the row at once. */
.lx-bulk-opt-unit:empty::before{content:"\00a0"}

/* The ribbon overhangs the pill, so the row needs headroom for it — reserved on
   the CONTAINER rather than on the flagged option, or the row's items would sit
   at two different heights. */
.lx-bulk-sel-opts:has(.lx-bulk-opt--popular){padding-top:9px}
.lx-bulk-opt-flag{position:absolute;top:-9px;left:50%;transform:translateX(-50%);white-space:nowrap;padding:2px 9px;border-radius:999px;background:var(--lx-bulk-accent,var(--gold));color:#fff;font-size:8.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;line-height:1.5}
/* :has() is unsupported on older Safari/Firefox ESR, where the whole rule above
   is dropped and the ribbon would clip against the element before it. Padding
   the container unconditionally is the floor — 9px of space is invisible when
   nothing is flagged. */
@supports not selector(:has(*)){
  .lx-bulk-sel-opts{padding-top:9px}
}

.lx-bulk-opt--popular{border-color:color-mix(in srgb,var(--lx-bulk-accent,var(--gold)) 55%,transparent)}

/* Chosen. Solid ink rather than a tint: this is the one option the shopper is
   buying, and it has to win against a row of five white pills. */
.lx-bulk-opt.is-selected{border-color:var(--ink);background:var(--ink);color:var(--cream);box-shadow:0 2px 10px rgba(14,12,11,.16)}
.lx-bulk-opt.is-selected .lx-bulk-opt-unit{color:rgba(255,255,255,.72)}

/* Interactive only in the picker variant — the read-only copy renders the same
   classes on <span>. */
.lx-bulk-sel--pick .lx-bulk-opt{cursor:pointer}
.lx-bulk-sel--pick .lx-bulk-opt:hover{border-color:var(--lx-bulk-accent,var(--gold))}
.lx-bulk-sel--pick .lx-bulk-opt.is-selected:hover{border-color:var(--ink)}
.lx-bulk-sel--pick .lx-bulk-opt:focus-visible{outline:2px solid var(--lx-bulk-accent,var(--gold));outline-offset:2px}

/* ── Link variant ────────────────────────────────────────────
   A card for a variable product has no stepper to set — the shade has not been
   chosen yet — so each pack is an <a> to the product page carrying `lx_qty`
   instead of dead text. It has to look identical to the button variant: the
   difference is where the choice is completed, not what is being offered. */
.lx-bulk-sel--link .lx-bulk-opt{cursor:pointer;text-decoration:none;color:var(--ink)}
.lx-bulk-sel--link .lx-bulk-opt:hover{border-color:var(--lx-bulk-accent,var(--gold));color:var(--ink)}
.lx-bulk-sel--link .lx-bulk-opt:focus-visible{outline:2px solid var(--lx-bulk-accent,var(--gold));outline-offset:2px}
.lx-bulk-chip-link{display:inline-flex;max-width:100%;text-decoration:none}
.lx-bulk-chip-link:hover .lx-bulk-chip{border-color:color-mix(in srgb, var(--lx-bulk-accent,var(--gold)) 60%, transparent)}
@supports not (background: color-mix(in srgb, red 10%, white)){
  .lx-bulk-opt--popular{border-color:rgba(184,150,62,.55)}
}

.lx-bulk-sel-note{margin:10px 0 0;font-size:11.5px;line-height:1.5;color:var(--muted)}

/* ── Compact: product cards and shade cards ───────────────────
   No heading, no baseline option, and a rectangle rather than a pill — a 145px
   card in a 2-up mobile grid cannot hold two round-ended buttons side by side
   without the text inside them wrapping to three lines. */
.lx-bulk-sel--compact{margin:8px 0 0}
.lx-bulk-sel--compact .lx-bulk-sel-opts{grid-template-columns:repeat(auto-fit,minmax(min(78px,100%),1fr));gap:6px}
.lx-bulk-sel--compact .lx-bulk-opt{min-height:0;gap:1px;padding:6px 8px;border-width:1px;border-radius:8px}
.lx-bulk-sel--compact .lx-bulk-opt-main{font-size:11.5px;font-weight:700}
/* Only compact renders this — the roomy surfaces fold the same words into
   .lx-bulk-opt-main through `option_template`. */
.lx-bulk-opt-save{font-size:10px;font-weight:600;line-height:1.25;color:#1a7f37;overflow-wrap:anywhere}
.lx-bulk-opt.is-selected .lx-bulk-opt-save{color:#7fd6a0}
.lx-bulk-sel--compact .lx-bulk-opt-unit{font-size:9.5px}
.lx-bulk-sel--compact .lx-bulk-opt-flag{top:-8px;font-size:7.5px;padding:1px 6px;letter-spacing:.06em}
.lx-bulk-sel--compact .lx-bulk-opt.is-selected{box-shadow:none}

/* ── Inside the classic variation form: dense ────────────────
   The form's own container is a flex ROW (see the badge note above), so the
   selector claims a full row of its own the same way the badge and hint do.

   And it is DENSE in there. This surface sits between the shade dropdowns and
   the Add to Cart button — the two controls the shopper came for — so at the
   roomy default (58px pills, a 16px gutter, a heading and a note at full size)
   the packs took more height than the buy row itself and pushed it toward the
   fold. One framed panel instead: same options, same behaviour, a little over
   half the height, and reading as something attached to the buy row rather
   than another section of the page.

   Descendant, not `>`: a per-shade ladder is wrapped in .lx-bulk-parentoffer /
   .lx-bulk-varset, so the selector is a grandchild there and the two would
   otherwise be styled differently depending on whether the product happens to
   have per-shade rules.

   Declared BEFORE the two @media blocks below, deliberately: under 430px the
   phone list layout there is still the right answer for these options, and at
   equal specificity it wins on source order. Anything added after those blocks
   silently takes the phone layout away. */
.woocommerce-variation-add-to-cart>.lx-bulk-sel{flex:0 0 100%}
.woocommerce-variation-add-to-cart .lx-bulk-sel{
  margin:0;padding:10px 12px;border-radius:14px;
  border:1px solid color-mix(in srgb,var(--lx-bulk-accent,var(--gold)) 26%,transparent);
  background:color-mix(in srgb,var(--lx-bulk-accent,var(--gold)) 5%,#fff)}
.woocommerce-variation-add-to-cart .lx-bulk-sel-head{font-size:9.5px;letter-spacing:.14em;color:var(--muted);margin-bottom:8px}
.woocommerce-variation-add-to-cart .lx-bulk-sel-opts{grid-template-columns:repeat(auto-fit,minmax(min(100px,100%),1fr));gap:8px}
.woocommerce-variation-add-to-cart .lx-bulk-opt{min-height:0;gap:1px;padding:8px 10px;border-width:1px;border-radius:10px}
.woocommerce-variation-add-to-cart .lx-bulk-opt-main{font-size:12px}
.woocommerce-variation-add-to-cart .lx-bulk-opt-unit{font-size:10px}
.woocommerce-variation-add-to-cart .lx-bulk-opt-flag{top:-7px;font-size:7.5px;padding:1px 7px;letter-spacing:.07em}
.woocommerce-variation-add-to-cart .lx-bulk-opt.is-selected{box-shadow:0 1px 6px rgba(14,12,11,.14)}
.woocommerce-variation-add-to-cart .lx-bulk-sel-note{margin:8px 0 0;font-size:10.5px}
/* The live nudge is one sentence about the packs directly above it; left at
   full size it read as a second, competing line of copy. */
.woocommerce-variation-add-to-cart .lx-bulk-hint{font-size:11px}
@supports not (background: color-mix(in srgb, red 10%, white)){
  .woocommerce-variation-add-to-cart .lx-bulk-sel{border-color:rgba(184,150,62,.26);background:rgba(184,150,62,.05)}
}

/* Both hosts are flex columns whose element above already carries a bottom
   margin, so the selector owns only the gap BELOW it — otherwise the two
   margins stack and the row floats away from the price it belongs to. */
.pinfo .lx-bulk-sel--compact,
.lx-var-info .lx-bulk-sel--compact{margin:0 0 12px}

@media(max-width:540px){
  .lx-bulk-sel-opts{grid-template-columns:repeat(auto-fit,minmax(min(96px,100%),1fr));gap:8px}
  .lx-bulk-opt{min-height:52px;padding:9px 8px}
  .lx-bulk-opt-main{font-size:12px}
}

/* ── Phone: the full selector becomes a list ──────────────────
   Three packs across a 288px column leaves ~90px each, which is narrower than
   "2pcs (Save 10%)" and its price — every option wrapped to three lines and the
   row became a wall. One option per row instead, read left to right: what you
   get on the left, what it costs on the right. The compact variant is excluded;
   it is already inside something narrow and has no baseline option to stack. */
@media(max-width:430px){
  .lx-bulk-sel:not(.lx-bulk-sel--compact) .lx-bulk-sel-opts{grid-template-columns:1fr;gap:16px}
  .lx-bulk-sel:not(.lx-bulk-sel--compact) .lx-bulk-opt{flex-direction:row;justify-content:space-between;align-items:center;gap:12px;min-height:50px;padding:10px 16px;border-radius:14px;text-align:left}
  .lx-bulk-sel:not(.lx-bulk-sel--compact) .lx-bulk-opt-unit{text-align:right;white-space:nowrap}
  /* Centred, the ribbon would sit over the label it is recommending. Pinned
     right, it clears it — and the 16px row gap above keeps it off the option
     before it, which a 10px gap did not. */
  .lx-bulk-sel:not(.lx-bulk-sel--compact) .lx-bulk-opt-flag{left:auto;right:14px;transform:none}
}

/* No hover to discover these with, so the target has to carry the affordance. */
@media(hover:none){
  .lx-bulk-sel--pick .lx-bulk-opt{min-height:52px}
  .lx-bulk-sel--compact.lx-bulk-sel--pick .lx-bulk-opt{min-height:44px}
}

/* ── Live hint ────────────────────────────────────────────── */
.lx-bulk-hint{font-size:12px;line-height:1.5;color:var(--muted);display:block}
.lx-bulk-hint[hidden]{display:none}
.lx-bulk-hint.is-active{color:#1a7f37;font-weight:500}
.lx-bulk-hint--pdp{margin:10px 0 0}
.lx-bulk-hint--modal,.lx-bulk-hint--classic{margin:0 0 10px}

/* ── Tier table ───────────────────────────────────────────── */
.lx-bulk-table{margin:16px 0;border:1px solid var(--border);border-left:3px solid var(--lx-bulk-accent,var(--gold));border-radius:6px;background:#fff;padding:14px 16px}
.lx-bulk-table-head{display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);font-weight:600;margin-bottom:10px}
.lx-bulk-table-head svg{flex:0 0 auto;color:var(--lx-bulk-accent,var(--gold))}
.lx-bulk-tiers{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
/* The separator lives on the <li>, not on the row itself: the row is a <button>
   in the selectable variant and gets its own background and padding, which a
   border shared with the divider would clip against. */
/* Drawn as a border-TOP on every row but the first, rather than a border-bottom
   on every row but the last. Identical when the whole ladder shows — and when
   stock retires the top rows (features.js hides them from the tail up), each one
   takes its own separator away with it. The bottom-border form would have left
   the last surviving row underlined against nothing. */
.lx-bulk-tier-item + .lx-bulk-tier-item{border-top:1px solid var(--border)}
.lx-bulk-tier-item[hidden],
.lx-bulk-table[hidden]{display:none}
/* A four-column grid with EXPLICIT placement, not flex-wrap. Two of the four
   cells are conditional — a variable product has no per-unit price to quote and
   a read-only table has no Select label — and with auto-placement their absence
   would slide the remaining cells left into a different column each time, so
   two tables on one page could disagree about where the money sits. Explicit
   grid-column keeps every row in the same shape whatever it happens to carry. */
.lx-bulk-tier{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;column-gap:12px;row-gap:2px;padding:7px 0;font-size:13px}
.lx-bulk-tier-qty{grid-column:1;grid-row:1;font-weight:600;color:var(--ink);white-space:nowrap}
.lx-bulk-tier-offer{grid-column:2;grid-row:1;color:var(--muted);min-width:0}
.lx-bulk-tier-money{grid-column:3;grid-row:1;display:flex;flex-direction:column;align-items:flex-end;gap:1px;text-align:right}
.lx-bulk-tier-price{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.lx-bulk-tier-price small{font-weight:400;font-size:11px;color:var(--muted);margin-left:2px}
.lx-bulk-tier-save{font-size:11.5px;font-weight:500;color:#1a7f37;white-space:nowrap}
.lx-bulk-table-note{margin:10px 0 0;font-size:11.5px;line-height:1.5;color:var(--muted)}

/* ── Selectable tier rows ─────────────────────────────────────
   Each row is a <button> that sets its own quantity. It has to fill the list
   item and keep the flex layout the read-only <div> version uses, so the UA
   button box is stripped rather than restyled around. */
button.lx-bulk-tier{width:100%;font-family:inherit;font-size:13px;color:inherit;background:none;border:0;text-align:left;cursor:pointer;padding:8px 10px;margin:0;border-radius:5px;transition:background var(--tr)}
.lx-bulk-table--pick .lx-bulk-tiers{gap:0}
.lx-bulk-tier--pick:hover{background:color-mix(in srgb, var(--lx-bulk-accent,var(--gold)) 10%, transparent)}
.lx-bulk-tier--pick:focus-visible{outline:2px solid var(--lx-bulk-accent,var(--gold));outline-offset:-2px}
.lx-bulk-tier--pick.is-selected{background:rgba(39,174,96,.09);box-shadow:inset 3px 0 0 #27ae60}
.lx-bulk-tier--pick.is-selected .lx-bulk-tier-qty{color:#1a7f37}
@supports not (background: color-mix(in srgb, red 10%, white)){
  .lx-bulk-tier--pick:hover{background:rgba(184,150,62,.1)}
}

/* "Select" / "Selected" — one is always hidden, so the state can flip in CSS
   without JS owning either string. */
.lx-bulk-tier-pick{grid-column:4;grid-row:1;font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--lx-bulk-accent,var(--gold));white-space:nowrap}
.lx-bulk-tier-pick-on{display:none}
.lx-bulk-tier-pick-on::before{content:"\2713";margin-right:4px}
.lx-bulk-tier--pick.is-selected .lx-bulk-tier-pick{color:#1a7f37}
.lx-bulk-tier--pick.is-selected .lx-bulk-tier-pick-off{display:none}
.lx-bulk-tier--pick.is-selected .lx-bulk-tier-pick-on{display:inline}

/* The ladder above the shade grid in the modern variation modal. */
.lx-var-modal-offer{margin-bottom:18px}
.lx-var-modal-offer .lx-bulk-table{margin:0}


/* ── Narrow columns ───────────────────────────────────────────
   Below ~540px the PDP column, the shade modal and a 1-up card grid are all too
   narrow for four columns of a tier row. Two rows of two: what it costs on top,
   what you get and the control underneath. */
@media(max-width:540px){
  .lx-bulk-tier{grid-template-columns:auto minmax(0,1fr);column-gap:10px;row-gap:4px}
  .lx-bulk-tier-money{grid-column:2;grid-row:1}
  .lx-bulk-tier-offer{grid-column:1;grid-row:2}
  .lx-bulk-tier-pick{grid-column:2;grid-row:2;justify-self:end}
  .lx-bulk-table{padding:12px 13px}
  .lx-bulk-table-head{margin-bottom:8px}
}

/* Touch pointers get no hover state to discover these with, so the affordance
   has to be size instead — 44px is the smallest comfortable tap target. */
@media(hover:none){
  button.lx-bulk-tier{min-height:44px;padding:10px}
  .lx-bulk-chip--pick{padding:7px 12px}
}

/* ── SEARCH CLOSE BUTTON ─────────────────────────────────── */
.search-close-btn{background:none;border:none;color:rgba(255,255,255,.5);font-size:28px;cursor:pointer;padding:0 8px;line-height:1;transition:color var(--tr)}
.search-close-btn:hover{color:#fff}

/* ── RESPONSIVE ───────────────────────────────────────────── */
@media(max-width:900px){
  .shop-layout{grid-template-columns:1fr;padding:24px 16px}
  .shop-main{padding-left:0;margin-top:16px}
  .shop-sidebar{position:fixed;top:0;left:-280px;width:280px;height:100vh;overflow-y:auto;z-index:400;transition:left .3s ease;border:none;box-shadow:4px 0 24px rgba(14,12,11,.15)}
  .shop-sidebar.open{left:0}
  .shop-sidebar-overlay.open{display:block}
  .sidebar-close-btn{display:block}
  .filter-toggle-btn{display:inline-flex}
  .testimonials-grid{grid-template-columns:1fr!important}
  .shop-layout .pgrid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:540px){
  .login-modal{padding:28px 20px 24px}
  .notif-panel{right:8px;left:8px;width:auto}
  .toast{left:16px;right:16px;bottom:16px;max-width:none}
  .shop-layout .pgrid{grid-template-columns:1fr}
}
